opencode-swarm 6.32.4 → 6.33.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/README.md +24 -0
- package/dist/agents/architect.dark-matter.test.d.ts +1 -0
- package/dist/cli/index.js +116 -24
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/registry.d.ts +4 -0
- package/dist/commands/reset-session.d.ts +7 -0
- package/dist/config/schema.d.ts +7 -0
- package/dist/hooks/delegation-gate.d.ts +7 -0
- package/dist/hooks/delegation-gate.verify.test.d.ts +11 -0
- package/dist/hooks/scope-guard.d.ts +2 -2
- package/dist/hooks/trajectory-logger.d.ts +57 -0
- package/dist/index.js +321 -191
- package/dist/session/snapshot-writer.d.ts +6 -0
- package/dist/tools/check-gate-status.prefix.test.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -142,6 +142,30 @@ You only need to specify the agents you want to override. The `architect` inheri
|
|
|
142
142
|
|
|
143
143
|
See the [full configuration reference](#configuration-reference) and the [free-tier model setup](#free-tier-opencode-zen-models) for more options.
|
|
144
144
|
|
|
145
|
+
### Step 7 — Performance modes (optional)
|
|
146
|
+
|
|
147
|
+
Swarm runs optional quality hooks (slop detection, incremental verification, compaction) on every tool call. For faster iteration, you can skip these:
|
|
148
|
+
|
|
149
|
+
**Via slash command** (session-wide):
|
|
150
|
+
```
|
|
151
|
+
/swarm turbo
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Via config** (persistent):
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"execution_mode": "fast"
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
| Mode | Behavior |
|
|
162
|
+
|------|----------|
|
|
163
|
+
| `strict` | Runs all quality hooks (slop detector, incremental verify, compaction). Maximum safety, highest overhead. |
|
|
164
|
+
| `balanced` (default) | Skips optional quality hooks. Recommended for most workflows. |
|
|
165
|
+
| `fast` | Same as balanced. Reserved for future more aggressive optimizations. |
|
|
166
|
+
|
|
167
|
+
Use `strict` mode for critical security-sensitive changes. Switch to `balanced` for routine development.
|
|
168
|
+
|
|
145
169
|
---
|
|
146
170
|
|
|
147
171
|
## Common First-Run Questions
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cli/index.js
CHANGED
|
@@ -17497,7 +17497,7 @@ var init_evidence_summary_service = __esm(() => {
|
|
|
17497
17497
|
});
|
|
17498
17498
|
|
|
17499
17499
|
// src/cli/index.ts
|
|
17500
|
-
import * as
|
|
17500
|
+
import * as fs12 from "fs";
|
|
17501
17501
|
import * as os5 from "os";
|
|
17502
17502
|
import * as path23 from "path";
|
|
17503
17503
|
|
|
@@ -18063,6 +18063,7 @@ var GuardrailsConfigSchema = exports_external.object({
|
|
|
18063
18063
|
max_consecutive_errors: exports_external.number().min(2).max(20).default(5),
|
|
18064
18064
|
warning_threshold: exports_external.number().min(0.1).max(0.9).default(0.75),
|
|
18065
18065
|
idle_timeout_minutes: exports_external.number().min(5).max(240).default(60),
|
|
18066
|
+
no_op_warning_threshold: exports_external.number().min(1).max(100).default(15),
|
|
18066
18067
|
qa_gates: exports_external.object({
|
|
18067
18068
|
required_tools: exports_external.array(exports_external.string().min(1)).default([
|
|
18068
18069
|
"diff",
|
|
@@ -18178,6 +18179,7 @@ var PluginConfigSchema = exports_external.object({
|
|
|
18178
18179
|
pipeline: PipelineConfigSchema.optional(),
|
|
18179
18180
|
phase_complete: PhaseCompleteConfigSchema.optional(),
|
|
18180
18181
|
qa_retry_limit: exports_external.number().min(1).max(10).default(3),
|
|
18182
|
+
execution_mode: exports_external.enum(["strict", "balanced", "fast"]).default("balanced"),
|
|
18181
18183
|
inject_phase_reminders: exports_external.boolean().default(true),
|
|
18182
18184
|
hooks: HooksConfigSchema.optional(),
|
|
18183
18185
|
gates: GateConfigSchema.optional(),
|
|
@@ -33931,6 +33933,8 @@ function formatHandoffMarkdown(data) {
|
|
|
33931
33933
|
init_utils2();
|
|
33932
33934
|
import { mkdirSync as mkdirSync4, renameSync as renameSync4 } from "fs";
|
|
33933
33935
|
import * as path14 from "path";
|
|
33936
|
+
var pendingWrite = null;
|
|
33937
|
+
var lastWritePromise = Promise.resolve();
|
|
33934
33938
|
function serializeAgentSession(s) {
|
|
33935
33939
|
const gateLog = {};
|
|
33936
33940
|
const rawGateLog = s.gateLog ?? new Map;
|
|
@@ -34015,7 +34019,18 @@ async function writeSnapshot(directory, state) {
|
|
|
34015
34019
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
34016
34020
|
await Bun.write(tempPath, content);
|
|
34017
34021
|
renameSync4(tempPath, resolvedPath);
|
|
34018
|
-
} catch {
|
|
34022
|
+
} catch (error93) {
|
|
34023
|
+
console.warn("[snapshot-writer] write failed:", error93 instanceof Error ? error93.message : String(error93));
|
|
34024
|
+
}
|
|
34025
|
+
}
|
|
34026
|
+
async function flushPendingSnapshot(directory) {
|
|
34027
|
+
if (pendingWrite) {
|
|
34028
|
+
clearTimeout(pendingWrite);
|
|
34029
|
+
pendingWrite = null;
|
|
34030
|
+
await writeSnapshot(directory, swarmState).catch(() => {});
|
|
34031
|
+
} else {
|
|
34032
|
+
await lastWritePromise;
|
|
34033
|
+
}
|
|
34019
34034
|
}
|
|
34020
34035
|
|
|
34021
34036
|
// src/commands/handoff.ts
|
|
@@ -34027,6 +34042,7 @@ async function handleHandoffCommand(directory, _args) {
|
|
|
34027
34042
|
await Bun.write(tempPath, markdown);
|
|
34028
34043
|
renameSync5(tempPath, resolvedPath);
|
|
34029
34044
|
await writeSnapshot(directory, swarmState);
|
|
34045
|
+
await flushPendingSnapshot(directory);
|
|
34030
34046
|
return `## Handoff Brief Written
|
|
34031
34047
|
|
|
34032
34048
|
Brief written to \`.swarm/handoff.md\`.
|
|
@@ -39322,6 +39338,37 @@ async function handleResetCommand(directory, args) {
|
|
|
39322
39338
|
`);
|
|
39323
39339
|
}
|
|
39324
39340
|
|
|
39341
|
+
// src/commands/reset-session.ts
|
|
39342
|
+
init_utils2();
|
|
39343
|
+
import * as fs10 from "fs";
|
|
39344
|
+
async function handleResetSessionCommand(directory, _args) {
|
|
39345
|
+
const results = [];
|
|
39346
|
+
try {
|
|
39347
|
+
const statePath = validateSwarmPath(directory, "session/state.json");
|
|
39348
|
+
if (fs10.existsSync(statePath)) {
|
|
39349
|
+
fs10.unlinkSync(statePath);
|
|
39350
|
+
results.push("\u2705 Deleted .swarm/session/state.json");
|
|
39351
|
+
} else {
|
|
39352
|
+
results.push("\u23ED\uFE0F state.json not found (already clean)");
|
|
39353
|
+
}
|
|
39354
|
+
} catch {
|
|
39355
|
+
results.push("\u274C Failed to delete state.json");
|
|
39356
|
+
}
|
|
39357
|
+
const sessionCount = swarmState.agentSessions.size;
|
|
39358
|
+
swarmState.agentSessions.clear();
|
|
39359
|
+
results.push(`\u2705 Cleared ${sessionCount} in-memory agent session(s)`);
|
|
39360
|
+
return [
|
|
39361
|
+
"## Session State Reset",
|
|
39362
|
+
"",
|
|
39363
|
+
...results,
|
|
39364
|
+
"",
|
|
39365
|
+
"Session state cleared. Plan, evidence, and knowledge preserved.",
|
|
39366
|
+
"",
|
|
39367
|
+
"**Next step:** Start a new OpenCode session. The plugin will initialize fresh session state on startup."
|
|
39368
|
+
].join(`
|
|
39369
|
+
`);
|
|
39370
|
+
}
|
|
39371
|
+
|
|
39325
39372
|
// src/summaries/manager.ts
|
|
39326
39373
|
init_utils2();
|
|
39327
39374
|
init_utils();
|
|
@@ -39402,18 +39449,18 @@ ${error93 instanceof Error ? error93.message : String(error93)}`;
|
|
|
39402
39449
|
|
|
39403
39450
|
// src/commands/rollback.ts
|
|
39404
39451
|
init_utils2();
|
|
39405
|
-
import * as
|
|
39452
|
+
import * as fs11 from "fs";
|
|
39406
39453
|
import * as path22 from "path";
|
|
39407
39454
|
async function handleRollbackCommand(directory, args) {
|
|
39408
39455
|
const phaseArg = args[0];
|
|
39409
39456
|
if (!phaseArg) {
|
|
39410
39457
|
const manifestPath2 = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
39411
|
-
if (!
|
|
39458
|
+
if (!fs11.existsSync(manifestPath2)) {
|
|
39412
39459
|
return "No checkpoints found. Use `/swarm checkpoint` to create checkpoints.";
|
|
39413
39460
|
}
|
|
39414
39461
|
let manifest2;
|
|
39415
39462
|
try {
|
|
39416
|
-
manifest2 = JSON.parse(
|
|
39463
|
+
manifest2 = JSON.parse(fs11.readFileSync(manifestPath2, "utf-8"));
|
|
39417
39464
|
} catch {
|
|
39418
39465
|
return "Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.";
|
|
39419
39466
|
}
|
|
@@ -39435,12 +39482,12 @@ async function handleRollbackCommand(directory, args) {
|
|
|
39435
39482
|
return "Error: Phase number must be a positive integer.";
|
|
39436
39483
|
}
|
|
39437
39484
|
const manifestPath = validateSwarmPath(directory, "checkpoints/manifest.json");
|
|
39438
|
-
if (!
|
|
39485
|
+
if (!fs11.existsSync(manifestPath)) {
|
|
39439
39486
|
return `Error: No checkpoints found. Cannot rollback to phase ${targetPhase}.`;
|
|
39440
39487
|
}
|
|
39441
39488
|
let manifest;
|
|
39442
39489
|
try {
|
|
39443
|
-
manifest = JSON.parse(
|
|
39490
|
+
manifest = JSON.parse(fs11.readFileSync(manifestPath, "utf-8"));
|
|
39444
39491
|
} catch {
|
|
39445
39492
|
return `Error: Checkpoint manifest is corrupted. Delete .swarm/checkpoints/manifest.json and re-checkpoint.`;
|
|
39446
39493
|
}
|
|
@@ -39450,10 +39497,10 @@ async function handleRollbackCommand(directory, args) {
|
|
|
39450
39497
|
return `Error: Checkpoint for phase ${targetPhase} not found. Available phases: ${available}`;
|
|
39451
39498
|
}
|
|
39452
39499
|
const checkpointDir = validateSwarmPath(directory, `checkpoints/phase-${targetPhase}`);
|
|
39453
|
-
if (!
|
|
39500
|
+
if (!fs11.existsSync(checkpointDir)) {
|
|
39454
39501
|
return `Error: Checkpoint directory for phase ${targetPhase} does not exist.`;
|
|
39455
39502
|
}
|
|
39456
|
-
const checkpointFiles =
|
|
39503
|
+
const checkpointFiles = fs11.readdirSync(checkpointDir);
|
|
39457
39504
|
if (checkpointFiles.length === 0) {
|
|
39458
39505
|
return `Error: Checkpoint for phase ${targetPhase} is empty. Cannot rollback.`;
|
|
39459
39506
|
}
|
|
@@ -39464,7 +39511,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
39464
39511
|
const src = path22.join(checkpointDir, file3);
|
|
39465
39512
|
const dest = path22.join(swarmDir, file3);
|
|
39466
39513
|
try {
|
|
39467
|
-
|
|
39514
|
+
fs11.cpSync(src, dest, { recursive: true, force: true });
|
|
39468
39515
|
successes.push(file3);
|
|
39469
39516
|
} catch (error93) {
|
|
39470
39517
|
failures.push({ file: file3, error: error93.message });
|
|
@@ -39481,7 +39528,7 @@ async function handleRollbackCommand(directory, args) {
|
|
|
39481
39528
|
timestamp: new Date().toISOString()
|
|
39482
39529
|
};
|
|
39483
39530
|
try {
|
|
39484
|
-
|
|
39531
|
+
fs11.appendFileSync(eventsPath, `${JSON.stringify(rollbackEvent)}
|
|
39485
39532
|
`);
|
|
39486
39533
|
} catch (error93) {
|
|
39487
39534
|
console.error("Failed to write rollback event:", error93);
|
|
@@ -39524,11 +39571,11 @@ async function handleSimulateCommand(directory, args) {
|
|
|
39524
39571
|
];
|
|
39525
39572
|
const report = reportLines.filter(Boolean).join(`
|
|
39526
39573
|
`);
|
|
39527
|
-
const
|
|
39574
|
+
const fs12 = await import("fs/promises");
|
|
39528
39575
|
const path23 = await import("path");
|
|
39529
39576
|
const reportPath = path23.join(directory, ".swarm", "simulate-report.md");
|
|
39530
|
-
await
|
|
39531
|
-
await
|
|
39577
|
+
await fs12.mkdir(path23.dirname(reportPath), { recursive: true });
|
|
39578
|
+
await fs12.writeFile(reportPath, report, "utf-8");
|
|
39532
39579
|
return `${darkMatterPairs.length} hidden coupling pairs detected`;
|
|
39533
39580
|
}
|
|
39534
39581
|
|
|
@@ -39929,6 +39976,47 @@ async function executeWriteRetro(args, directory) {
|
|
|
39929
39976
|
message: "Invalid summary: must be a non-empty string"
|
|
39930
39977
|
}, null, 2);
|
|
39931
39978
|
}
|
|
39979
|
+
if (args.task_id !== undefined) {
|
|
39980
|
+
const tid = args.task_id;
|
|
39981
|
+
if (!tid || tid.length === 0 || tid.length > 200) {
|
|
39982
|
+
return JSON.stringify({
|
|
39983
|
+
success: false,
|
|
39984
|
+
phase,
|
|
39985
|
+
message: "Invalid task ID: must match pattern"
|
|
39986
|
+
}, null, 2);
|
|
39987
|
+
}
|
|
39988
|
+
if (/\0/.test(tid)) {
|
|
39989
|
+
return JSON.stringify({
|
|
39990
|
+
success: false,
|
|
39991
|
+
phase,
|
|
39992
|
+
message: "Invalid task ID: contains null bytes"
|
|
39993
|
+
}, null, 2);
|
|
39994
|
+
}
|
|
39995
|
+
for (let i = 0;i < tid.length; i++) {
|
|
39996
|
+
if (tid.charCodeAt(i) < 32) {
|
|
39997
|
+
return JSON.stringify({
|
|
39998
|
+
success: false,
|
|
39999
|
+
phase,
|
|
40000
|
+
message: "Invalid task ID: contains control characters"
|
|
40001
|
+
}, null, 2);
|
|
40002
|
+
}
|
|
40003
|
+
}
|
|
40004
|
+
if (tid.includes("..") || tid.includes("/") || tid.includes("\\")) {
|
|
40005
|
+
return JSON.stringify({
|
|
40006
|
+
success: false,
|
|
40007
|
+
phase,
|
|
40008
|
+
message: "Invalid task ID: path traversal detected"
|
|
40009
|
+
}, null, 2);
|
|
40010
|
+
}
|
|
40011
|
+
const VALID_TASK_ID = /^(retro-\d+|\d+\.\d+(\.\d+)*)$/;
|
|
40012
|
+
if (!VALID_TASK_ID.test(tid)) {
|
|
40013
|
+
return JSON.stringify({
|
|
40014
|
+
success: false,
|
|
40015
|
+
phase,
|
|
40016
|
+
message: "Invalid task ID: must match pattern"
|
|
40017
|
+
}, null, 2);
|
|
40018
|
+
}
|
|
40019
|
+
}
|
|
39932
40020
|
const taskId = args.task_id ?? `retro-${phase}`;
|
|
39933
40021
|
const retroEntry = {
|
|
39934
40022
|
task_id: taskId,
|
|
@@ -40168,6 +40256,10 @@ var COMMAND_REGISTRY = {
|
|
|
40168
40256
|
handler: (ctx) => handleResetCommand(ctx.directory, ctx.args),
|
|
40169
40257
|
description: "Clear swarm state files [--confirm]"
|
|
40170
40258
|
},
|
|
40259
|
+
"reset-session": {
|
|
40260
|
+
handler: (ctx) => handleResetSessionCommand(ctx.directory, ctx.args),
|
|
40261
|
+
description: "Clear session state while preserving plan, evidence, and knowledge"
|
|
40262
|
+
},
|
|
40171
40263
|
rollback: {
|
|
40172
40264
|
handler: (ctx) => handleRollbackCommand(ctx.directory, ctx.args),
|
|
40173
40265
|
description: "Restore swarm state to a checkpoint <phase>"
|
|
@@ -40241,13 +40333,13 @@ var OPENCODE_CONFIG_PATH = path23.join(CONFIG_DIR, "opencode.json");
|
|
|
40241
40333
|
var PLUGIN_CONFIG_PATH = path23.join(CONFIG_DIR, "opencode-swarm.json");
|
|
40242
40334
|
var PROMPTS_DIR = path23.join(CONFIG_DIR, "opencode-swarm");
|
|
40243
40335
|
function ensureDir(dir) {
|
|
40244
|
-
if (!
|
|
40245
|
-
|
|
40336
|
+
if (!fs12.existsSync(dir)) {
|
|
40337
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
40246
40338
|
}
|
|
40247
40339
|
}
|
|
40248
40340
|
function loadJson(filepath) {
|
|
40249
40341
|
try {
|
|
40250
|
-
const content =
|
|
40342
|
+
const content = fs12.readFileSync(filepath, "utf-8");
|
|
40251
40343
|
const stripped = content.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (match, comment) => comment ? "" : match).replace(/,(\s*[}\]])/g, "$1");
|
|
40252
40344
|
return JSON.parse(stripped);
|
|
40253
40345
|
} catch {
|
|
@@ -40255,7 +40347,7 @@ function loadJson(filepath) {
|
|
|
40255
40347
|
}
|
|
40256
40348
|
}
|
|
40257
40349
|
function saveJson(filepath, data) {
|
|
40258
|
-
|
|
40350
|
+
fs12.writeFileSync(filepath, `${JSON.stringify(data, null, 2)}
|
|
40259
40351
|
`, "utf-8");
|
|
40260
40352
|
}
|
|
40261
40353
|
async function install() {
|
|
@@ -40288,7 +40380,7 @@ async function install() {
|
|
|
40288
40380
|
saveJson(OPENCODE_CONFIG_PATH, opencodeConfig);
|
|
40289
40381
|
console.log("\u2713 Added opencode-swarm to OpenCode plugins");
|
|
40290
40382
|
console.log("\u2713 Disabled default OpenCode agents (explore, general)");
|
|
40291
|
-
if (!
|
|
40383
|
+
if (!fs12.existsSync(PLUGIN_CONFIG_PATH)) {
|
|
40292
40384
|
const defaultConfig = {
|
|
40293
40385
|
agents: {
|
|
40294
40386
|
coder: { model: "opencode/minimax-m2.5-free" },
|
|
@@ -40331,7 +40423,7 @@ async function uninstall() {
|
|
|
40331
40423
|
`);
|
|
40332
40424
|
const opencodeConfig = loadJson(OPENCODE_CONFIG_PATH);
|
|
40333
40425
|
if (!opencodeConfig) {
|
|
40334
|
-
if (
|
|
40426
|
+
if (fs12.existsSync(OPENCODE_CONFIG_PATH)) {
|
|
40335
40427
|
console.log(`\u2717 Could not parse opencode config at: ${OPENCODE_CONFIG_PATH}`);
|
|
40336
40428
|
return 1;
|
|
40337
40429
|
} else {
|
|
@@ -40363,13 +40455,13 @@ async function uninstall() {
|
|
|
40363
40455
|
console.log("\u2713 Re-enabled default OpenCode agents (explore, general)");
|
|
40364
40456
|
if (process.argv.includes("--clean")) {
|
|
40365
40457
|
let cleaned = false;
|
|
40366
|
-
if (
|
|
40367
|
-
|
|
40458
|
+
if (fs12.existsSync(PLUGIN_CONFIG_PATH)) {
|
|
40459
|
+
fs12.unlinkSync(PLUGIN_CONFIG_PATH);
|
|
40368
40460
|
console.log(`\u2713 Removed plugin config: ${PLUGIN_CONFIG_PATH}`);
|
|
40369
40461
|
cleaned = true;
|
|
40370
40462
|
}
|
|
40371
|
-
if (
|
|
40372
|
-
|
|
40463
|
+
if (fs12.existsSync(PROMPTS_DIR)) {
|
|
40464
|
+
fs12.rmSync(PROMPTS_DIR, { recursive: true });
|
|
40373
40465
|
console.log(`\u2713 Removed custom prompts: ${PROMPTS_DIR}`);
|
|
40374
40466
|
cleaned = true;
|
|
40375
40467
|
}
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export { handlePromoteCommand } from './promote';
|
|
|
21
21
|
export type { CommandContext, CommandEntry, RegisteredCommand, } from './registry.js';
|
|
22
22
|
export { COMMAND_REGISTRY, resolveCommand, VALID_COMMANDS, } from './registry.js';
|
|
23
23
|
export { handleResetCommand } from './reset';
|
|
24
|
+
export { handleResetSessionCommand } from './reset-session';
|
|
24
25
|
export { handleRetrieveCommand } from './retrieve';
|
|
25
26
|
export { handleRollbackCommand } from './rollback';
|
|
26
27
|
export { handleSimulateCommand } from './simulate';
|
|
@@ -104,6 +104,10 @@ export declare const COMMAND_REGISTRY: {
|
|
|
104
104
|
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
105
105
|
readonly description: "Clear swarm state files [--confirm]";
|
|
106
106
|
};
|
|
107
|
+
readonly 'reset-session': {
|
|
108
|
+
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
109
|
+
readonly description: "Clear session state while preserving plan, evidence, and knowledge";
|
|
110
|
+
};
|
|
107
111
|
readonly rollback: {
|
|
108
112
|
readonly handler: (ctx: CommandContext) => Promise<string>;
|
|
109
113
|
readonly description: "Restore swarm state to a checkpoint <phase>";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles the /swarm reset-session command.
|
|
3
|
+
* Deletes only the session state file (.swarm/session/state.json)
|
|
4
|
+
* and clears in-memory agent sessions. Preserves plan, evidence,
|
|
5
|
+
* and knowledge for continuity across sessions.
|
|
6
|
+
*/
|
|
7
|
+
export declare function handleResetSessionCommand(directory: string, _args: string[]): Promise<string>;
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -313,6 +313,7 @@ export declare const GuardrailsConfigSchema: z.ZodObject<{
|
|
|
313
313
|
max_consecutive_errors: z.ZodDefault<z.ZodNumber>;
|
|
314
314
|
warning_threshold: z.ZodDefault<z.ZodNumber>;
|
|
315
315
|
idle_timeout_minutes: z.ZodDefault<z.ZodNumber>;
|
|
316
|
+
no_op_warning_threshold: z.ZodDefault<z.ZodNumber>;
|
|
316
317
|
qa_gates: z.ZodOptional<z.ZodObject<{
|
|
317
318
|
required_tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
318
319
|
require_reviewer_test_engineer: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -497,6 +498,11 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
497
498
|
}, z.core.$strip>>;
|
|
498
499
|
}, z.core.$strip>>;
|
|
499
500
|
qa_retry_limit: z.ZodDefault<z.ZodNumber>;
|
|
501
|
+
execution_mode: z.ZodDefault<z.ZodEnum<{
|
|
502
|
+
strict: "strict";
|
|
503
|
+
balanced: "balanced";
|
|
504
|
+
fast: "fast";
|
|
505
|
+
}>>;
|
|
500
506
|
inject_phase_reminders: z.ZodDefault<z.ZodBoolean>;
|
|
501
507
|
hooks: z.ZodOptional<z.ZodObject<{
|
|
502
508
|
system_enhancer: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -585,6 +591,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
|
|
|
585
591
|
max_consecutive_errors: z.ZodDefault<z.ZodNumber>;
|
|
586
592
|
warning_threshold: z.ZodDefault<z.ZodNumber>;
|
|
587
593
|
idle_timeout_minutes: z.ZodDefault<z.ZodNumber>;
|
|
594
|
+
no_op_warning_threshold: z.ZodDefault<z.ZodNumber>;
|
|
588
595
|
qa_gates: z.ZodOptional<z.ZodObject<{
|
|
589
596
|
required_tools: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
590
597
|
require_reviewer_test_engineer: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { PluginConfig } from '../config';
|
|
8
8
|
import type { DelegationEnvelope, EnvelopeValidationResult } from '../types/delegation.js';
|
|
9
|
+
/**
|
|
10
|
+
* v6.33.1 CRIT-1: Fallback map for declared coder scope by taskId.
|
|
11
|
+
* When messagesTransform sets declaredCoderScope on the architect session,
|
|
12
|
+
* the coder session may not exist yet. This map allows scope-guard to look up
|
|
13
|
+
* the scope by taskId when the session's declaredCoderScope is null.
|
|
14
|
+
*/
|
|
15
|
+
export declare const pendingCoderScopeByTaskId: Map<string, string[]>;
|
|
9
16
|
/**
|
|
10
17
|
* Parses a string to extract a DelegationEnvelope.
|
|
11
18
|
* Returns null if no valid envelope is found.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verification tests for callID→evidenceTaskId map in delegation-gate.ts
|
|
3
|
+
*
|
|
4
|
+
* Tests verify the map behavior indirectly through evidence recording outcomes:
|
|
5
|
+
* 1. Map stores callID→evidenceTaskId after determining the taskId
|
|
6
|
+
* 2. Map is checked first before getEvidenceTaskId fallback
|
|
7
|
+
* 3. Map entry is cleaned up after successful evidence recording
|
|
8
|
+
* 4. Map entry is cleaned up even when evidence recording errors
|
|
9
|
+
* 5. Fallback works when storedTaskId is not in map
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
@@ -23,7 +23,7 @@ export interface ScopeGuardConfig {
|
|
|
23
23
|
* @param _directory - The workspace directory (reserved for future use)
|
|
24
24
|
* @param injectAdvisory - Optional callback to push advisory to architect session
|
|
25
25
|
*/
|
|
26
|
-
export declare function createScopeGuardHook(config: Partial<ScopeGuardConfig>,
|
|
26
|
+
export declare function createScopeGuardHook(config: Partial<ScopeGuardConfig>, directory: string, injectAdvisory?: (sessionId: string, message: string) => void): {
|
|
27
27
|
toolBefore: (input: {
|
|
28
28
|
tool: string;
|
|
29
29
|
sessionID: string;
|
|
@@ -40,4 +40,4 @@ export declare function createScopeGuardHook(config: Partial<ScopeGuardConfig>,
|
|
|
40
40
|
* @param scopeEntries - Array of declared scope entries (files or directories)
|
|
41
41
|
* @returns true if the file is within scope, false otherwise
|
|
42
42
|
*/
|
|
43
|
-
export declare function isFileInScope(filePath: string, scopeEntries: string[]): boolean;
|
|
43
|
+
export declare function isFileInScope(filePath: string, scopeEntries: string[], directory?: string): boolean;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TRAJECTORY LOGGER (v6.31 Task 3.2)
|
|
3
|
+
*
|
|
4
|
+
* tool.execute.after hook that appends per-task tool call trajectories to a
|
|
5
|
+
* .swarm/evidence/{taskId}/trajectory.jsonl file. Only logs INSIDE delegation
|
|
6
|
+
* scope (when delegationActive is true on the session).
|
|
7
|
+
*
|
|
8
|
+
* Trajectories are used for post-hoc analysis, audit trails, and replay.
|
|
9
|
+
*/
|
|
10
|
+
export interface TrajectoryConfig {
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
max_lines: number;
|
|
13
|
+
}
|
|
14
|
+
export interface TrajectoryEntry {
|
|
15
|
+
tool: string;
|
|
16
|
+
args_summary: string;
|
|
17
|
+
verdict: string;
|
|
18
|
+
timestamp: string;
|
|
19
|
+
agent: string;
|
|
20
|
+
elapsed_ms: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Truncates a trajectory file to the newest half when maxLines is exceeded.
|
|
24
|
+
* Reads all lines, keeps the newest half, rewrites the file.
|
|
25
|
+
*
|
|
26
|
+
* @param filePath - Absolute path to the trajectory.jsonl file
|
|
27
|
+
* @param maxLines - Maximum number of lines to retain
|
|
28
|
+
*/
|
|
29
|
+
export declare function truncateTrajectoryFile(filePath: string, maxLines: number): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Creates the trajectory logger hook pair.
|
|
32
|
+
*
|
|
33
|
+
* @param config - TrajectoryConfig { enabled: boolean (default true), max_lines: number (default 500) }
|
|
34
|
+
* @param _directory - Reserved for future use (evidence path derived from session taskId)
|
|
35
|
+
* @returns Object with toolAfter handler
|
|
36
|
+
*/
|
|
37
|
+
export declare function createTrajectoryLoggerHook(config: Partial<TrajectoryConfig>, _directory: string): {
|
|
38
|
+
toolAfter: (input: {
|
|
39
|
+
tool: string;
|
|
40
|
+
sessionID: string;
|
|
41
|
+
callID: string;
|
|
42
|
+
args?: Record<string, unknown>;
|
|
43
|
+
}, output: {
|
|
44
|
+
title: string;
|
|
45
|
+
output: string;
|
|
46
|
+
metadata: unknown;
|
|
47
|
+
}) => Promise<void>;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Records the start time for a tool call (called from toolBefore).
|
|
51
|
+
* Stored in a module-level Map for correlation with toolAfter.
|
|
52
|
+
*
|
|
53
|
+
* @param sessionId - Session identifier
|
|
54
|
+
* @param callID - Tool call identifier
|
|
55
|
+
* @param startTime - Start timestamp in milliseconds
|
|
56
|
+
*/
|
|
57
|
+
export declare function recordToolCallStart(sessionId: string, callID: string, startTime: number): void;
|