opencode-swarm 7.99.0 → 7.99.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 +5 -3
- package/dist/agents/_prompt-helpers.d.ts +1 -0
- package/dist/cli/{evidence-summary-service-4hs44n2c.js → evidence-summary-service-gvd7mw7v.js} +1 -1
- package/dist/cli/{explorer-jc46negv.js → explorer-rwfvbbx5.js} +1 -1
- package/dist/cli/{guardrail-explain-ktm6szbm.js → guardrail-explain-6g1japmf.js} +4 -4
- package/dist/cli/{index-hw8r3e5p.js → index-brpm7xs3.js} +66 -20
- package/dist/cli/{index-wwnjw0fb.js → index-qcr60fgm.js} +26 -13
- package/dist/cli/{index-ft4gehk1.js → index-sy329dh4.js} +1 -1
- package/dist/cli/{index-4pt2py5p.js → index-xy3gw0rw.js} +4 -4
- package/dist/cli/{index-2a6ppa65.js → index-ydgy7vg5.js} +12 -7
- package/dist/cli/index.js +3 -3
- package/dist/evidence/manager.d.ts +5 -0
- package/dist/hooks/knowledge-migrator.d.ts +7 -0
- package/dist/index.js +144 -167
- package/dist/turbo/lean/conflicts.d.ts +2 -13
- package/dist/utils/path.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Most AI coding tools let one model write code and ask that same model whether th
|
|
|
39
39
|
- 🔄 **Phase completion gates** — completion-verify and drift verifier gates enforced before phase completion
|
|
40
40
|
- 🔁 **Resumable sessions** — all state saved to `.swarm/`; pick up any project any day
|
|
41
41
|
- 🖥️ **PR Monitor** — GitHub PR subscription and background polling via `gh` CLI; delivers real-time CI, review, and merge status updates via the AutomationEventBus (FR-001, opt-in via `pr_monitor.enabled: true`). Subscribe with `/swarm pr subscribe <pr-url|owner/repo#N|N>`; unsubscribe with `/swarm pr unsubscribe <pr-url|owner/repo#N|N>`; check status with `/swarm pr status`. Enable `auto_pr_feedback: true` in `pr_monitor` config to inject `[MODE: PR_FEEDBACK pr="URL"]` on CI failures and merge conflicts automatically.
|
|
42
|
-
- 🌐 **
|
|
42
|
+
- 🌐 **12 full language profiles** (TypeScript, Python, Go, Rust, Java, Kotlin, C/C++, C#, Ruby, Swift, Dart, PHP) with **tree-sitter parse validation across 20 grammars** (adds JavaScript, CSS, Bash, PowerShell, INI, Regex — and `.tsx` / `.c` aliases) — extending: see [docs/adding-a-language.md](docs/adding-a-language.md)
|
|
43
43
|
- 🛡️ **Built-in security** — SAST, secrets scanning, dependency audit per task
|
|
44
44
|
- 🔒 **Scope enforcement** — Validates write targets against declared scope with cross-process persistence, TTL expiry, and scope-aware destructive command blocking. **Handles both single-string and array-based path arguments** (`files[]`, `paths[]`, `targetFiles[]`) to prevent scope bypass via multi-file tool calls.
|
|
45
45
|
- 📝 **Shell write detection** — Static analysis of POSIX/PowerShell/cmd commands to detect file writes (redirects, builtins, in-place editors, network downloads, archive extraction, git destructive ops) before execution
|
|
@@ -522,6 +522,8 @@ Every agent runs inside a circuit breaker that prevents runaway behavior:
|
|
|
522
522
|
|
|
523
523
|
Limits reset per task. Per-agent overrides available in config.
|
|
524
524
|
|
|
525
|
+
> **Note:** Built-in per-agent profiles override the global `max_consecutive_errors` to **8** for `architect`, `coder`, `test_engineer`, `explorer`, and `reviewer` (`src/config/schema.ts` `DEFAULT_AGENT_PROFILES`). The `5` shown above is the `GuardrailsConfigSchema` global default that applies only when no per-agent profile sets the value. See [docs/installation.md § Guardrails Configuration](docs/installation.md#guardrails-configuration) for the full schema and [docs/configuration.md § Per-agent override fields](docs/configuration.md#per-agent-override-fields) for how to override.
|
|
526
|
+
|
|
525
527
|
### File Authority (Per-Agent Write Permissions)
|
|
526
528
|
|
|
527
529
|
Each agent can only write to specific paths:
|
|
@@ -540,7 +542,7 @@ Built-in tools verify every task before it ships:
|
|
|
540
542
|
|
|
541
543
|
- **syntax_check** — Tree-sitter validation across the configured language grammar map
|
|
542
544
|
- **placeholder_scan** — Catches TODOs, stubs, incomplete code
|
|
543
|
-
- **sast_scan** —
|
|
545
|
+
- **sast_scan** — 65 security rules across 7 languages (offline)
|
|
544
546
|
- **sbom_generate** — Dependency tracking (CycloneDX)
|
|
545
547
|
- **quality_budget** — Complexity, duplication, test ratio limits
|
|
546
548
|
|
|
@@ -796,7 +798,7 @@ Every candidate passes a 3-gate pipeline before entering quarantine:
|
|
|
796
798
|
|------|-------------|
|
|
797
799
|
| syntax_check | Tree-sitter validation across the configured language grammar map |
|
|
798
800
|
| placeholder_scan | Catches TODOs, FIXMEs, stubs, placeholder text |
|
|
799
|
-
| sast_scan | Offline security analysis,
|
|
801
|
+
| sast_scan | Offline security analysis, 65 rules, 7 languages |
|
|
800
802
|
| sbom_generate | CycloneDX dependency tracking, 8 ecosystems |
|
|
801
803
|
| build_check | Runs your project's native build/typecheck |
|
|
802
804
|
| incremental_verify | Post-coder hook for TS/JS, Go, Rust, Python, and C#; configured by `incremental_verify.*`, not invoked as a registered tool |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolvePrompt(base: string, custom?: string, append?: string): string;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
4
|
+
} from "./index-sy329dh4.js";
|
|
5
|
+
import"./index-brpm7xs3.js";
|
|
6
6
|
import"./index-xsswhy6k.js";
|
|
7
|
-
import"./index-
|
|
7
|
+
import"./index-ydgy7vg5.js";
|
|
8
8
|
import"./index-vwyjkzgs.js";
|
|
9
9
|
import"./index-f7nma02k.js";
|
|
10
10
|
import"./index-svf2zjxs.js";
|
|
11
11
|
import"./index-7hnwnw5g.js";
|
|
12
|
-
import"./index-
|
|
12
|
+
import"./index-qcr60fgm.js";
|
|
13
13
|
import"./index-adz3nk9b.js";
|
|
14
14
|
import"./index-v4fcn4tr.js";
|
|
15
15
|
import"./index-r8f89sm9.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
READ_ONLY_LANE_GUIDANCE
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-ydgy7vg5.js";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_SKILL_MIN_CONFIDENCE,
|
|
7
7
|
DEFAULT_SKILL_MIN_CONFIRMATIONS,
|
|
@@ -114,7 +114,7 @@ import {
|
|
|
114
114
|
transientBackoff,
|
|
115
115
|
validateProjectRoot,
|
|
116
116
|
writeProjectedSpecSync
|
|
117
|
-
} from "./index-
|
|
117
|
+
} from "./index-qcr60fgm.js";
|
|
118
118
|
import {
|
|
119
119
|
_internals as _internals2,
|
|
120
120
|
_internals1 as _internals3,
|
|
@@ -909,7 +909,7 @@ var init_executor = __esm(() => {
|
|
|
909
909
|
// package.json
|
|
910
910
|
var package_default = {
|
|
911
911
|
name: "opencode-swarm",
|
|
912
|
-
version: "7.99.
|
|
912
|
+
version: "7.99.1",
|
|
913
913
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
914
914
|
main: "dist/index.js",
|
|
915
915
|
types: "dist/index.d.ts",
|
|
@@ -3738,6 +3738,9 @@ function clearAllScopes(directory) {
|
|
|
3738
3738
|
// src/hooks/shell-write-detect.ts
|
|
3739
3739
|
import * as path8 from "path";
|
|
3740
3740
|
import parse from "bash-parser";
|
|
3741
|
+
function buildDedupeKey(category, operator, path9) {
|
|
3742
|
+
return `${category}|${operator}|${path9 ?? "null"}`;
|
|
3743
|
+
}
|
|
3741
3744
|
var REDIRECT_WRITE_TOKENS = new Set([
|
|
3742
3745
|
"GREAT",
|
|
3743
3746
|
"DGREAT",
|
|
@@ -4756,7 +4759,7 @@ function detectPosixWrites(command) {
|
|
|
4756
4759
|
}
|
|
4757
4760
|
const seen = new Set;
|
|
4758
4761
|
const writes = allWrites.filter((wt) => {
|
|
4759
|
-
const key =
|
|
4762
|
+
const key = buildDedupeKey(wt.category, wt.operator, wt.path);
|
|
4760
4763
|
if (seen.has(key))
|
|
4761
4764
|
return false;
|
|
4762
4765
|
seen.add(key);
|
|
@@ -4781,7 +4784,7 @@ function detectWindowsWrites(command, shell) {
|
|
|
4781
4784
|
}
|
|
4782
4785
|
const seen = new Set;
|
|
4783
4786
|
const writes = allWrites.filter((wt) => {
|
|
4784
|
-
const key =
|
|
4787
|
+
const key = buildDedupeKey(wt.category, wt.operator, wt.path);
|
|
4785
4788
|
if (seen.has(key))
|
|
4786
4789
|
return false;
|
|
4787
4790
|
seen.add(key);
|
|
@@ -5036,7 +5039,7 @@ function resolveWriteTargets(command, writes, cwd) {
|
|
|
5036
5039
|
collectWritesWithNodes(ast, writesWithNodes, cwdStack);
|
|
5037
5040
|
const seen = new Set;
|
|
5038
5041
|
const deduplicated = writesWithNodes.filter((wwn) => {
|
|
5039
|
-
const key =
|
|
5042
|
+
const key = buildDedupeKey(wwn.write.category, wwn.write.operator, wwn.write.path);
|
|
5040
5043
|
if (seen.has(key))
|
|
5041
5044
|
return false;
|
|
5042
5045
|
seen.add(key);
|
|
@@ -5046,11 +5049,11 @@ function resolveWriteTargets(command, writes, cwd) {
|
|
|
5046
5049
|
for (const { write, context } of deduplicated) {
|
|
5047
5050
|
const resolvedPath = resolvePath(write.path, context);
|
|
5048
5051
|
const resolved = write.path !== null && !isDynamicPath(write.path);
|
|
5049
|
-
const key =
|
|
5052
|
+
const key = buildDedupeKey(write.category, write.operator, write.path);
|
|
5050
5053
|
resolvedMap.set(key, { resolvedPath, resolved });
|
|
5051
5054
|
}
|
|
5052
5055
|
return writes.map((original) => {
|
|
5053
|
-
const key =
|
|
5056
|
+
const key = buildDedupeKey(original.category, original.operator, original.path);
|
|
5054
5057
|
const resolved = resolvedMap.get(key);
|
|
5055
5058
|
if (resolved) {
|
|
5056
5059
|
return {
|
|
@@ -7650,7 +7653,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
7650
7653
|
let reportContent;
|
|
7651
7654
|
if (options.llmDelegate) {
|
|
7652
7655
|
try {
|
|
7653
|
-
const { CURATOR_POSTMORTEM_PROMPT: CURATOR_POSTMORTEM_PROMPT2 } = await import("./explorer-
|
|
7656
|
+
const { CURATOR_POSTMORTEM_PROMPT: CURATOR_POSTMORTEM_PROMPT2 } = await import("./explorer-rwfvbbx5.js");
|
|
7654
7657
|
const userInput = assembleLLMInput(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
|
|
7655
7658
|
const ac = new AbortController;
|
|
7656
7659
|
const timer = setTimeout(() => ac.abort(), 300000);
|
|
@@ -17914,7 +17917,7 @@ async function handleEvidenceCommand(directory, args) {
|
|
|
17914
17917
|
return formatTaskEvidenceMarkdown(evidenceData);
|
|
17915
17918
|
}
|
|
17916
17919
|
async function handleEvidenceSummaryCommand(directory) {
|
|
17917
|
-
const { buildEvidenceSummary } = await import("./evidence-summary-service-
|
|
17920
|
+
const { buildEvidenceSummary } = await import("./evidence-summary-service-gvd7mw7v.js");
|
|
17918
17921
|
const artifact = await buildEvidenceSummary(directory);
|
|
17919
17922
|
if (!artifact) {
|
|
17920
17923
|
return "No plan found. Run `/swarm plan` to check plan status.";
|
|
@@ -19424,12 +19427,50 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
|
19424
19427
|
|
|
19425
19428
|
// src/hooks/knowledge-migrator.ts
|
|
19426
19429
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
19430
|
+
const externalSentinelPath = path39.join(_directory, ".swarm", ".knowledge-external-migrated");
|
|
19431
|
+
const contextPath = path39.join(_directory, ".swarm", "context.md");
|
|
19432
|
+
if (_internals30.existsSync(externalSentinelPath)) {
|
|
19433
|
+
return {
|
|
19434
|
+
migrated: false,
|
|
19435
|
+
entriesMigrated: 0,
|
|
19436
|
+
entriesDropped: 0,
|
|
19437
|
+
entriesTotal: 0,
|
|
19438
|
+
skippedReason: "external-sentinel-exists"
|
|
19439
|
+
};
|
|
19440
|
+
}
|
|
19441
|
+
if (!_internals30.existsSync(contextPath)) {
|
|
19442
|
+
return {
|
|
19443
|
+
migrated: false,
|
|
19444
|
+
entriesMigrated: 0,
|
|
19445
|
+
entriesDropped: 0,
|
|
19446
|
+
entriesTotal: 0,
|
|
19447
|
+
skippedReason: "no-context-file"
|
|
19448
|
+
};
|
|
19449
|
+
}
|
|
19450
|
+
const contextContent = await _internals30.readFile(contextPath, "utf-8");
|
|
19451
|
+
if (contextContent.trim().length === 0) {
|
|
19452
|
+
return {
|
|
19453
|
+
migrated: false,
|
|
19454
|
+
entriesMigrated: 0,
|
|
19455
|
+
entriesDropped: 0,
|
|
19456
|
+
entriesTotal: 0,
|
|
19457
|
+
skippedReason: "empty-context"
|
|
19458
|
+
};
|
|
19459
|
+
}
|
|
19460
|
+
const lines = contextContent.split(`
|
|
19461
|
+
`);
|
|
19462
|
+
let entriesCount = 0;
|
|
19463
|
+
for (const line of lines) {
|
|
19464
|
+
if (line.trimStart().startsWith("- ")) {
|
|
19465
|
+
entriesCount++;
|
|
19466
|
+
}
|
|
19467
|
+
}
|
|
19468
|
+
await _internals30.writeSentinel(externalSentinelPath, entriesCount, entriesCount);
|
|
19427
19469
|
return {
|
|
19428
|
-
migrated:
|
|
19429
|
-
entriesMigrated:
|
|
19470
|
+
migrated: true,
|
|
19471
|
+
entriesMigrated: entriesCount,
|
|
19430
19472
|
entriesDropped: 0,
|
|
19431
|
-
entriesTotal:
|
|
19432
|
-
skippedReason: "no-context-file"
|
|
19473
|
+
entriesTotal: entriesCount
|
|
19433
19474
|
};
|
|
19434
19475
|
}
|
|
19435
19476
|
var _internals30 = {
|
|
@@ -19444,7 +19485,12 @@ var _internals30 = {
|
|
|
19444
19485
|
truncateLesson: truncateLesson2,
|
|
19445
19486
|
inferProjectName,
|
|
19446
19487
|
writeSentinel,
|
|
19447
|
-
resolveLegacyHiveKnowledgePath
|
|
19488
|
+
resolveLegacyHiveKnowledgePath,
|
|
19489
|
+
existsSync: existsSync23,
|
|
19490
|
+
readFileSync: readFileSync15,
|
|
19491
|
+
readFile: readFile11,
|
|
19492
|
+
mkdir: mkdir9,
|
|
19493
|
+
writeFile: writeFile9
|
|
19448
19494
|
};
|
|
19449
19495
|
async function migrateContextToKnowledge(directory, config) {
|
|
19450
19496
|
const sentinelPath = path39.join(directory, ".swarm", ".knowledge-migrated");
|
|
@@ -19782,8 +19828,8 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
19782
19828
|
schema_version: 1,
|
|
19783
19829
|
migration_tool: "knowledge-migrator.ts"
|
|
19784
19830
|
};
|
|
19785
|
-
await
|
|
19786
|
-
await
|
|
19831
|
+
await _internals30.mkdir(path39.dirname(sentinelPath), { recursive: true });
|
|
19832
|
+
await _internals30.writeFile(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
19787
19833
|
}
|
|
19788
19834
|
function resolveLegacyHiveKnowledgePath() {
|
|
19789
19835
|
const platform = process.platform;
|
|
@@ -32165,7 +32211,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
32165
32211
|
async function handleHelpCommand(ctx) {
|
|
32166
32212
|
const targetCommand = ctx.args.join(" ");
|
|
32167
32213
|
if (!targetCommand) {
|
|
32168
|
-
const { buildHelpText } = await import("./index-
|
|
32214
|
+
const { buildHelpText } = await import("./index-xy3gw0rw.js");
|
|
32169
32215
|
return buildHelpText();
|
|
32170
32216
|
}
|
|
32171
32217
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -32174,7 +32220,7 @@ async function handleHelpCommand(ctx) {
|
|
|
32174
32220
|
return _internals45.buildDetailedHelp(resolved.key, resolved.entry);
|
|
32175
32221
|
}
|
|
32176
32222
|
const similar = _internals45.findSimilarCommands(targetCommand);
|
|
32177
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
32223
|
+
const { buildHelpText: fullHelp } = await import("./index-xy3gw0rw.js");
|
|
32178
32224
|
if (similar.length > 0) {
|
|
32179
32225
|
return `Command '/swarm ${targetCommand}' not found.
|
|
32180
32226
|
|
|
@@ -32307,7 +32353,7 @@ var COMMAND_REGISTRY = {
|
|
|
32307
32353
|
},
|
|
32308
32354
|
"guardrail explain": {
|
|
32309
32355
|
handler: async (ctx) => {
|
|
32310
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
32356
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-6g1japmf.js");
|
|
32311
32357
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
32312
32358
|
},
|
|
32313
32359
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -939,6 +939,26 @@ var _internals2 = {
|
|
|
939
939
|
// src/turbo/lean/conflicts.ts
|
|
940
940
|
import * as fs3 from "fs";
|
|
941
941
|
import * as path3 from "path";
|
|
942
|
+
|
|
943
|
+
// src/utils/path.ts
|
|
944
|
+
function normalizePath(p) {
|
|
945
|
+
if (!p)
|
|
946
|
+
return "";
|
|
947
|
+
let result = p.replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^\.\//, "").replace(/(?:^|\/)\.\//g, "/");
|
|
948
|
+
result = result.replace(/\/$/, "");
|
|
949
|
+
result = result.replace(/\/\.$/, "");
|
|
950
|
+
if (process.platform === "win32")
|
|
951
|
+
result = result.toLowerCase();
|
|
952
|
+
if (!result) {
|
|
953
|
+
const norm = p.replace(/\\/g, "/");
|
|
954
|
+
if (norm === "." || norm === "./")
|
|
955
|
+
return ".";
|
|
956
|
+
return "";
|
|
957
|
+
}
|
|
958
|
+
return result;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
// src/turbo/lean/conflicts.ts
|
|
942
962
|
var DEFAULT_GLOBAL_FILES = [
|
|
943
963
|
"package.json",
|
|
944
964
|
"package-lock.json",
|
|
@@ -997,18 +1017,6 @@ var BARREL_FILE_PATTERNS = [
|
|
|
997
1017
|
/\/exports\.ts$/,
|
|
998
1018
|
/\/types\.ts$/
|
|
999
1019
|
];
|
|
1000
|
-
function normalizePath(filePath) {
|
|
1001
|
-
if (filePath === "." || filePath === "./") {
|
|
1002
|
-
return ".";
|
|
1003
|
-
}
|
|
1004
|
-
let result = filePath.replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^\.\//, "").replace(/(?:^|\/)\.\//g, "/");
|
|
1005
|
-
result = result.replace(/\/$/, "");
|
|
1006
|
-
result = result.replace(/\/\.$/, "");
|
|
1007
|
-
if (process.platform === "win32") {
|
|
1008
|
-
result = result.toLowerCase();
|
|
1009
|
-
}
|
|
1010
|
-
return result;
|
|
1011
|
-
}
|
|
1012
1020
|
function pathsConflict(path1, path22) {
|
|
1013
1021
|
if (process.platform === "win32") {
|
|
1014
1022
|
path1 = path1.toLowerCase();
|
|
@@ -3535,6 +3543,7 @@ async function saveEvidence(directory, taskId, evidence) {
|
|
|
3535
3543
|
const sanitizedTaskId = sanitizeTaskId2(taskId);
|
|
3536
3544
|
const relativePath = path7.join("evidence", sanitizedTaskId, "evidence.json");
|
|
3537
3545
|
validateSwarmPath(directory, relativePath);
|
|
3546
|
+
_internals5.validateEvidence(evidence);
|
|
3538
3547
|
return withEvidenceLock(directory, relativePath, "evidence-manager", sanitizedTaskId, async () => {
|
|
3539
3548
|
const evidencePath = validateSwarmPath(directory, relativePath);
|
|
3540
3549
|
const evidenceDir = path7.dirname(evidencePath);
|
|
@@ -3771,11 +3780,15 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles) {
|
|
|
3771
3780
|
}
|
|
3772
3781
|
return archived;
|
|
3773
3782
|
}
|
|
3783
|
+
function validateEvidence(evidence) {
|
|
3784
|
+
return EvidenceSchema.parse(evidence);
|
|
3785
|
+
}
|
|
3774
3786
|
var _internals5 = {
|
|
3775
3787
|
wrapFlatRetrospective,
|
|
3776
3788
|
loadEvidence,
|
|
3777
3789
|
listEvidenceTaskIds,
|
|
3778
|
-
validateProjectRoot
|
|
3790
|
+
validateProjectRoot,
|
|
3791
|
+
validateEvidence
|
|
3779
3792
|
};
|
|
3780
3793
|
|
|
3781
3794
|
// src/evidence/gate-bridge.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-sy329dh4.js";
|
|
5
5
|
import {
|
|
6
6
|
handleGuardrailLog
|
|
7
7
|
} from "./index-h9ptj4b1.js";
|
|
@@ -79,9 +79,9 @@ import {
|
|
|
79
79
|
handleWriteRetroCommand,
|
|
80
80
|
normalizeSwarmCommandInput,
|
|
81
81
|
resolveCommand
|
|
82
|
-
} from "./index-
|
|
82
|
+
} from "./index-brpm7xs3.js";
|
|
83
83
|
import"./index-xsswhy6k.js";
|
|
84
|
-
import"./index-
|
|
84
|
+
import"./index-ydgy7vg5.js";
|
|
85
85
|
import"./index-vwyjkzgs.js";
|
|
86
86
|
import"./index-f7nma02k.js";
|
|
87
87
|
import"./index-svf2zjxs.js";
|
|
@@ -90,7 +90,7 @@ import {
|
|
|
90
90
|
ORCHESTRATOR_NAME,
|
|
91
91
|
stripKnownSwarmPrefix
|
|
92
92
|
} from "./index-7hnwnw5g.js";
|
|
93
|
-
import"./index-
|
|
93
|
+
import"./index-qcr60fgm.js";
|
|
94
94
|
import"./index-adz3nk9b.js";
|
|
95
95
|
import"./index-v4fcn4tr.js";
|
|
96
96
|
import"./index-r8f89sm9.js";
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// src/agents/_prompt-helpers.ts
|
|
3
|
+
function resolvePrompt(base, custom, append) {
|
|
4
|
+
if (custom)
|
|
5
|
+
return custom;
|
|
6
|
+
if (append)
|
|
7
|
+
return `${base}
|
|
8
|
+
|
|
9
|
+
${append}`;
|
|
10
|
+
return base;
|
|
11
|
+
}
|
|
12
|
+
|
|
2
13
|
// src/agents/read-only-lane-guidance.ts
|
|
3
14
|
var READ_ONLY_LANE_GUIDANCE = `## READ-ONLY ADVISORY LANE CONTEXT
|
|
4
15
|
|
|
@@ -379,13 +390,7 @@ OUTPUT FORMAT:
|
|
|
379
390
|
`;
|
|
380
391
|
function createExplorerAgent(model, customPrompt, customAppendPrompt) {
|
|
381
392
|
let prompt = EXPLORER_PROMPT;
|
|
382
|
-
|
|
383
|
-
prompt = customPrompt;
|
|
384
|
-
} else if (customAppendPrompt) {
|
|
385
|
-
prompt = `${EXPLORER_PROMPT}
|
|
386
|
-
|
|
387
|
-
${customAppendPrompt}`;
|
|
388
|
-
}
|
|
393
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
389
394
|
return {
|
|
390
395
|
name: "explorer",
|
|
391
396
|
description: "Fast codebase discovery and analysis. Scans directory structure, identifies languages/frameworks, summarizes key files, and identifies areas where specialized domain knowledge may be beneficial.",
|
package/dist/cli/index.js
CHANGED
|
@@ -7,16 +7,16 @@ import {
|
|
|
7
7
|
getPluginLockFilePaths,
|
|
8
8
|
package_default,
|
|
9
9
|
resolveCommand
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-brpm7xs3.js";
|
|
11
11
|
import"./index-xsswhy6k.js";
|
|
12
|
-
import"./index-
|
|
12
|
+
import"./index-ydgy7vg5.js";
|
|
13
13
|
import"./index-vwyjkzgs.js";
|
|
14
14
|
import"./index-f7nma02k.js";
|
|
15
15
|
import"./index-svf2zjxs.js";
|
|
16
16
|
import {
|
|
17
17
|
DEFAULT_AGENT_CONFIGS
|
|
18
18
|
} from "./index-7hnwnw5g.js";
|
|
19
|
-
import"./index-
|
|
19
|
+
import"./index-qcr60fgm.js";
|
|
20
20
|
import"./index-adz3nk9b.js";
|
|
21
21
|
import"./index-v4fcn4tr.js";
|
|
22
22
|
import"./index-r8f89sm9.js";
|
|
@@ -93,6 +93,10 @@ export declare function checkRequirementCoverage(phase: number, directory: strin
|
|
|
93
93
|
* Returns array of archived (deleted) task IDs.
|
|
94
94
|
*/
|
|
95
95
|
export declare function archiveEvidence(directory: string, maxAgeDays: number, maxBundles?: number): Promise<string[]>;
|
|
96
|
+
/**
|
|
97
|
+
* Validates evidence through Zod. Exposed via _internals for DI testing.
|
|
98
|
+
*/
|
|
99
|
+
declare function validateEvidence(evidence: Evidence): Evidence;
|
|
96
100
|
/**
|
|
97
101
|
* DI seam for testability. Contains all test-mocked exports.
|
|
98
102
|
* Internal calls should use _internals.fn() instead of fn() directly.
|
|
@@ -102,5 +106,6 @@ export declare const _internals: {
|
|
|
102
106
|
loadEvidence: typeof loadEvidence;
|
|
103
107
|
listEvidenceTaskIds: typeof listEvidenceTaskIds;
|
|
104
108
|
validateProjectRoot: typeof validateProjectRoot;
|
|
109
|
+
validateEvidence: typeof validateEvidence;
|
|
105
110
|
};
|
|
106
111
|
export {};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/** One-time migration from .swarm/context.md → .swarm/knowledge.jsonl for existing projects. */
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
4
|
import { appendKnowledge } from './knowledge-store.js';
|
|
3
5
|
import type { KnowledgeCategory, KnowledgeConfig } from './knowledge-types.js';
|
|
4
6
|
export interface MigrationResult {
|
|
@@ -32,6 +34,11 @@ export declare const _internals: {
|
|
|
32
34
|
inferProjectName: typeof inferProjectName;
|
|
33
35
|
writeSentinel: typeof writeSentinel;
|
|
34
36
|
resolveLegacyHiveKnowledgePath: typeof resolveLegacyHiveKnowledgePath;
|
|
37
|
+
existsSync: typeof existsSync;
|
|
38
|
+
readFileSync: typeof readFileSync;
|
|
39
|
+
readFile: typeof readFile;
|
|
40
|
+
mkdir: typeof mkdir;
|
|
41
|
+
writeFile: typeof writeFile;
|
|
35
42
|
};
|
|
36
43
|
export declare function migrateContextToKnowledge(directory: string, config: KnowledgeConfig): Promise<MigrationResult>;
|
|
37
44
|
/**
|
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ var package_default;
|
|
|
69
69
|
var init_package = __esm(() => {
|
|
70
70
|
package_default = {
|
|
71
71
|
name: "opencode-swarm",
|
|
72
|
-
version: "7.99.
|
|
72
|
+
version: "7.99.1",
|
|
73
73
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
74
74
|
main: "dist/index.js",
|
|
75
75
|
types: "dist/index.d.ts",
|
|
@@ -17329,6 +17329,17 @@ var init_warning_buffer = __esm(() => {
|
|
|
17329
17329
|
deferredWarnings = [];
|
|
17330
17330
|
});
|
|
17331
17331
|
|
|
17332
|
+
// src/agents/_prompt-helpers.ts
|
|
17333
|
+
function resolvePrompt(base, custom2, append) {
|
|
17334
|
+
if (custom2)
|
|
17335
|
+
return custom2;
|
|
17336
|
+
if (append)
|
|
17337
|
+
return `${base}
|
|
17338
|
+
|
|
17339
|
+
${append}`;
|
|
17340
|
+
return base;
|
|
17341
|
+
}
|
|
17342
|
+
|
|
17332
17343
|
// src/config/bundled-skills.ts
|
|
17333
17344
|
import * as fs2 from "node:fs";
|
|
17334
17345
|
import * as fsp from "node:fs/promises";
|
|
@@ -19371,21 +19382,27 @@ var init_task_commit = __esm(() => {
|
|
|
19371
19382
|
};
|
|
19372
19383
|
});
|
|
19373
19384
|
|
|
19374
|
-
// src/
|
|
19375
|
-
|
|
19376
|
-
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
return ".";
|
|
19380
|
-
}
|
|
19381
|
-
let result = filePath.replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^\.\//, "").replace(/(?:^|\/)\.\//g, "/");
|
|
19385
|
+
// src/utils/path.ts
|
|
19386
|
+
function normalizePath(p) {
|
|
19387
|
+
if (!p)
|
|
19388
|
+
return "";
|
|
19389
|
+
let result = p.replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^\.\//, "").replace(/(?:^|\/)\.\//g, "/");
|
|
19382
19390
|
result = result.replace(/\/$/, "");
|
|
19383
19391
|
result = result.replace(/\/\.$/, "");
|
|
19384
|
-
if (process.platform === "win32")
|
|
19392
|
+
if (process.platform === "win32")
|
|
19385
19393
|
result = result.toLowerCase();
|
|
19394
|
+
if (!result) {
|
|
19395
|
+
const norm = p.replace(/\\/g, "/");
|
|
19396
|
+
if (norm === "." || norm === "./")
|
|
19397
|
+
return ".";
|
|
19398
|
+
return "";
|
|
19386
19399
|
}
|
|
19387
19400
|
return result;
|
|
19388
19401
|
}
|
|
19402
|
+
|
|
19403
|
+
// src/turbo/lean/conflicts.ts
|
|
19404
|
+
import * as fs7 from "node:fs";
|
|
19405
|
+
import * as path10 from "node:path";
|
|
19389
19406
|
function isPathSafe(filePath) {
|
|
19390
19407
|
const normalized = normalizePath(filePath);
|
|
19391
19408
|
if (normalized.includes("..")) {
|
|
@@ -23739,6 +23756,7 @@ async function saveEvidence(directory, taskId, evidence) {
|
|
|
23739
23756
|
const sanitizedTaskId = sanitizeTaskId2(taskId);
|
|
23740
23757
|
const relativePath = path15.join("evidence", sanitizedTaskId, "evidence.json");
|
|
23741
23758
|
validateSwarmPath(directory, relativePath);
|
|
23759
|
+
_internals10.validateEvidence(evidence);
|
|
23742
23760
|
return withEvidenceLock(directory, relativePath, "evidence-manager", sanitizedTaskId, async () => {
|
|
23743
23761
|
const evidencePath = validateSwarmPath(directory, relativePath);
|
|
23744
23762
|
const evidenceDir = path15.dirname(evidencePath);
|
|
@@ -23970,6 +23988,9 @@ async function archiveEvidence(directory, maxAgeDays, maxBundles) {
|
|
|
23970
23988
|
}
|
|
23971
23989
|
return archived;
|
|
23972
23990
|
}
|
|
23991
|
+
function validateEvidence(evidence) {
|
|
23992
|
+
return EvidenceSchema.parse(evidence);
|
|
23993
|
+
}
|
|
23973
23994
|
var VALID_EVIDENCE_TYPES, sanitizeTaskId2, MAX_DEPTH = 20, PROJECT_INDICATORS, LEGACY_TASK_COMPLEXITY_MAP, _internals10;
|
|
23974
23995
|
var init_manager2 = __esm(() => {
|
|
23975
23996
|
init_zod();
|
|
@@ -24017,7 +24038,8 @@ var init_manager2 = __esm(() => {
|
|
|
24017
24038
|
wrapFlatRetrospective,
|
|
24018
24039
|
loadEvidence,
|
|
24019
24040
|
listEvidenceTaskIds,
|
|
24020
|
-
validateProjectRoot
|
|
24041
|
+
validateProjectRoot,
|
|
24042
|
+
validateEvidence
|
|
24021
24043
|
};
|
|
24022
24044
|
});
|
|
24023
24045
|
|
|
@@ -41214,6 +41236,9 @@ var require_src = __commonJS((exports, module) => {
|
|
|
41214
41236
|
|
|
41215
41237
|
// src/hooks/shell-write-detect.ts
|
|
41216
41238
|
import * as path25 from "node:path";
|
|
41239
|
+
function buildDedupeKey(category, operator, path26) {
|
|
41240
|
+
return `${category}|${operator}|${path26 ?? "null"}`;
|
|
41241
|
+
}
|
|
41217
41242
|
function detectProcessSubstitutionWrites(command) {
|
|
41218
41243
|
const results = [];
|
|
41219
41244
|
const writeProcSubPattern = />\s*\(([^)]+)\)/g;
|
|
@@ -42188,7 +42213,7 @@ function detectPosixWrites(command) {
|
|
|
42188
42213
|
}
|
|
42189
42214
|
const seen = new Set;
|
|
42190
42215
|
const writes = allWrites.filter((wt) => {
|
|
42191
|
-
const key =
|
|
42216
|
+
const key = buildDedupeKey(wt.category, wt.operator, wt.path);
|
|
42192
42217
|
if (seen.has(key))
|
|
42193
42218
|
return false;
|
|
42194
42219
|
seen.add(key);
|
|
@@ -42213,7 +42238,7 @@ function detectWindowsWrites(command, shell) {
|
|
|
42213
42238
|
}
|
|
42214
42239
|
const seen = new Set;
|
|
42215
42240
|
const writes = allWrites.filter((wt) => {
|
|
42216
|
-
const key =
|
|
42241
|
+
const key = buildDedupeKey(wt.category, wt.operator, wt.path);
|
|
42217
42242
|
if (seen.has(key))
|
|
42218
42243
|
return false;
|
|
42219
42244
|
seen.add(key);
|
|
@@ -42468,7 +42493,7 @@ function resolveWriteTargets(command, writes, cwd) {
|
|
|
42468
42493
|
collectWritesWithNodes(ast, writesWithNodes, cwdStack);
|
|
42469
42494
|
const seen = new Set;
|
|
42470
42495
|
const deduplicated = writesWithNodes.filter((wwn) => {
|
|
42471
|
-
const key =
|
|
42496
|
+
const key = buildDedupeKey(wwn.write.category, wwn.write.operator, wwn.write.path);
|
|
42472
42497
|
if (seen.has(key))
|
|
42473
42498
|
return false;
|
|
42474
42499
|
seen.add(key);
|
|
@@ -42478,11 +42503,11 @@ function resolveWriteTargets(command, writes, cwd) {
|
|
|
42478
42503
|
for (const { write, context } of deduplicated) {
|
|
42479
42504
|
const resolvedPath = resolvePath(write.path, context);
|
|
42480
42505
|
const resolved = write.path !== null && !isDynamicPath(write.path);
|
|
42481
|
-
const key =
|
|
42506
|
+
const key = buildDedupeKey(write.category, write.operator, write.path);
|
|
42482
42507
|
resolvedMap.set(key, { resolvedPath, resolved });
|
|
42483
42508
|
}
|
|
42484
42509
|
return writes.map((original) => {
|
|
42485
|
-
const key =
|
|
42510
|
+
const key = buildDedupeKey(original.category, original.operator, original.path);
|
|
42486
42511
|
const resolved = resolvedMap.get(key);
|
|
42487
42512
|
if (resolved) {
|
|
42488
42513
|
return {
|
|
@@ -63255,13 +63280,7 @@ __export(exports_explorer, {
|
|
|
63255
63280
|
});
|
|
63256
63281
|
function createExplorerAgent(model, customPrompt, customAppendPrompt) {
|
|
63257
63282
|
let prompt = EXPLORER_PROMPT;
|
|
63258
|
-
|
|
63259
|
-
prompt = customPrompt;
|
|
63260
|
-
} else if (customAppendPrompt) {
|
|
63261
|
-
prompt = `${EXPLORER_PROMPT}
|
|
63262
|
-
|
|
63263
|
-
${customAppendPrompt}`;
|
|
63264
|
-
}
|
|
63283
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
63265
63284
|
return {
|
|
63266
63285
|
name: "explorer",
|
|
63267
63286
|
description: "Fast codebase discovery and analysis. Scans directory structure, identifies languages/frameworks, summarizes key files, and identifies areas where specialized domain knowledge may be beneficial.",
|
|
@@ -83526,12 +83545,50 @@ import { mkdir as mkdir17, readFile as readFile19, writeFile as writeFile15 } fr
|
|
|
83526
83545
|
import * as os16 from "node:os";
|
|
83527
83546
|
import * as path76 from "node:path";
|
|
83528
83547
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
83548
|
+
const externalSentinelPath = path76.join(_directory, ".swarm", ".knowledge-external-migrated");
|
|
83549
|
+
const contextPath = path76.join(_directory, ".swarm", "context.md");
|
|
83550
|
+
if (_internals51.existsSync(externalSentinelPath)) {
|
|
83551
|
+
return {
|
|
83552
|
+
migrated: false,
|
|
83553
|
+
entriesMigrated: 0,
|
|
83554
|
+
entriesDropped: 0,
|
|
83555
|
+
entriesTotal: 0,
|
|
83556
|
+
skippedReason: "external-sentinel-exists"
|
|
83557
|
+
};
|
|
83558
|
+
}
|
|
83559
|
+
if (!_internals51.existsSync(contextPath)) {
|
|
83560
|
+
return {
|
|
83561
|
+
migrated: false,
|
|
83562
|
+
entriesMigrated: 0,
|
|
83563
|
+
entriesDropped: 0,
|
|
83564
|
+
entriesTotal: 0,
|
|
83565
|
+
skippedReason: "no-context-file"
|
|
83566
|
+
};
|
|
83567
|
+
}
|
|
83568
|
+
const contextContent = await _internals51.readFile(contextPath, "utf-8");
|
|
83569
|
+
if (contextContent.trim().length === 0) {
|
|
83570
|
+
return {
|
|
83571
|
+
migrated: false,
|
|
83572
|
+
entriesMigrated: 0,
|
|
83573
|
+
entriesDropped: 0,
|
|
83574
|
+
entriesTotal: 0,
|
|
83575
|
+
skippedReason: "empty-context"
|
|
83576
|
+
};
|
|
83577
|
+
}
|
|
83578
|
+
const lines = contextContent.split(`
|
|
83579
|
+
`);
|
|
83580
|
+
let entriesCount = 0;
|
|
83581
|
+
for (const line of lines) {
|
|
83582
|
+
if (line.trimStart().startsWith("- ")) {
|
|
83583
|
+
entriesCount++;
|
|
83584
|
+
}
|
|
83585
|
+
}
|
|
83586
|
+
await _internals51.writeSentinel(externalSentinelPath, entriesCount, entriesCount);
|
|
83529
83587
|
return {
|
|
83530
|
-
migrated:
|
|
83531
|
-
entriesMigrated:
|
|
83588
|
+
migrated: true,
|
|
83589
|
+
entriesMigrated: entriesCount,
|
|
83532
83590
|
entriesDropped: 0,
|
|
83533
|
-
entriesTotal:
|
|
83534
|
-
skippedReason: "no-context-file"
|
|
83591
|
+
entriesTotal: entriesCount
|
|
83535
83592
|
};
|
|
83536
83593
|
}
|
|
83537
83594
|
async function migrateContextToKnowledge(directory, config3) {
|
|
@@ -83870,8 +83927,8 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
83870
83927
|
schema_version: 1,
|
|
83871
83928
|
migration_tool: "knowledge-migrator.ts"
|
|
83872
83929
|
};
|
|
83873
|
-
await
|
|
83874
|
-
await
|
|
83930
|
+
await _internals51.mkdir(path76.dirname(sentinelPath), { recursive: true });
|
|
83931
|
+
await _internals51.writeFile(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
83875
83932
|
}
|
|
83876
83933
|
function resolveLegacyHiveKnowledgePath() {
|
|
83877
83934
|
const platform = process.platform;
|
|
@@ -83903,7 +83960,12 @@ var init_knowledge_migrator = __esm(() => {
|
|
|
83903
83960
|
truncateLesson: truncateLesson2,
|
|
83904
83961
|
inferProjectName,
|
|
83905
83962
|
writeSentinel,
|
|
83906
|
-
resolveLegacyHiveKnowledgePath
|
|
83963
|
+
resolveLegacyHiveKnowledgePath,
|
|
83964
|
+
existsSync: existsSync43,
|
|
83965
|
+
readFileSync: readFileSync27,
|
|
83966
|
+
readFile: readFile19,
|
|
83967
|
+
mkdir: mkdir17,
|
|
83968
|
+
writeFile: writeFile15
|
|
83907
83969
|
};
|
|
83908
83970
|
});
|
|
83909
83971
|
|
|
@@ -102308,13 +102370,7 @@ function buildSlashCommandsList() {
|
|
|
102308
102370
|
}
|
|
102309
102371
|
function createArchitectAgent(model, customPrompt, customAppendPrompt, adversarialTesting, council, uiReview, memoryEnabled = false, architecturalSupervision, designDocsEnabled = false, externalSkillsEnabled = false, turboEnabled = false, skillsEnabled = false) {
|
|
102310
102372
|
let prompt = ARCHITECT_PROMPT;
|
|
102311
|
-
|
|
102312
|
-
prompt = customPrompt;
|
|
102313
|
-
} else if (customAppendPrompt) {
|
|
102314
|
-
prompt = `${ARCHITECT_PROMPT}
|
|
102315
|
-
|
|
102316
|
-
${customAppendPrompt}`;
|
|
102317
|
-
}
|
|
102373
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
102318
102374
|
prompt = prompt?.replace("{{YOUR_TOOLS}}", buildYourToolsList(council, memoryEnabled, externalSkillsEnabled, turboEnabled, skillsEnabled))?.replace("{{AVAILABLE_TOOLS}}", buildAvailableToolsList(council, memoryEnabled, externalSkillsEnabled, turboEnabled, skillsEnabled))?.replace("{{SLASH_COMMANDS}}", buildSlashCommandsList());
|
|
102319
102375
|
prompt = prompt?.replace(/\{\{QA_GATE_DIALOGUE_SPECIFY\}\}/g, buildQaGateSelectionDialogue("SPECIFY"))?.replace(/\{\{QA_GATE_DIALOGUE_BRAINSTORM\}\}/g, buildQaGateSelectionDialogue("BRAINSTORM"))?.replace(/\{\{QA_GATE_DIALOGUE_PLAN\}\}/g, buildQaGateSelectionDialogue("PLAN"));
|
|
102320
102376
|
const councilBlock = buildCouncilWorkflow(council);
|
|
@@ -103370,13 +103426,7 @@ var init_architect = __esm(() => {
|
|
|
103370
103426
|
// src/agents/coder.ts
|
|
103371
103427
|
function createCoderAgent(model, customPrompt, customAppendPrompt) {
|
|
103372
103428
|
let prompt = CODER_PROMPT;
|
|
103373
|
-
|
|
103374
|
-
prompt = customPrompt;
|
|
103375
|
-
} else if (customAppendPrompt) {
|
|
103376
|
-
prompt = `${CODER_PROMPT}
|
|
103377
|
-
|
|
103378
|
-
${customAppendPrompt}`;
|
|
103379
|
-
}
|
|
103429
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
103380
103430
|
return {
|
|
103381
103431
|
name: "coder",
|
|
103382
103432
|
description: "Production-quality code implementation specialist. Receives unified specifications and writes complete, working code.",
|
|
@@ -103626,6 +103676,7 @@ META.SUMMARY CONVENTION — When reporting task completion, include:
|
|
|
103626
103676
|
Write for the next agent reading the event log, not for a human.
|
|
103627
103677
|
|
|
103628
103678
|
`;
|
|
103679
|
+
var init_coder = () => {};
|
|
103629
103680
|
|
|
103630
103681
|
// src/agents/council-prompts.ts
|
|
103631
103682
|
var ROUND_PROTOCOL = `================================================================
|
|
@@ -104485,13 +104536,7 @@ var init_curator_agent = __esm(() => {
|
|
|
104485
104536
|
// src/agents/designer.ts
|
|
104486
104537
|
function createDesignerAgent(model, customPrompt, customAppendPrompt) {
|
|
104487
104538
|
let prompt = DESIGNER_PROMPT;
|
|
104488
|
-
|
|
104489
|
-
prompt = customPrompt;
|
|
104490
|
-
} else if (customAppendPrompt) {
|
|
104491
|
-
prompt = `${DESIGNER_PROMPT}
|
|
104492
|
-
|
|
104493
|
-
${customAppendPrompt}`;
|
|
104494
|
-
}
|
|
104539
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
104495
104540
|
return {
|
|
104496
104541
|
name: "designer",
|
|
104497
104542
|
description: "UI/UX design specification agent. Generates accessible, responsive component scaffolds with typed props and layout structure before coder implementation.",
|
|
@@ -104666,18 +104711,13 @@ RULES:
|
|
|
104666
104711
|
- Keep output under 3000 characters per component
|
|
104667
104712
|
|
|
104668
104713
|
`;
|
|
104714
|
+
var init_designer = () => {};
|
|
104669
104715
|
|
|
104670
104716
|
// src/agents/docs.ts
|
|
104671
104717
|
function createDocsAgent(model, customPrompt, customAppendPrompt, role = "standard") {
|
|
104672
104718
|
const roleConfig = ROLE_CONFIG2[role];
|
|
104673
104719
|
let prompt = roleConfig.basePrompt;
|
|
104674
|
-
|
|
104675
|
-
prompt = customPrompt;
|
|
104676
|
-
} else if (customAppendPrompt) {
|
|
104677
|
-
prompt = `${roleConfig.basePrompt}
|
|
104678
|
-
|
|
104679
|
-
${customAppendPrompt}`;
|
|
104680
|
-
}
|
|
104720
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
104681
104721
|
return {
|
|
104682
104722
|
name: roleConfig.name,
|
|
104683
104723
|
description: roleConfig.description,
|
|
@@ -104880,13 +104920,7 @@ var init_docs = __esm(() => {
|
|
|
104880
104920
|
// src/agents/researcher.ts
|
|
104881
104921
|
function createResearcherAgent(model, customPrompt, customAppendPrompt) {
|
|
104882
104922
|
let prompt = RESEARCHER_PROMPT;
|
|
104883
|
-
|
|
104884
|
-
prompt = customPrompt;
|
|
104885
|
-
} else if (customAppendPrompt) {
|
|
104886
|
-
prompt = `${RESEARCHER_PROMPT}
|
|
104887
|
-
|
|
104888
|
-
${customAppendPrompt}`;
|
|
104889
|
-
}
|
|
104923
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
104890
104924
|
return {
|
|
104891
104925
|
name: "researcher",
|
|
104892
104926
|
description: "Automated multi-source research specialist. Searches the web, GitHub, official docs, and academic sources, then synthesises findings with citations. Read-only.",
|
|
@@ -105036,13 +105070,7 @@ Do not pad responses with hedging when confidence is HIGH. A precise answer is m
|
|
|
105036
105070
|
// src/agents/reviewer.ts
|
|
105037
105071
|
function createReviewerAgent(model, customPrompt, customAppendPrompt) {
|
|
105038
105072
|
let prompt = REVIEWER_PROMPT;
|
|
105039
|
-
|
|
105040
|
-
prompt = customPrompt;
|
|
105041
|
-
} else if (customAppendPrompt) {
|
|
105042
|
-
prompt = `${REVIEWER_PROMPT}
|
|
105043
|
-
|
|
105044
|
-
${customAppendPrompt}`;
|
|
105045
|
-
}
|
|
105073
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
105046
105074
|
return {
|
|
105047
105075
|
name: "reviewer",
|
|
105048
105076
|
description: "Code reviewer. Verifies correctness, finds vulnerabilities, and checks quality across architect-specified dimensions.",
|
|
@@ -105330,12 +105358,7 @@ A blank APPROVED without reasoning is NOT acceptable — it indicates you did no
|
|
|
105330
105358
|
// src/agents/skill-improver.ts
|
|
105331
105359
|
function createSkillImproverAgent(model, customPrompt, customAppendPrompt) {
|
|
105332
105360
|
let prompt = DEFAULT_PROMPT;
|
|
105333
|
-
|
|
105334
|
-
prompt = customPrompt;
|
|
105335
|
-
else if (customAppendPrompt)
|
|
105336
|
-
prompt = `${DEFAULT_PROMPT}
|
|
105337
|
-
|
|
105338
|
-
${customAppendPrompt}`;
|
|
105361
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
105339
105362
|
const config3 = {
|
|
105340
105363
|
model,
|
|
105341
105364
|
temperature: 0.2,
|
|
@@ -105395,17 +105418,12 @@ least one non-empty predicate field (forbidden_actions / required_actions /
|
|
|
105395
105418
|
verification_checks). Hardened entries return to the active store; entries
|
|
105396
105419
|
that cannot be hardened are flagged retire_candidate for human review.
|
|
105397
105420
|
`;
|
|
105421
|
+
var init_skill_improver2 = () => {};
|
|
105398
105422
|
|
|
105399
105423
|
// src/agents/sme.ts
|
|
105400
105424
|
function createSMEAgent(model, customPrompt, customAppendPrompt) {
|
|
105401
105425
|
let prompt = SME_PROMPT;
|
|
105402
|
-
|
|
105403
|
-
prompt = customPrompt;
|
|
105404
|
-
} else if (customAppendPrompt) {
|
|
105405
|
-
prompt = `${SME_PROMPT}
|
|
105406
|
-
|
|
105407
|
-
${customAppendPrompt}`;
|
|
105408
|
-
}
|
|
105426
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
105409
105427
|
return {
|
|
105410
105428
|
name: "sme",
|
|
105411
105429
|
description: "Open-domain subject matter expert. Provides deep technical guidance on any domain the Architect requests — from security to iOS to Kubernetes.",
|
|
@@ -105562,12 +105580,7 @@ SME is read-only. Cache persistence is Architect's responsibility — save this
|
|
|
105562
105580
|
// src/agents/spec-writer.ts
|
|
105563
105581
|
function createSpecWriterAgent(model, customPrompt, customAppendPrompt) {
|
|
105564
105582
|
let prompt = DEFAULT_PROMPT2;
|
|
105565
|
-
|
|
105566
|
-
prompt = customPrompt;
|
|
105567
|
-
else if (customAppendPrompt)
|
|
105568
|
-
prompt = `${DEFAULT_PROMPT2}
|
|
105569
|
-
|
|
105570
|
-
${customAppendPrompt}`;
|
|
105583
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
105571
105584
|
const config3 = {
|
|
105572
105585
|
model,
|
|
105573
105586
|
temperature: 0.2,
|
|
@@ -105611,6 +105624,7 @@ If a <swarm_knowledge_directives> block is present in your context, treat it
|
|
|
105611
105624
|
as authoritative. For each applicable directive cite KNOWLEDGE_APPLIED: <id>
|
|
105612
105625
|
in your reply, or KNOWLEDGE_IGNORED: <id> reason=... when it does not apply.
|
|
105613
105626
|
`;
|
|
105627
|
+
var init_spec_writer = () => {};
|
|
105614
105628
|
|
|
105615
105629
|
// src/agents/template.ts
|
|
105616
105630
|
function emptyProjectContext() {
|
|
@@ -105641,13 +105655,7 @@ var UNRESOLVED = "unresolved (run /swarm preflight)";
|
|
|
105641
105655
|
// src/agents/test-engineer.ts
|
|
105642
105656
|
function createTestEngineerAgent(model, customPrompt, customAppendPrompt) {
|
|
105643
105657
|
let prompt = TEST_ENGINEER_PROMPT;
|
|
105644
|
-
|
|
105645
|
-
prompt = customPrompt;
|
|
105646
|
-
} else if (customAppendPrompt) {
|
|
105647
|
-
prompt = `${TEST_ENGINEER_PROMPT}
|
|
105648
|
-
|
|
105649
|
-
${customAppendPrompt}`;
|
|
105650
|
-
}
|
|
105658
|
+
prompt = resolvePrompt(prompt, customPrompt, customAppendPrompt);
|
|
105651
105659
|
return {
|
|
105652
105660
|
name: "test_engineer",
|
|
105653
105661
|
description: "Testing and validation specialist. Generates test cases, runs them, and reports structured PASS/FAIL verdicts.",
|
|
@@ -105880,6 +105888,7 @@ COVERAGE REPORTING:
|
|
|
105880
105888
|
- If COVERAGE_PCT < 70%, add a note: "COVERAGE_WARNING: Below 70% threshold — consider additional test cases for uncovered paths."
|
|
105881
105889
|
- The architect uses this to decide whether to request an additional test pass (Rule 10 / Phase 5 step 5h).
|
|
105882
105890
|
`;
|
|
105891
|
+
var init_test_engineer = () => {};
|
|
105883
105892
|
|
|
105884
105893
|
// src/agents/index.ts
|
|
105885
105894
|
import { mkdir as mkdir23, writeFile as writeFile19 } from "node:fs/promises";
|
|
@@ -106016,35 +106025,13 @@ If you call @coder instead of @${swarmId}_coder, the call will FAIL or go to the
|
|
|
106016
106025
|
}
|
|
106017
106026
|
agents.push(applyOverrides(architect, swarmAgents, swarmPrefix, quiet));
|
|
106018
106027
|
}
|
|
106019
|
-
|
|
106020
|
-
|
|
106021
|
-
|
|
106022
|
-
|
|
106023
|
-
|
|
106024
|
-
|
|
106025
|
-
|
|
106026
|
-
const smePrompts = getPrompts("sme");
|
|
106027
|
-
const sme = createSMEAgent(getModel("sme"), smePrompts.prompt, smePrompts.appendPrompt);
|
|
106028
|
-
sme.name = prefixName("sme");
|
|
106029
|
-
agents.push(applyOverrides(sme, swarmAgents, swarmPrefix, quiet));
|
|
106030
|
-
}
|
|
106031
|
-
if (!isAgentDisabled("researcher", swarmAgents, swarmPrefix)) {
|
|
106032
|
-
const researcherPrompts = getPrompts("researcher");
|
|
106033
|
-
const researcher = createResearcherAgent(getModel("researcher"), researcherPrompts.prompt, researcherPrompts.appendPrompt);
|
|
106034
|
-
researcher.name = prefixName("researcher");
|
|
106035
|
-
agents.push(applyOverrides(researcher, swarmAgents, swarmPrefix, quiet));
|
|
106036
|
-
}
|
|
106037
|
-
if (!isAgentDisabled("coder", swarmAgents, swarmPrefix)) {
|
|
106038
|
-
const coderPrompts = getPrompts("coder");
|
|
106039
|
-
const coder = createCoderAgent(getModel("coder"), coderPrompts.prompt, coderPrompts.appendPrompt);
|
|
106040
|
-
coder.name = prefixName("coder");
|
|
106041
|
-
agents.push(applyOverrides(coder, swarmAgents, swarmPrefix, quiet));
|
|
106042
|
-
}
|
|
106043
|
-
if (!isAgentDisabled("reviewer", swarmAgents, swarmPrefix)) {
|
|
106044
|
-
const reviewerPrompts = getPrompts("reviewer");
|
|
106045
|
-
const reviewer = createReviewerAgent(getModel("reviewer"), reviewerPrompts.prompt, reviewerPrompts.appendPrompt);
|
|
106046
|
-
reviewer.name = prefixName("reviewer");
|
|
106047
|
-
agents.push(applyOverrides(reviewer, swarmAgents, swarmPrefix, quiet));
|
|
106028
|
+
for (const { name, factory } of TYPE_A_AGENTS) {
|
|
106029
|
+
if (!isAgentDisabled(name, swarmAgents, swarmPrefix)) {
|
|
106030
|
+
const prompts = getPrompts(name);
|
|
106031
|
+
const agent = factory(getModel(name), prompts.prompt, prompts.appendPrompt);
|
|
106032
|
+
agent.name = prefixName(name);
|
|
106033
|
+
agents.push(applyOverrides(agent, swarmAgents, swarmPrefix, quiet));
|
|
106034
|
+
}
|
|
106048
106035
|
}
|
|
106049
106036
|
if (!isAgentDisabled("critic", swarmAgents, swarmPrefix)) {
|
|
106050
106037
|
const criticPrompts = getPrompts("critic");
|
|
@@ -106101,24 +106088,6 @@ If you call @coder instead of @${swarmId}_coder, the call will FAIL or go to the
|
|
|
106101
106088
|
curatorConsolidation.name = prefixName("curator_consolidation");
|
|
106102
106089
|
agents.push(applyOverrides(curatorConsolidation, swarmAgents, swarmPrefix, quiet));
|
|
106103
106090
|
}
|
|
106104
|
-
if (!isAgentDisabled("skill_improver", swarmAgents, swarmPrefix)) {
|
|
106105
|
-
const sip = getPrompts("skill_improver");
|
|
106106
|
-
const skillImprover = createSkillImproverAgent(swarmAgents?.skill_improver?.model ?? getModel("skill_improver"), sip.prompt, sip.appendPrompt);
|
|
106107
|
-
skillImprover.name = prefixName("skill_improver");
|
|
106108
|
-
agents.push(applyOverrides(skillImprover, swarmAgents, swarmPrefix, quiet));
|
|
106109
|
-
}
|
|
106110
|
-
if (!isAgentDisabled("spec_writer", swarmAgents, swarmPrefix)) {
|
|
106111
|
-
const sw = getPrompts("spec_writer");
|
|
106112
|
-
const specWriter = createSpecWriterAgent(swarmAgents?.spec_writer?.model ?? getModel("spec_writer"), sw.prompt, sw.appendPrompt);
|
|
106113
|
-
specWriter.name = prefixName("spec_writer");
|
|
106114
|
-
agents.push(applyOverrides(specWriter, swarmAgents, swarmPrefix, quiet));
|
|
106115
|
-
}
|
|
106116
|
-
if (!isAgentDisabled("test_engineer", swarmAgents, swarmPrefix)) {
|
|
106117
|
-
const testPrompts = getPrompts("test_engineer");
|
|
106118
|
-
const testEngineer = createTestEngineerAgent(getModel("test_engineer"), testPrompts.prompt, testPrompts.appendPrompt);
|
|
106119
|
-
testEngineer.name = prefixName("test_engineer");
|
|
106120
|
-
agents.push(applyOverrides(testEngineer, swarmAgents, swarmPrefix, quiet));
|
|
106121
|
-
}
|
|
106122
106091
|
if (pluginConfig?.council?.general?.enabled === true) {
|
|
106123
106092
|
let councilAgentsCreated = 0;
|
|
106124
106093
|
if (!isAgentDisabled("reviewer", swarmAgents, swarmPrefix)) {
|
|
@@ -106153,12 +106122,6 @@ If you call @coder instead of @${swarmId}_coder, the call will FAIL or go to the
|
|
|
106153
106122
|
addDeferredWarning("[opencode-swarm] council.general.moderatorModel is deprecated and ignored. The architect now synthesizes the final answer directly using inline output rules. Remove this field (and council.general.moderator if set) from opencode-swarm.json to silence this warning.");
|
|
106154
106123
|
}
|
|
106155
106124
|
}
|
|
106156
|
-
if (!isAgentDisabled("docs", swarmAgents, swarmPrefix)) {
|
|
106157
|
-
const docsPrompts = getPrompts("docs");
|
|
106158
|
-
const docs = createDocsAgent(getModel("docs"), docsPrompts.prompt, docsPrompts.appendPrompt);
|
|
106159
|
-
docs.name = prefixName("docs");
|
|
106160
|
-
agents.push(applyOverrides(docs, swarmAgents, swarmPrefix, quiet));
|
|
106161
|
-
}
|
|
106162
106125
|
if (pluginConfig?.design_docs?.enabled === true && !isAgentDisabled("docs_design", swarmAgents, swarmPrefix)) {
|
|
106163
106126
|
const docsDesignPrompts = getPrompts("docs_design");
|
|
106164
106127
|
const docsDesign = createDocsAgent(getModel("docs_design"), docsDesignPrompts.prompt, docsDesignPrompts.appendPrompt, "design_docs");
|
|
@@ -106393,30 +106356,38 @@ function getAgentConfigs(config3, directory, sessionId, projectContext) {
|
|
|
106393
106356
|
}
|
|
106394
106357
|
return result;
|
|
106395
106358
|
}
|
|
106396
|
-
var warnedAgents, _swarmAgentsMap, KNOWN_VARIANT_VALUES;
|
|
106359
|
+
var warnedAgents, _swarmAgentsMap, KNOWN_VARIANT_VALUES, TYPE_A_AGENTS;
|
|
106397
106360
|
var init_agents2 = __esm(() => {
|
|
106398
106361
|
init_config();
|
|
106399
106362
|
init_constants();
|
|
106400
106363
|
init_schema();
|
|
106401
106364
|
init_warning_buffer();
|
|
106402
106365
|
init_architect();
|
|
106366
|
+
init_coder();
|
|
106403
106367
|
init_council_prompts();
|
|
106404
106368
|
init_critic();
|
|
106405
106369
|
init_curator_agent();
|
|
106370
|
+
init_designer();
|
|
106406
106371
|
init_docs();
|
|
106407
106372
|
init_explorer();
|
|
106408
106373
|
init_researcher();
|
|
106409
106374
|
init_reviewer();
|
|
106375
|
+
init_skill_improver2();
|
|
106410
106376
|
init_sme();
|
|
106377
|
+
init_spec_writer();
|
|
106378
|
+
init_test_engineer();
|
|
106411
106379
|
init_architect();
|
|
106380
|
+
init_coder();
|
|
106412
106381
|
init_council_prompts();
|
|
106413
106382
|
init_critic();
|
|
106414
106383
|
init_curator_agent();
|
|
106384
|
+
init_designer();
|
|
106415
106385
|
init_docs();
|
|
106416
106386
|
init_explorer();
|
|
106417
106387
|
init_researcher();
|
|
106418
106388
|
init_reviewer();
|
|
106419
106389
|
init_sme();
|
|
106390
|
+
init_test_engineer();
|
|
106420
106391
|
warnedAgents = new Set;
|
|
106421
106392
|
_swarmAgentsMap = new Map;
|
|
106422
106393
|
KNOWN_VARIANT_VALUES = new Set([
|
|
@@ -106427,6 +106398,17 @@ var init_agents2 = __esm(() => {
|
|
|
106427
106398
|
"xhigh",
|
|
106428
106399
|
"thinking"
|
|
106429
106400
|
]);
|
|
106401
|
+
TYPE_A_AGENTS = [
|
|
106402
|
+
{ name: "explorer", factory: createExplorerAgent },
|
|
106403
|
+
{ name: "sme", factory: createSMEAgent },
|
|
106404
|
+
{ name: "researcher", factory: createResearcherAgent },
|
|
106405
|
+
{ name: "coder", factory: createCoderAgent },
|
|
106406
|
+
{ name: "reviewer", factory: createReviewerAgent },
|
|
106407
|
+
{ name: "test_engineer", factory: createTestEngineerAgent },
|
|
106408
|
+
{ name: "docs", factory: createDocsAgent },
|
|
106409
|
+
{ name: "skill_improver", factory: createSkillImproverAgent },
|
|
106410
|
+
{ name: "spec_writer", factory: createSpecWriterAgent }
|
|
106411
|
+
];
|
|
106430
106412
|
});
|
|
106431
106413
|
|
|
106432
106414
|
// src/background/evidence-summary-integration.ts
|
|
@@ -123877,11 +123859,6 @@ function isSubagentDelegation(toolName, args2) {
|
|
|
123877
123859
|
return true;
|
|
123878
123860
|
return false;
|
|
123879
123861
|
}
|
|
123880
|
-
function normalizePath4(p) {
|
|
123881
|
-
if (!p)
|
|
123882
|
-
return "";
|
|
123883
|
-
return p.replace(/\\/g, "/").replace(/^\.\/+/, "").replace(/\/+$/, "");
|
|
123884
|
-
}
|
|
123885
123862
|
function isWithinDirectory(target, root) {
|
|
123886
123863
|
if (!target || !root)
|
|
123887
123864
|
return false;
|
|
@@ -123908,9 +123885,9 @@ var SEGMENT_PROTECTED = new Set([
|
|
|
123908
123885
|
function isProtectedPath2(filePath, config3) {
|
|
123909
123886
|
if (!filePath)
|
|
123910
123887
|
return false;
|
|
123911
|
-
const normalized =
|
|
123888
|
+
const normalized = normalizePath(filePath);
|
|
123912
123889
|
for (const prefix of ALWAYS_PROTECTED_PREFIXES) {
|
|
123913
|
-
const np =
|
|
123890
|
+
const np = normalizePath(prefix);
|
|
123914
123891
|
if (normalized === np || normalized.startsWith(`${np}/`))
|
|
123915
123892
|
return true;
|
|
123916
123893
|
}
|
|
@@ -123927,7 +123904,7 @@ function isProtectedPath2(filePath, config3) {
|
|
|
123927
123904
|
...config3?.permission_policy?.protected_paths ?? []
|
|
123928
123905
|
];
|
|
123929
123906
|
for (const candidate of protectedList) {
|
|
123930
|
-
const c =
|
|
123907
|
+
const c = normalizePath(candidate);
|
|
123931
123908
|
if (!c)
|
|
123932
123909
|
continue;
|
|
123933
123910
|
if (normalized === c)
|
|
@@ -123976,18 +123953,18 @@ function classifyPathRisk(filePath, context) {
|
|
|
123976
123953
|
}
|
|
123977
123954
|
})();
|
|
123978
123955
|
const withinProjectRoot = isWithinDirectory(absolute, context.directory) && isWithinDirectory(resolvedAbsolute, context.directory);
|
|
123979
|
-
const relative26 = path151.relative(context.directory, absolute)
|
|
123956
|
+
const relative26 = normalizePath(path151.relative(context.directory, absolute));
|
|
123980
123957
|
let withinDeclaredScope = null;
|
|
123981
123958
|
if (Array.isArray(context.declaredScope)) {
|
|
123982
123959
|
withinDeclaredScope = context.declaredScope.length === 0 ? false : context.declaredScope.some((scope) => {
|
|
123983
|
-
const s =
|
|
123960
|
+
const s = normalizePath(scope);
|
|
123984
123961
|
if (!s)
|
|
123985
123962
|
return false;
|
|
123986
123963
|
return relative26 === s || relative26.startsWith(`${s}/`);
|
|
123987
123964
|
});
|
|
123988
123965
|
}
|
|
123989
123966
|
const highRiskBuild = HIGH_RISK_BUILD_PATHS.some((entry) => {
|
|
123990
|
-
const e =
|
|
123967
|
+
const e = normalizePath(entry);
|
|
123991
123968
|
if (e.endsWith("/")) {
|
|
123992
123969
|
return relative26.startsWith(e);
|
|
123993
123970
|
}
|
|
@@ -151637,7 +151614,7 @@ var SKIP_DIRS = [
|
|
|
151637
151614
|
var SKIP_EXTENSIONS = [".test.", ".spec."];
|
|
151638
151615
|
var MAX_SPEC_SIZE = 10 * 1024 * 1024;
|
|
151639
151616
|
var ALLOWED_EXTENSIONS = [".json", ".yaml", ".yml"];
|
|
151640
|
-
function
|
|
151617
|
+
function normalizeApiPath(p) {
|
|
151641
151618
|
return p.replace(/\/$/, "").replace(/\{[^}]+\}/g, ":param").replace(/:[a-zA-Z_][a-zA-Z0-9_]*/g, ":param");
|
|
151642
151619
|
}
|
|
151643
151620
|
function discoverSpecFile(cwd, specFileArg) {
|
|
@@ -151814,7 +151791,7 @@ function extractRoutesFromFile(filePath) {
|
|
|
151814
151791
|
function findDrift(specPaths, codeRoutes) {
|
|
151815
151792
|
const specPathMap = new Map;
|
|
151816
151793
|
for (const sp of specPaths) {
|
|
151817
|
-
const normalized =
|
|
151794
|
+
const normalized = normalizeApiPath(sp.path);
|
|
151818
151795
|
if (!specPathMap.has(normalized)) {
|
|
151819
151796
|
specPathMap.set(normalized, []);
|
|
151820
151797
|
}
|
|
@@ -151822,7 +151799,7 @@ function findDrift(specPaths, codeRoutes) {
|
|
|
151822
151799
|
}
|
|
151823
151800
|
const codeRouteMap = new Map;
|
|
151824
151801
|
for (const cr of codeRoutes) {
|
|
151825
|
-
const normalized =
|
|
151802
|
+
const normalized = normalizeApiPath(cr.path);
|
|
151826
151803
|
if (!codeRouteMap.has(normalized)) {
|
|
151827
151804
|
codeRouteMap.set(normalized, []);
|
|
151828
151805
|
}
|
|
@@ -151845,7 +151822,7 @@ function findDrift(specPaths, codeRoutes) {
|
|
|
151845
151822
|
for (const [normalized, methods] of specPathMap) {
|
|
151846
151823
|
if (!codeRouteMap.has(normalized)) {
|
|
151847
151824
|
phantom.push({
|
|
151848
|
-
path: specPaths.find((sp) =>
|
|
151825
|
+
path: specPaths.find((sp) => normalizeApiPath(sp.path) === normalized).path,
|
|
151849
151826
|
methods
|
|
151850
151827
|
});
|
|
151851
151828
|
}
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
* All paths are normalized to POSIX-style (forward slashes, no trailing slash)
|
|
19
19
|
* before conflict detection. This ensures consistent behavior across platforms.
|
|
20
20
|
*/
|
|
21
|
+
import { normalizePath } from '../../utils/path';
|
|
22
|
+
export { normalizePath };
|
|
21
23
|
/**
|
|
22
24
|
* A scope file persisted by the `declare_scope` tool.
|
|
23
25
|
* Stored at `.swarm/scopes/scope-{taskId}.json`.
|
|
@@ -32,19 +34,6 @@ export interface ScopeFile {
|
|
|
32
34
|
* These are treated as global because other tasks may import from them.
|
|
33
35
|
*/
|
|
34
36
|
export declare const BARREL_FILE_PATTERNS: readonly RegExp[];
|
|
35
|
-
/**
|
|
36
|
-
* Normalize a file path to POSIX-style for consistent cross-platform comparison.
|
|
37
|
-
*
|
|
38
|
-
* - Converts backslashes to forward slashes
|
|
39
|
-
* - Removes trailing slashes
|
|
40
|
-
* - Collapses multiple consecutive slashes
|
|
41
|
-
* - Resolves `.` path segments (current directory references)
|
|
42
|
-
* - Does NOT resolve `..` segments or symlinks
|
|
43
|
-
*
|
|
44
|
-
* @param filePath - The path to normalize
|
|
45
|
-
* @returns POSIX-normalized path
|
|
46
|
-
*/
|
|
47
|
-
export declare function normalizePath(filePath: string): string;
|
|
48
37
|
/**
|
|
49
38
|
* Check if a path contains directory traversal components.
|
|
50
39
|
* Rejects paths with `..` segments that could escape the project root.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function normalizePath(p: string): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.99.
|
|
3
|
+
"version": "7.99.1",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|