opencode-swarm 7.74.3 → 7.76.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/dist/cli/index.js +194 -25
- package/dist/commands/full-auto.d.ts +15 -3
- package/dist/commands/registry.d.ts +3 -3
- package/dist/config/loader.d.ts +6 -11
- package/dist/config/schema.d.ts +22 -0
- package/dist/full-auto/state.d.ts +12 -0
- package/dist/hooks/auto-review.d.ts +82 -0
- package/dist/hooks/repo-graph-injection.d.ts +1 -1
- package/dist/hooks/review-receipt-collector.d.ts +58 -0
- package/dist/hooks/review-receipt.d.ts +7 -0
- package/dist/index.js +3297 -2516
- package/dist/session/snapshot-reader.d.ts +1 -1
- package/dist/tools/repo-graph/builder.d.ts +4 -0
- package/dist/tools/repo-graph/ontology.d.ts +10 -0
- package/dist/tools/repo-graph/query.d.ts +21 -0
- package/dist/tools/repo-graph/storage.d.ts +7 -0
- package/dist/tools/repo-graph/types.d.ts +102 -1
- package/dist/tools/repo-graph/validation.d.ts +1 -1
- package/dist/tools/repo-graph.d.ts +5 -2
- package/dist/turbo/lean/reviewer.d.ts +3 -1
- package/dist/utils/path-security.d.ts +2 -2
- package/package.json +8 -1
package/dist/cli/index.js
CHANGED
|
@@ -52,10 +52,17 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "opencode-swarm",
|
|
55
|
-
version: "7.
|
|
55
|
+
version: "7.76.0",
|
|
56
56
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
57
57
|
main: "dist/index.js",
|
|
58
58
|
types: "dist/index.d.ts",
|
|
59
|
+
exports: {
|
|
60
|
+
".": {
|
|
61
|
+
types: "./dist/index.d.ts",
|
|
62
|
+
default: "./dist/index.js"
|
|
63
|
+
},
|
|
64
|
+
"./package.json": "./package.json"
|
|
65
|
+
},
|
|
59
66
|
bin: {
|
|
60
67
|
"opencode-swarm": "./dist/cli/index.js"
|
|
61
68
|
},
|
|
@@ -17493,7 +17500,7 @@ var init_tool_metadata = __esm(() => {
|
|
|
17493
17500
|
agents: ["critic_drift_verifier", "critic", "critic_oversight"]
|
|
17494
17501
|
},
|
|
17495
17502
|
repo_map: {
|
|
17496
|
-
description: "query the repo code graph: importers, dependencies, blast radius,
|
|
17503
|
+
description: "query the repo code graph: importers, dependencies, blast radius, localization, ontology facts, package boundaries, and heuristic preflight packets before refactoring; ontology findings are advisory, not formal proofs",
|
|
17497
17504
|
agents: [
|
|
17498
17505
|
"architect",
|
|
17499
17506
|
"critic_sounding_board",
|
|
@@ -18015,6 +18022,7 @@ __export(exports_schema, {
|
|
|
18015
18022
|
AutomationModeSchema: () => AutomationModeSchema,
|
|
18016
18023
|
AutomationConfigSchema: () => AutomationConfigSchema,
|
|
18017
18024
|
AutomationCapabilitiesSchema: () => AutomationCapabilitiesSchema,
|
|
18025
|
+
AutoReviewConfigSchema: () => AutoReviewConfigSchema,
|
|
18018
18026
|
AuthorityConfigSchema: () => AuthorityConfigSchema,
|
|
18019
18027
|
ArchitecturalSupervisionConfigSchema: () => ArchitecturalSupervisionConfigSchema,
|
|
18020
18028
|
AgentThinkingConfigSchema: () => AgentThinkingConfigSchema,
|
|
@@ -18100,7 +18108,7 @@ function resolveExternalSkillsConfig(input) {
|
|
|
18100
18108
|
};
|
|
18101
18109
|
return merged;
|
|
18102
18110
|
}
|
|
18103
|
-
var _internals5, SEPARATORS, CANONICAL_ROLES_LONGEST_FIRST, CANONICAL_ROLES_SET, AgentReasoningConfigSchema, AgentThinkingConfigSchema, AgentOverrideConfigSchema, SwarmConfigSchema, HooksConfigSchema, ScoringWeightsSchema, DecisionDecaySchema, TokenRatiosSchema, ScoringConfigSchema, ContextBudgetConfigSchema, EvidenceConfigSchema, GateFeatureSchema, PlaceholderScanConfigSchema, QualityBudgetConfigSchema, GateConfigSchema, PipelineConfigSchema, PhaseCompleteConfigSchema, SummaryConfigSchema, ReviewPassesConfigSchema, AdversarialDetectionConfigSchema, AdversarialTestingConfigSchemaBase, AdversarialTestingConfigSchema, IntegrationAnalysisConfigSchema, DocsConfigSchema, DesignDocsConfigSchema, UIReviewConfigSchema, CompactionAdvisoryConfigSchema, LintConfigSchema, SecretscanConfigSchema, GuardrailsProfileSchema, DEFAULT_AGENT_PROFILES, DEFAULT_ARCHITECT_PROFILE, GuardrailsConfigSchema, WatchdogConfigSchema, SelfReviewConfigSchema, ToolFilterConfigSchema, PlanCursorConfigSchema, ContextMapConfigSchema, CheckpointConfigSchema, AutomationModeSchema, AutomationCapabilitiesSchema, AutomationConfigSchemaBase, AutomationConfigSchema, KnowledgeConfigSchema, MemoryConfigSchema, CuratorConfigSchema, ArchitecturalSupervisionConfigSchema, KnowledgeApplicationConfigSchema, SkillPropagationConfigSchema, SkillImproverConfigSchema, SpecWriterConfigSchema, SlopDetectorConfigSchema, IncrementalVerifyConfigSchema, CompactionConfigSchema, PrmConfigSchema, AgentAuthorityRuleSchema, AuthorityConfigSchema, GeneralCouncilMemberConfigSchema, GeneralCouncilConfigSchema, CouncilConfigSchema, PrMonitorConfigSchema, ParallelizationConfigSchema, WorktreeIsolationConfigSchema, LeanTurboConfigSchema, StandardTurboConfigSchema, LeanTurboStrategyConfigSchema, TurboConfigSchema, ExternalSkillCandidateSourceTypeSchema, ExternalSkillCandidateEvaluationVerdictSchema, DiscoverySourceSchema, ExternalSkillCandidateSchema, ExternalSkillsConfigSchema, DEFAULT_EXTERNAL_SKILLS_CONFIG, PluginConfigSchema;
|
|
18111
|
+
var _internals5, SEPARATORS, CANONICAL_ROLES_LONGEST_FIRST, CANONICAL_ROLES_SET, AgentReasoningConfigSchema, AgentThinkingConfigSchema, AgentOverrideConfigSchema, SwarmConfigSchema, HooksConfigSchema, ScoringWeightsSchema, DecisionDecaySchema, TokenRatiosSchema, ScoringConfigSchema, ContextBudgetConfigSchema, EvidenceConfigSchema, GateFeatureSchema, PlaceholderScanConfigSchema, QualityBudgetConfigSchema, GateConfigSchema, PipelineConfigSchema, PhaseCompleteConfigSchema, SummaryConfigSchema, ReviewPassesConfigSchema, AutoReviewConfigSchema, AdversarialDetectionConfigSchema, AdversarialTestingConfigSchemaBase, AdversarialTestingConfigSchema, IntegrationAnalysisConfigSchema, DocsConfigSchema, DesignDocsConfigSchema, UIReviewConfigSchema, CompactionAdvisoryConfigSchema, LintConfigSchema, SecretscanConfigSchema, GuardrailsProfileSchema, DEFAULT_AGENT_PROFILES, DEFAULT_ARCHITECT_PROFILE, GuardrailsConfigSchema, WatchdogConfigSchema, SelfReviewConfigSchema, ToolFilterConfigSchema, PlanCursorConfigSchema, ContextMapConfigSchema, CheckpointConfigSchema, AutomationModeSchema, AutomationCapabilitiesSchema, AutomationConfigSchemaBase, AutomationConfigSchema, KnowledgeConfigSchema, MemoryConfigSchema, CuratorConfigSchema, ArchitecturalSupervisionConfigSchema, KnowledgeApplicationConfigSchema, SkillPropagationConfigSchema, SkillImproverConfigSchema, SpecWriterConfigSchema, SlopDetectorConfigSchema, IncrementalVerifyConfigSchema, CompactionConfigSchema, PrmConfigSchema, AgentAuthorityRuleSchema, AuthorityConfigSchema, GeneralCouncilMemberConfigSchema, GeneralCouncilConfigSchema, CouncilConfigSchema, PrMonitorConfigSchema, ParallelizationConfigSchema, WorktreeIsolationConfigSchema, LeanTurboConfigSchema, StandardTurboConfigSchema, LeanTurboStrategyConfigSchema, TurboConfigSchema, ExternalSkillCandidateSourceTypeSchema, ExternalSkillCandidateEvaluationVerdictSchema, DiscoverySourceSchema, ExternalSkillCandidateSchema, ExternalSkillsConfigSchema, DEFAULT_EXTERNAL_SKILLS_CONFIG, PluginConfigSchema;
|
|
18104
18112
|
var init_schema = __esm(() => {
|
|
18105
18113
|
init_zod();
|
|
18106
18114
|
init_constants();
|
|
@@ -18288,6 +18296,12 @@ var init_schema = __esm(() => {
|
|
|
18288
18296
|
"**/token/**"
|
|
18289
18297
|
])
|
|
18290
18298
|
});
|
|
18299
|
+
AutoReviewConfigSchema = exports_external.object({
|
|
18300
|
+
enabled: exports_external.boolean().default(false),
|
|
18301
|
+
trigger: exports_external.enum(["task_completion", "phase_boundary", "both"]).default("phase_boundary"),
|
|
18302
|
+
timeout_ms: exports_external.number().int().min(1e4).max(1800000).default(300000),
|
|
18303
|
+
max_diff_kb: exports_external.number().int().min(16).max(2048).default(256)
|
|
18304
|
+
});
|
|
18291
18305
|
AdversarialDetectionConfigSchema = exports_external.object({
|
|
18292
18306
|
enabled: exports_external.boolean().default(true),
|
|
18293
18307
|
policy: exports_external.enum(["warn", "gate", "ignore"]).default("warn"),
|
|
@@ -18971,6 +18985,7 @@ var init_schema = __esm(() => {
|
|
|
18971
18985
|
guardrails: GuardrailsConfigSchema.optional(),
|
|
18972
18986
|
watchdog: WatchdogConfigSchema.optional(),
|
|
18973
18987
|
self_review: SelfReviewConfigSchema.optional(),
|
|
18988
|
+
auto_review: AutoReviewConfigSchema.optional(),
|
|
18974
18989
|
tool_filter: ToolFilterConfigSchema.optional(),
|
|
18975
18990
|
authority: AuthorityConfigSchema.optional(),
|
|
18976
18991
|
plan_cursor: PlanCursorConfigSchema.optional(),
|
|
@@ -19021,6 +19036,7 @@ var init_schema = __esm(() => {
|
|
|
19021
19036
|
version_check: exports_external.boolean().default(true).optional(),
|
|
19022
19037
|
full_auto: exports_external.object({
|
|
19023
19038
|
enabled: exports_external.boolean().default(false),
|
|
19039
|
+
locked: exports_external.boolean().default(false),
|
|
19024
19040
|
critic_model: exports_external.string().optional(),
|
|
19025
19041
|
max_interactions_per_phase: exports_external.number().int().min(5).max(200).default(50),
|
|
19026
19042
|
deadlock_threshold: exports_external.number().int().min(2).max(10).default(3),
|
|
@@ -19034,6 +19050,7 @@ var init_schema = __esm(() => {
|
|
|
19034
19050
|
protected_paths: exports_external.array(exports_external.string()).default([
|
|
19035
19051
|
".git",
|
|
19036
19052
|
".github/workflows",
|
|
19053
|
+
".opencode",
|
|
19037
19054
|
".swarm",
|
|
19038
19055
|
"package.json",
|
|
19039
19056
|
"package-lock.json",
|
|
@@ -19061,6 +19078,7 @@ var init_schema = __esm(() => {
|
|
|
19061
19078
|
protected_paths: [
|
|
19062
19079
|
".git",
|
|
19063
19080
|
".github/workflows",
|
|
19081
|
+
".opencode",
|
|
19064
19082
|
".swarm",
|
|
19065
19083
|
"package.json",
|
|
19066
19084
|
"package-lock.json",
|
|
@@ -19112,6 +19130,7 @@ var init_schema = __esm(() => {
|
|
|
19112
19130
|
}))
|
|
19113
19131
|
}).optional().default(() => ({
|
|
19114
19132
|
enabled: false,
|
|
19133
|
+
locked: false,
|
|
19115
19134
|
max_interactions_per_phase: 50,
|
|
19116
19135
|
deadlock_threshold: 3,
|
|
19117
19136
|
escalation_mode: "pause",
|
|
@@ -19124,6 +19143,7 @@ var init_schema = __esm(() => {
|
|
|
19124
19143
|
protected_paths: [
|
|
19125
19144
|
".git",
|
|
19126
19145
|
".github/workflows",
|
|
19146
|
+
".opencode",
|
|
19127
19147
|
".swarm",
|
|
19128
19148
|
"package.json",
|
|
19129
19149
|
"package-lock.json",
|
|
@@ -19319,6 +19339,15 @@ function sanitizeExternalSkillsConfig(raw) {
|
|
|
19319
19339
|
delete cleaned.external_skills;
|
|
19320
19340
|
return cleaned;
|
|
19321
19341
|
}
|
|
19342
|
+
function rawFullAutoLocked(raw) {
|
|
19343
|
+
if (!raw || typeof raw !== "object")
|
|
19344
|
+
return false;
|
|
19345
|
+
const fullAuto = raw.full_auto;
|
|
19346
|
+
if (!fullAuto || typeof fullAuto !== "object" || Array.isArray(fullAuto)) {
|
|
19347
|
+
return false;
|
|
19348
|
+
}
|
|
19349
|
+
return fullAuto.locked === true;
|
|
19350
|
+
}
|
|
19322
19351
|
function loadPluginConfig(directory) {
|
|
19323
19352
|
const userConfigPath = path7.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
|
|
19324
19353
|
const projectConfigPath = path7.join(directory, ".opencode", CONFIG_FILENAME);
|
|
@@ -19332,6 +19361,13 @@ function loadPluginConfig(directory) {
|
|
|
19332
19361
|
if (rawProjectConfig) {
|
|
19333
19362
|
mergedRaw = deepMerge(mergedRaw, rawProjectConfig);
|
|
19334
19363
|
}
|
|
19364
|
+
if (rawFullAutoLocked(rawUserConfig) || rawFullAutoLocked(rawProjectConfig)) {
|
|
19365
|
+
const fullAutoRaw = mergedRaw.full_auto && typeof mergedRaw.full_auto === "object" && !Array.isArray(mergedRaw.full_auto) ? mergedRaw.full_auto : {};
|
|
19366
|
+
mergedRaw = {
|
|
19367
|
+
...mergedRaw,
|
|
19368
|
+
full_auto: { ...fullAutoRaw, locked: true }
|
|
19369
|
+
};
|
|
19370
|
+
}
|
|
19335
19371
|
mergedRaw = migratePresetsConfig(mergedRaw);
|
|
19336
19372
|
mergedRaw = sanitizeExternalSkillsConfig(mergedRaw);
|
|
19337
19373
|
const result = PluginConfigSchema.safeParse(mergedRaw);
|
|
@@ -19364,8 +19400,9 @@ function loadPluginConfigWithMeta(directory) {
|
|
|
19364
19400
|
const userResult = loadRawConfigFromPath(userConfigPath);
|
|
19365
19401
|
const projectResult = loadRawConfigFromPath(projectConfigPath);
|
|
19366
19402
|
const loadedFromFile = userResult.fileExisted || projectResult.fileExisted;
|
|
19403
|
+
const configHadErrors = userResult.hadError || projectResult.hadError;
|
|
19367
19404
|
const config2 = loadPluginConfig(directory);
|
|
19368
|
-
return { config: config2, loadedFromFile };
|
|
19405
|
+
return { config: config2, loadedFromFile, configHadErrors };
|
|
19369
19406
|
}
|
|
19370
19407
|
var CONFIG_FILENAME = "opencode-swarm.json", MAX_CONFIG_FILE_BYTES = 102400;
|
|
19371
19408
|
var init_loader = __esm(() => {
|
|
@@ -51242,6 +51279,25 @@ function emptyCounters() {
|
|
|
51242
51279
|
consecutiveNoProgressTurns: 0
|
|
51243
51280
|
};
|
|
51244
51281
|
}
|
|
51282
|
+
function sanitizeRunState(raw) {
|
|
51283
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
51284
|
+
return null;
|
|
51285
|
+
const r = raw;
|
|
51286
|
+
if (typeof r.sessionID !== "string" || !r.sessionID)
|
|
51287
|
+
return null;
|
|
51288
|
+
const mode = VALID_RUN_MODES.has(r.mode) ? r.mode : "supervised";
|
|
51289
|
+
const status = VALID_RUN_STATUSES.has(r.status) ? r.status : "idle";
|
|
51290
|
+
return { ...raw, mode, status };
|
|
51291
|
+
}
|
|
51292
|
+
function sanitizeSessions(raw) {
|
|
51293
|
+
const result = {};
|
|
51294
|
+
for (const [id, session] of Object.entries(raw)) {
|
|
51295
|
+
const sanitized = sanitizeRunState(session);
|
|
51296
|
+
if (sanitized)
|
|
51297
|
+
result[id] = sanitized;
|
|
51298
|
+
}
|
|
51299
|
+
return result;
|
|
51300
|
+
}
|
|
51245
51301
|
function emptyState(sessionID, mode = "supervised") {
|
|
51246
51302
|
const now = nowISO();
|
|
51247
51303
|
return {
|
|
@@ -51306,26 +51362,45 @@ function clearStateUnreadable() {
|
|
|
51306
51362
|
stateUnreadable = false;
|
|
51307
51363
|
stateUnreadableReason = "";
|
|
51308
51364
|
}
|
|
51365
|
+
function isFullAutoStateUnreadable() {
|
|
51366
|
+
return { unreadable: stateUnreadable, reason: stateUnreadableReason };
|
|
51367
|
+
}
|
|
51309
51368
|
function readPersisted(directory) {
|
|
51310
51369
|
try {
|
|
51311
51370
|
const filePath = validateSwarmPath(directory, STATE_FILE);
|
|
51312
|
-
|
|
51371
|
+
let stats;
|
|
51372
|
+
try {
|
|
51373
|
+
stats = fs15.statSync(filePath);
|
|
51374
|
+
} catch {
|
|
51313
51375
|
clearStateUnreadable();
|
|
51376
|
+
readCache.delete(filePath);
|
|
51314
51377
|
return emptyPersisted();
|
|
51315
51378
|
}
|
|
51379
|
+
const cached3 = readCache.get(filePath);
|
|
51380
|
+
if (cached3 && cached3.mtimeMs === stats.mtimeMs && cached3.size === stats.size) {
|
|
51381
|
+
clearStateUnreadable();
|
|
51382
|
+
return structuredClone(cached3.state);
|
|
51383
|
+
}
|
|
51316
51384
|
const raw = fs15.readFileSync(filePath, "utf-8");
|
|
51317
51385
|
const parsed = JSON.parse(raw);
|
|
51318
51386
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || parsed.version !== 2 || !parsed.sessions || typeof parsed.sessions !== "object" || Array.isArray(parsed.sessions)) {
|
|
51319
51387
|
markStateUnreadable(`malformed shape (version=${parsed?.version}, sessions type=${Array.isArray(parsed?.sessions) ? "array" : typeof parsed?.sessions})`);
|
|
51388
|
+
readCache.delete(filePath);
|
|
51320
51389
|
return emptyPersisted();
|
|
51321
51390
|
}
|
|
51322
51391
|
clearStateUnreadable();
|
|
51323
|
-
|
|
51392
|
+
const state = {
|
|
51324
51393
|
version: 2,
|
|
51325
51394
|
updatedAt: parsed.updatedAt ?? nowISO(),
|
|
51326
51395
|
oversightSequence: typeof parsed.oversightSequence === "number" ? parsed.oversightSequence : 0,
|
|
51327
|
-
sessions: parsed.sessions
|
|
51396
|
+
sessions: sanitizeSessions(parsed.sessions)
|
|
51328
51397
|
};
|
|
51398
|
+
readCache.set(filePath, {
|
|
51399
|
+
mtimeMs: stats.mtimeMs,
|
|
51400
|
+
size: stats.size,
|
|
51401
|
+
state: structuredClone(state)
|
|
51402
|
+
});
|
|
51403
|
+
return state;
|
|
51329
51404
|
} catch (error93) {
|
|
51330
51405
|
const reason = error93 instanceof Error ? error93.message : String(error93);
|
|
51331
51406
|
error(`[full-auto/state] Failed to read ${STATE_FILE}: ${reason} \u2014 attempting .bak recovery`);
|
|
@@ -51341,7 +51416,7 @@ function readPersisted(directory) {
|
|
|
51341
51416
|
version: 2,
|
|
51342
51417
|
updatedAt: parsed.updatedAt ?? nowISO(),
|
|
51343
51418
|
oversightSequence: typeof parsed.oversightSequence === "number" ? parsed.oversightSequence : 0,
|
|
51344
|
-
sessions: parsed.sessions
|
|
51419
|
+
sessions: sanitizeSessions(parsed.sessions)
|
|
51345
51420
|
};
|
|
51346
51421
|
}
|
|
51347
51422
|
}
|
|
@@ -51349,6 +51424,7 @@ function readPersisted(directory) {
|
|
|
51349
51424
|
error(`[full-auto/state] .bak recovery also failed: ${bakError instanceof Error ? bakError.message : String(bakError)}`);
|
|
51350
51425
|
}
|
|
51351
51426
|
markStateUnreadable(`canonical=${reason}; .bak=missing-or-corrupt`);
|
|
51427
|
+
readCache.clear();
|
|
51352
51428
|
return emptyPersisted();
|
|
51353
51429
|
}
|
|
51354
51430
|
}
|
|
@@ -51386,6 +51462,7 @@ function writePersisted(directory, persisted) {
|
|
|
51386
51462
|
}
|
|
51387
51463
|
} catch {}
|
|
51388
51464
|
fs15.renameSync(tmpPath, filePath);
|
|
51465
|
+
readCache.delete(filePath);
|
|
51389
51466
|
const readback = fs15.readFileSync(filePath, "utf-8");
|
|
51390
51467
|
const parsed = JSON.parse(readback);
|
|
51391
51468
|
if (parsed?.version !== 2) {
|
|
@@ -51397,6 +51474,10 @@ function writePersisted(directory, persisted) {
|
|
|
51397
51474
|
throw new Error(`Full-Auto state persistence failed: ${msg}`);
|
|
51398
51475
|
}
|
|
51399
51476
|
}
|
|
51477
|
+
function loadFullAutoRunState(directory, sessionID) {
|
|
51478
|
+
const persisted = readPersisted(directory);
|
|
51479
|
+
return persisted.sessions[sessionID];
|
|
51480
|
+
}
|
|
51400
51481
|
function startFullAutoRun(directory, sessionID, config3, options = {}) {
|
|
51401
51482
|
return withStateLock(directory, () => {
|
|
51402
51483
|
const persisted = readPersisted(directory);
|
|
@@ -51428,14 +51509,15 @@ function startFullAutoRun(directory, sessionID, config3, options = {}) {
|
|
|
51428
51509
|
return state;
|
|
51429
51510
|
});
|
|
51430
51511
|
}
|
|
51431
|
-
function
|
|
51512
|
+
function disarmFullAutoRun(directory, sessionID, reason) {
|
|
51432
51513
|
return withStateLock(directory, () => {
|
|
51433
51514
|
const persisted = readPersisted(directory);
|
|
51434
51515
|
const state = persisted.sessions[sessionID];
|
|
51435
51516
|
if (!state)
|
|
51436
51517
|
return;
|
|
51437
|
-
state.status = "
|
|
51518
|
+
state.status = "idle";
|
|
51438
51519
|
state.pauseReason = reason;
|
|
51520
|
+
state.terminateReason = undefined;
|
|
51439
51521
|
state.updatedAt = nowISO();
|
|
51440
51522
|
persisted.sessions[sessionID] = state;
|
|
51441
51523
|
writePersisted(directory, persisted);
|
|
@@ -51456,15 +51538,26 @@ function terminateFullAutoRun(directory, sessionID, reason) {
|
|
|
51456
51538
|
return state;
|
|
51457
51539
|
});
|
|
51458
51540
|
}
|
|
51459
|
-
var import_proper_lockfile8, lockfile8, STATE_FILE = "full-auto-state.json", stateUnreadable = false, stateUnreadableReason = "";
|
|
51541
|
+
var import_proper_lockfile8, lockfile8, STATE_FILE = "full-auto-state.json", VALID_RUN_MODES, VALID_RUN_STATUSES, stateUnreadable = false, stateUnreadableReason = "", readCache;
|
|
51460
51542
|
var init_state2 = __esm(() => {
|
|
51461
51543
|
init_utils2();
|
|
51462
51544
|
init_logger();
|
|
51463
51545
|
import_proper_lockfile8 = __toESM(require_proper_lockfile(), 1);
|
|
51464
51546
|
lockfile8 = import_proper_lockfile8.default;
|
|
51547
|
+
VALID_RUN_MODES = new Set(["assisted", "supervised", "strict"]);
|
|
51548
|
+
VALID_RUN_STATUSES = new Set([
|
|
51549
|
+
"idle",
|
|
51550
|
+
"running",
|
|
51551
|
+
"paused",
|
|
51552
|
+
"terminated"
|
|
51553
|
+
]);
|
|
51554
|
+
readCache = new Map;
|
|
51465
51555
|
});
|
|
51466
51556
|
|
|
51467
51557
|
// src/commands/full-auto.ts
|
|
51558
|
+
function isValidMode(value) {
|
|
51559
|
+
return VALID_MODES.includes(value);
|
|
51560
|
+
}
|
|
51468
51561
|
async function handleFullAutoCommand(directory, args, sessionID) {
|
|
51469
51562
|
if (!sessionID || sessionID.trim() === "") {
|
|
51470
51563
|
return "Error: No active session context. Full-Auto Mode requires an active session. Use /swarm-full-auto from within an OpenCode session, or start a session first.";
|
|
@@ -51474,39 +51567,63 @@ async function handleFullAutoCommand(directory, args, sessionID) {
|
|
|
51474
51567
|
return "Error: No active session. Full-Auto Mode requires an active session to operate.";
|
|
51475
51568
|
}
|
|
51476
51569
|
const arg = args[0]?.toLowerCase();
|
|
51570
|
+
if (arg === "status") {
|
|
51571
|
+
return buildStatusReport(directory, sessionID, session.fullAutoMode);
|
|
51572
|
+
}
|
|
51477
51573
|
let newFullAutoMode;
|
|
51574
|
+
let modeOverride;
|
|
51478
51575
|
if (arg === "on") {
|
|
51479
51576
|
newFullAutoMode = true;
|
|
51577
|
+
const modeArg = args[1]?.toLowerCase();
|
|
51578
|
+
if (modeArg) {
|
|
51579
|
+
if (!isValidMode(modeArg)) {
|
|
51580
|
+
return `Error: invalid Full-Auto mode '${args[1]}'. Valid modes: ${VALID_MODES.join(", ")}.`;
|
|
51581
|
+
}
|
|
51582
|
+
modeOverride = modeArg;
|
|
51583
|
+
}
|
|
51480
51584
|
} else if (arg === "off") {
|
|
51481
51585
|
newFullAutoMode = false;
|
|
51586
|
+
} else if (arg && isValidMode(arg)) {
|
|
51587
|
+
newFullAutoMode = true;
|
|
51588
|
+
modeOverride = arg;
|
|
51482
51589
|
} else {
|
|
51483
51590
|
newFullAutoMode = !session.fullAutoMode;
|
|
51484
51591
|
}
|
|
51485
|
-
if (newFullAutoMode && !swarmState.fullAutoEnabledInConfig) {
|
|
51486
|
-
return "Error: Full-Auto Mode cannot be enabled because full_auto.enabled is not set to true in the swarm plugin config. The autonomous oversight hook is inactive without config-level enablement. Set full_auto.enabled = true in your opencode-swarm config and restart.";
|
|
51487
|
-
}
|
|
51488
51592
|
let v2Status = "unavailable";
|
|
51489
51593
|
let modeLabel = "supervised";
|
|
51490
51594
|
let denialMaxConsecutive = 3;
|
|
51491
51595
|
let denialMaxTotal = 20;
|
|
51492
51596
|
let failClosed = true;
|
|
51493
51597
|
let durableError;
|
|
51598
|
+
let criticModelAdvisory = "";
|
|
51494
51599
|
try {
|
|
51495
|
-
const { config: config3 } = loadPluginConfigWithMeta(directory);
|
|
51600
|
+
const { config: config3, configHadErrors } = loadPluginConfigWithMeta(directory);
|
|
51496
51601
|
const fullAutoConfig = config3.full_auto;
|
|
51497
|
-
|
|
51602
|
+
if (newFullAutoMode && configHadErrors) {
|
|
51603
|
+
return "Error: Full-Auto Mode cannot be enabled \u2014 a swarm plugin config file exists but could not be loaded, so full_auto.locked cannot be verified. Fix the config file (see warnings above) and retry.";
|
|
51604
|
+
}
|
|
51605
|
+
if (newFullAutoMode && fullAutoConfig?.locked === true) {
|
|
51606
|
+
return "Error: Full-Auto Mode is locked for this project (full_auto.locked is true in the swarm plugin config). Runtime activation is disabled by configuration; remove the lock to use /swarm full-auto on.";
|
|
51607
|
+
}
|
|
51608
|
+
const effectiveMode = modeOverride ?? fullAutoConfig?.mode ?? "supervised";
|
|
51609
|
+
modeLabel = effectiveMode;
|
|
51498
51610
|
denialMaxConsecutive = fullAutoConfig?.denials?.max_consecutive ?? 3;
|
|
51499
51611
|
denialMaxTotal = fullAutoConfig?.denials?.max_total ?? 20;
|
|
51500
51612
|
failClosed = fullAutoConfig?.fail_closed !== false;
|
|
51501
51613
|
if (newFullAutoMode) {
|
|
51502
|
-
startFullAutoRun(directory, sessionID, fullAutoConfig);
|
|
51614
|
+
startFullAutoRun(directory, sessionID, fullAutoConfig ? { ...fullAutoConfig, mode: effectiveMode } : undefined);
|
|
51503
51615
|
v2Status = "running";
|
|
51616
|
+
const criticModel = fullAutoConfig?.critic_model ?? config3.agents?.critic?.model;
|
|
51617
|
+
const architectModel = config3.agents?.architect?.model;
|
|
51618
|
+
if (criticModel && architectModel && criticModel === architectModel) {
|
|
51619
|
+
criticModelAdvisory = " WARNING: critic model matches architect model \u2014 set full_auto.critic_model (or agents.critic.model) to a different model for independent oversight.";
|
|
51620
|
+
}
|
|
51504
51621
|
} else {
|
|
51505
|
-
const
|
|
51506
|
-
if (!
|
|
51622
|
+
const disarmed = disarmFullAutoRun(directory, sessionID, "/swarm full-auto off");
|
|
51623
|
+
if (!disarmed) {
|
|
51507
51624
|
terminateFullAutoRun(directory, sessionID, "never started");
|
|
51508
51625
|
}
|
|
51509
|
-
v2Status = "
|
|
51626
|
+
v2Status = "idle";
|
|
51510
51627
|
}
|
|
51511
51628
|
} catch (error93) {
|
|
51512
51629
|
durableError = error93 instanceof Error ? error93.message : String(error93);
|
|
@@ -51535,13 +51652,54 @@ async function handleFullAutoCommand(directory, args, sessionID) {
|
|
|
51535
51652
|
"Full-Auto Mode enabled",
|
|
51536
51653
|
`(v2 mode=${modeLabel}, fail_closed=${failClosed},`,
|
|
51537
51654
|
`denials max ${denialMaxConsecutive} consecutive / ${denialMaxTotal} total)`
|
|
51538
|
-
].join(" ");
|
|
51655
|
+
].join(" ") + criticModelAdvisory;
|
|
51656
|
+
}
|
|
51657
|
+
function buildStatusReport(directory, sessionID, sessionFlag) {
|
|
51658
|
+
const lines = [];
|
|
51659
|
+
lines.push(`Full-Auto session flag: ${sessionFlag ? "on" : "off"}`);
|
|
51660
|
+
try {
|
|
51661
|
+
const { config: config3, configHadErrors } = loadPluginConfigWithMeta(directory);
|
|
51662
|
+
if (configHadErrors) {
|
|
51663
|
+
lines.push("Config: UNREADABLE (a config file exists but could not be loaded; `full_auto.locked` cannot be verified, so runtime activation refuses by fail-closed default). Fix the config file to restore normal status.");
|
|
51664
|
+
}
|
|
51665
|
+
if (config3.full_auto?.locked === true) {
|
|
51666
|
+
lines.push("Config: locked (runtime activation disabled via full_auto.locked)");
|
|
51667
|
+
}
|
|
51668
|
+
} catch {}
|
|
51669
|
+
try {
|
|
51670
|
+
const runState = loadFullAutoRunState(directory, sessionID);
|
|
51671
|
+
const stateHealth = isFullAutoStateUnreadable();
|
|
51672
|
+
if (stateHealth.unreadable) {
|
|
51673
|
+
lines.push(`Durable run-state: UNREADABLE (${stateHealth.reason}). Non-read-only tools are blocked fail-closed until .swarm/full-auto-state.json (or .bak) is restored or deleted.`);
|
|
51674
|
+
} else if (!runState) {
|
|
51675
|
+
lines.push("Durable run-state: none (no Full-Auto run for this session)");
|
|
51676
|
+
} else {
|
|
51677
|
+
lines.push(`Durable run-state: ${runState.status} (mode=${runState.mode})`);
|
|
51678
|
+
if (runState.pauseReason) {
|
|
51679
|
+
lines.push(`Pause reason: ${runState.pauseReason}`);
|
|
51680
|
+
}
|
|
51681
|
+
if (runState.terminateReason) {
|
|
51682
|
+
lines.push(`Terminate reason: ${runState.terminateReason}`);
|
|
51683
|
+
}
|
|
51684
|
+
lines.push(`Counters: ${runState.counters.toolCalls} tool calls, ${runState.counters.architectTurns} architect turns, ${runState.counters.oversightChecks} oversight checks`);
|
|
51685
|
+
lines.push(`Denials: ${runState.denialCounters.consecutive} consecutive / ${runState.denialCounters.total} total`);
|
|
51686
|
+
if (runState.lastOversightVerdict) {
|
|
51687
|
+
lines.push(`Last oversight verdict: ${runState.lastOversightVerdict}${runState.lastOversightAt ? ` at ${runState.lastOversightAt}` : ""}`);
|
|
51688
|
+
}
|
|
51689
|
+
}
|
|
51690
|
+
} catch (error93) {
|
|
51691
|
+
lines.push(`Durable run-state: unreadable (${error93 instanceof Error ? error93.message : String(error93)})`);
|
|
51692
|
+
}
|
|
51693
|
+
return lines.join(`
|
|
51694
|
+
`);
|
|
51539
51695
|
}
|
|
51696
|
+
var VALID_MODES;
|
|
51540
51697
|
var init_full_auto = __esm(() => {
|
|
51541
51698
|
init_config();
|
|
51542
51699
|
init_state2();
|
|
51543
51700
|
init_state();
|
|
51544
51701
|
init_logger();
|
|
51702
|
+
VALID_MODES = ["assisted", "supervised", "strict"];
|
|
51545
51703
|
});
|
|
51546
51704
|
|
|
51547
51705
|
// src/services/handoff-service.ts
|
|
@@ -57314,7 +57472,18 @@ function containsPathTraversal(str) {
|
|
|
57314
57472
|
return false;
|
|
57315
57473
|
}
|
|
57316
57474
|
function containsControlChars(str) {
|
|
57317
|
-
|
|
57475
|
+
for (const ch of str) {
|
|
57476
|
+
const code = ch.codePointAt(0);
|
|
57477
|
+
if (code === undefined)
|
|
57478
|
+
continue;
|
|
57479
|
+
if (code <= 31 || code >= 127 && code <= 159)
|
|
57480
|
+
return true;
|
|
57481
|
+
if (code >= 8234 && code <= 8238)
|
|
57482
|
+
return true;
|
|
57483
|
+
if (code >= 8294 && code <= 8297)
|
|
57484
|
+
return true;
|
|
57485
|
+
}
|
|
57486
|
+
return false;
|
|
57318
57487
|
}
|
|
57319
57488
|
var init_path_security = () => {};
|
|
57320
57489
|
|
|
@@ -66676,9 +66845,9 @@ Subcommands:
|
|
|
66676
66845
|
},
|
|
66677
66846
|
"full-auto": {
|
|
66678
66847
|
handler: (ctx) => handleFullAutoCommand(ctx.directory, ctx.args, ctx.sessionID),
|
|
66679
|
-
description: "Toggle Full-Auto Mode for the active session [on|off]",
|
|
66680
|
-
args: "on, off",
|
|
66681
|
-
details: '
|
|
66848
|
+
description: "Toggle Full-Auto Mode for the active session [on [mode]|off|status]",
|
|
66849
|
+
args: "on [assisted|supervised|strict], off, status",
|
|
66850
|
+
details: 'First-class toggle for Full-Auto Mode \u2014 autonomous execution with the critic reviewing escalations on your behalf. No config-level enablement is required: "on" activates immediately (unless full_auto.locked is true in config), "off" disarms the run and returns the session to normal interactive operation, "status" reports the durable run state. ' + 'An optional mode after "on" overrides full_auto.mode for this run: assisted (critic consulted only on policy escalations), supervised (default \u2014 risky/high-impact actions reviewed by the critic), strict (ALL plan mutations reviewed by the critic). ' + "While active, the critic answers architect questions and reviews phase boundaries, delegations, and risky actions on your behalf; only ESCALATE_TO_HUMAN verdicts halt the run for your input. The run state is durable (.swarm/full-auto-state.json) and survives restarts; toggle with no argument flips the current state.",
|
|
66682
66851
|
category: "utility"
|
|
66683
66852
|
},
|
|
66684
66853
|
"auto-proceed": {
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Handles the /swarm full-auto command.
|
|
3
|
-
*
|
|
3
|
+
* First-class session toggle for Full-Auto Mode: on / off / status / bare toggle.
|
|
4
|
+
*
|
|
5
|
+
* Full-Auto no longer requires `full_auto.enabled: true` in the plugin config —
|
|
6
|
+
* the v2 hooks are always armed and gated at runtime by the durable per-session
|
|
7
|
+
* run state, so activation is a pure runtime decision (like switching permission
|
|
8
|
+
* modes in other agent CLIs). Administrators can set `full_auto.locked: true`
|
|
9
|
+
* to refuse runtime activation entirely.
|
|
10
|
+
*
|
|
11
|
+
* `on` accepts an optional mode argument (`assisted` | `supervised` | `strict`)
|
|
12
|
+
* that overrides `full_auto.mode` for this run. In every mode the critic
|
|
13
|
+
* reviews escalations on the user's behalf; `strict` routes ALL plan mutations
|
|
14
|
+
* through the critic, `supervised` (default) routes risky/high-impact actions,
|
|
15
|
+
* `assisted` only consults the critic when the deterministic policy escalates.
|
|
4
16
|
*
|
|
5
17
|
* In Full-Auto v2 this also creates a durable run-state record under
|
|
6
18
|
* .swarm/full-auto-state.json so the permission/oversight infrastructure can
|
|
7
19
|
* fail-closed across hooks and across process restarts.
|
|
8
20
|
*
|
|
9
|
-
* H2 fix: durable write happens BEFORE flipping the legacy
|
|
21
|
+
* H2 fix (preserved): durable write happens BEFORE flipping the legacy
|
|
10
22
|
* `session.fullAutoMode` flag. If the durable write fails, the command
|
|
11
23
|
* surfaces the error in its return string and does NOT enable the legacy
|
|
12
24
|
* reactive intercept — preventing a silent fail-open where reactive checks
|
|
@@ -14,7 +26,7 @@
|
|
|
14
26
|
* durable run.
|
|
15
27
|
*
|
|
16
28
|
* @param directory - Project directory (used to persist Full-Auto run state)
|
|
17
|
-
* @param args -
|
|
29
|
+
* @param args - "on [mode]" | "off" | "status" | undefined (toggle behavior)
|
|
18
30
|
* @param sessionID - Session ID for accessing active session state
|
|
19
31
|
* @returns Feedback message about Full-Auto Mode state
|
|
20
32
|
*/
|
|
@@ -501,9 +501,9 @@ export declare const COMMAND_REGISTRY: {
|
|
|
501
501
|
};
|
|
502
502
|
readonly 'full-auto': {
|
|
503
503
|
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
504
|
-
readonly description: "Toggle Full-Auto Mode for the active session [on|off]";
|
|
505
|
-
readonly args: "on, off";
|
|
506
|
-
readonly details:
|
|
504
|
+
readonly description: "Toggle Full-Auto Mode for the active session [on [mode]|off|status]";
|
|
505
|
+
readonly args: "on [assisted|supervised|strict], off, status";
|
|
506
|
+
readonly details: string;
|
|
507
507
|
readonly category: "utility";
|
|
508
508
|
};
|
|
509
509
|
readonly 'auto-proceed': {
|
package/dist/config/loader.d.ts
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
import { type PluginConfig } from './schema';
|
|
2
2
|
export declare const MAX_CONFIG_FILE_BYTES = 102400;
|
|
3
3
|
export { deepMerge, MAX_MERGE_DEPTH } from '../utils/merge';
|
|
4
|
-
/**
|
|
5
|
-
* Load plugin configuration from user and project config files.
|
|
6
|
-
*
|
|
7
|
-
* Config locations:
|
|
8
|
-
* 1. User config: ~/.config/opencode/opencode-swarm.json
|
|
9
|
-
* 2. Project config: <directory>/.opencode/opencode-swarm.json
|
|
10
|
-
*
|
|
11
|
-
* Project config takes precedence. Nested objects are deep-merged.
|
|
12
|
-
* IMPORTANT: Raw configs are merged BEFORE Zod parsing so that
|
|
13
|
-
* Zod defaults don't override explicit user values.
|
|
14
|
-
*/
|
|
15
4
|
export declare function loadPluginConfig(directory: string): PluginConfig;
|
|
16
5
|
/**
|
|
17
6
|
* Internal variant of loadPluginConfig that also returns loader metadata.
|
|
@@ -21,6 +10,11 @@ export declare function loadPluginConfig(directory: string): PluginConfig;
|
|
|
21
10
|
export declare function loadPluginConfigWithMeta(directory: string): {
|
|
22
11
|
config: PluginConfig;
|
|
23
12
|
loadedFromFile: boolean;
|
|
13
|
+
/** True when a config file existed but could not be loaded (corrupt JSON,
|
|
14
|
+
* oversized, permission error). Consumers with fail-closed semantics —
|
|
15
|
+
* e.g. the Full-Auto `locked` activation guard — must treat this as
|
|
16
|
+
* "config unknown", not "config defaults". */
|
|
17
|
+
configHadErrors: boolean;
|
|
24
18
|
};
|
|
25
19
|
/**
|
|
26
20
|
* Async variant of `loadPluginConfigWithMeta`. Used by the plugin entry
|
|
@@ -29,6 +23,7 @@ export declare function loadPluginConfigWithMeta(directory: string): {
|
|
|
29
23
|
export declare function loadPluginConfigWithMetaAsync(directory: string): Promise<{
|
|
30
24
|
config: PluginConfig;
|
|
31
25
|
loadedFromFile: boolean;
|
|
26
|
+
configHadErrors: boolean;
|
|
32
27
|
}>;
|
|
33
28
|
/**
|
|
34
29
|
* Load custom prompt for an agent from the prompts directory.
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -333,6 +333,17 @@ export declare const ReviewPassesConfigSchema: z.ZodObject<{
|
|
|
333
333
|
security_globs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
334
334
|
}, z.core.$strip>;
|
|
335
335
|
export type ReviewPassesConfig = z.infer<typeof ReviewPassesConfigSchema>;
|
|
336
|
+
export declare const AutoReviewConfigSchema: z.ZodObject<{
|
|
337
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
338
|
+
trigger: z.ZodDefault<z.ZodEnum<{
|
|
339
|
+
task_completion: "task_completion";
|
|
340
|
+
phase_boundary: "phase_boundary";
|
|
341
|
+
both: "both";
|
|
342
|
+
}>>;
|
|
343
|
+
timeout_ms: z.ZodDefault<z.ZodNumber>;
|
|
344
|
+
max_diff_kb: z.ZodDefault<z.ZodNumber>;
|
|
345
|
+
}, z.core.$strip>;
|
|
346
|
+
export type AutoReviewConfig = z.infer<typeof AutoReviewConfigSchema>;
|
|
336
347
|
export declare const AdversarialDetectionConfigSchema: z.ZodObject<{
|
|
337
348
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
338
349
|
policy: z.ZodDefault<z.ZodEnum<{
|
|
@@ -1392,6 +1403,16 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
1392
1403
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1393
1404
|
skip_in_turbo: z.ZodDefault<z.ZodBoolean>;
|
|
1394
1405
|
}, z.core.$strip>>;
|
|
1406
|
+
auto_review: z.ZodOptional<z.ZodObject<{
|
|
1407
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1408
|
+
trigger: z.ZodDefault<z.ZodEnum<{
|
|
1409
|
+
task_completion: "task_completion";
|
|
1410
|
+
phase_boundary: "phase_boundary";
|
|
1411
|
+
both: "both";
|
|
1412
|
+
}>>;
|
|
1413
|
+
timeout_ms: z.ZodDefault<z.ZodNumber>;
|
|
1414
|
+
max_diff_kb: z.ZodDefault<z.ZodNumber>;
|
|
1415
|
+
}, z.core.$strip>>;
|
|
1395
1416
|
tool_filter: z.ZodOptional<z.ZodObject<{
|
|
1396
1417
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1397
1418
|
overrides: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
@@ -1858,6 +1879,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
1858
1879
|
version_check: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
1859
1880
|
full_auto: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
1860
1881
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1882
|
+
locked: z.ZodDefault<z.ZodBoolean>;
|
|
1861
1883
|
critic_model: z.ZodOptional<z.ZodString>;
|
|
1862
1884
|
max_interactions_per_phase: z.ZodDefault<z.ZodNumber>;
|
|
1863
1885
|
deadlock_threshold: z.ZodDefault<z.ZodNumber>;
|
|
@@ -88,6 +88,18 @@ export declare function startFullAutoRun(directory: string, sessionID: string, c
|
|
|
88
88
|
taskID?: string;
|
|
89
89
|
}): FullAutoRunState;
|
|
90
90
|
export declare function pauseFullAutoRun(directory: string, sessionID: string, reason: string): FullAutoRunState | undefined;
|
|
91
|
+
/**
|
|
92
|
+
* Disarm a Full-Auto run in response to an explicit user `off`.
|
|
93
|
+
*
|
|
94
|
+
* Unlike `pauseFullAutoRun` / `terminateFullAutoRun` (system-initiated halts
|
|
95
|
+
* that fail-closed-block non-read-only tools until the user re-enables),
|
|
96
|
+
* disarming returns the session to normal interactive operation: the record
|
|
97
|
+
* transitions to `'idle'`, which every enforcement path treats as
|
|
98
|
+
* "no active Full-Auto run". Counters and denial history are preserved for
|
|
99
|
+
* audit. (Adversarial review F3: `off` must not be a one-way door into a
|
|
100
|
+
* write-blocked session.)
|
|
101
|
+
*/
|
|
102
|
+
export declare function disarmFullAutoRun(directory: string, sessionID: string, reason: string): FullAutoRunState | undefined;
|
|
91
103
|
export declare function terminateFullAutoRun(directory: string, sessionID: string, reason: string): FullAutoRunState | undefined;
|
|
92
104
|
export declare function isFullAutoRunActive(directory: string, sessionID: string): boolean;
|
|
93
105
|
export type FullAutoCounterKey = keyof FullAutoCounters;
|