opencode-swarm 7.87.0 → 7.87.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/{guardrail-explain-wb1cj312.js → guardrail-explain-scym5r5y.js} +2 -2
- package/dist/cli/{index-0m44n5qv.js → index-dsjyfd3g.js} +2 -2
- package/dist/cli/{index-wv2yj8ka.js → index-gwzpy671.js} +117 -13
- package/dist/cli/{index-f13d3b69.js → index-ts2j1wjr.js} +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/index.js +178 -68
- package/dist/memory/scoring.d.ts +18 -0
- package/dist/memory/sqlite-provider.d.ts +10 -0
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
4
|
+
} from "./index-ts2j1wjr.js";
|
|
5
|
+
import"./index-gwzpy671.js";
|
|
6
6
|
import"./index-5hvbw5xh.js";
|
|
7
7
|
import"./index-yhsmmv2z.js";
|
|
8
8
|
import"./index-s8bj492g.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
handleGuardrailExplain
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-ts2j1wjr.js";
|
|
5
5
|
import {
|
|
6
6
|
handleGuardrailLog
|
|
7
7
|
} from "./index-5vpe6vq9.js";
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
handleWriteRetroCommand,
|
|
77
77
|
normalizeSwarmCommandInput,
|
|
78
78
|
resolveCommand
|
|
79
|
-
} from "./index-
|
|
79
|
+
} from "./index-gwzpy671.js";
|
|
80
80
|
import"./index-5hvbw5xh.js";
|
|
81
81
|
import"./index-yhsmmv2z.js";
|
|
82
82
|
import"./index-s8bj492g.js";
|
|
@@ -894,7 +894,7 @@ var init_executor = __esm(() => {
|
|
|
894
894
|
// package.json
|
|
895
895
|
var package_default = {
|
|
896
896
|
name: "opencode-swarm",
|
|
897
|
-
version: "7.87.
|
|
897
|
+
version: "7.87.1",
|
|
898
898
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
899
899
|
main: "dist/index.js",
|
|
900
900
|
types: "dist/index.d.ts",
|
|
@@ -18161,7 +18161,26 @@ var SECRET_PATTERNS = [
|
|
|
18161
18161
|
},
|
|
18162
18162
|
{
|
|
18163
18163
|
type: "env_secret",
|
|
18164
|
-
pattern: /\b(?:[A-Z0-9]+_)
|
|
18164
|
+
pattern: /\b(?:[A-Z][A-Z0-9]+_)+(?:KEY|TOKEN|SECRET|PASSWORD)\b\s*=\s*["']?[^\s"'`]{8,}["']?/gi
|
|
18165
|
+
},
|
|
18166
|
+
{ type: "gitlab_token", pattern: /\bgl(?:pat|ptt)-[A-Za-z0-9_-]{15,}\b/g },
|
|
18167
|
+
{ type: "slack_token", pattern: /\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g },
|
|
18168
|
+
{
|
|
18169
|
+
type: "jwt_token",
|
|
18170
|
+
pattern: /\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g
|
|
18171
|
+
},
|
|
18172
|
+
{
|
|
18173
|
+
type: "aws_secret_access_key",
|
|
18174
|
+
pattern: /\b(?:aws_secret_access_key|AWS_SECRET_ACCESS_KEY)\s*[=:]\s*[A-Za-z0-9/+=]{40}\b/g
|
|
18175
|
+
},
|
|
18176
|
+
{
|
|
18177
|
+
type: "stripe_secret_key",
|
|
18178
|
+
pattern: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{24,}\b/g
|
|
18179
|
+
},
|
|
18180
|
+
{ type: "google_api_key", pattern: /\bAIza[0-9A-Za-z_-]{35}\b/g },
|
|
18181
|
+
{
|
|
18182
|
+
type: "openssh_private_key_block",
|
|
18183
|
+
pattern: /-----BEGIN[ ]OPENSSH[ ]PRIVATE[ ]KEY-----[\s\S]*?-----END[ ]OPENSSH[ ]PRIVATE[ ]KEY-----/g
|
|
18165
18184
|
}
|
|
18166
18185
|
];
|
|
18167
18186
|
function findSecrets(text) {
|
|
@@ -18732,7 +18751,7 @@ function normalizeMemoryAgentRole(agentRole) {
|
|
|
18732
18751
|
if (base === "critic" || base === "critic_sounding_board" || base === "critic_drift_verifier" || base === "critic_hallucination_verifier" || base === "critic_architecture_supervisor") {
|
|
18733
18752
|
return "security";
|
|
18734
18753
|
}
|
|
18735
|
-
if (base === "curator_init" || base === "curator_phase")
|
|
18754
|
+
if (base === "curator_init" || base === "curator_phase" || base === "curator_postmortem")
|
|
18736
18755
|
return "curator";
|
|
18737
18756
|
if (base === "docs")
|
|
18738
18757
|
return "sme";
|
|
@@ -18743,6 +18762,17 @@ function normalizeMemoryAgentRole(agentRole) {
|
|
|
18743
18762
|
}
|
|
18744
18763
|
|
|
18745
18764
|
// src/memory/scoring.ts
|
|
18765
|
+
var SCORING_WEIGHTS = {
|
|
18766
|
+
textOverlap: 0.38,
|
|
18767
|
+
tagOverlap: 0.16,
|
|
18768
|
+
fileOverlap: 0.12,
|
|
18769
|
+
symbolOverlap: 0.08,
|
|
18770
|
+
taskTermOverlap: 0.08,
|
|
18771
|
+
scopeSpecificityBoost: 0.12,
|
|
18772
|
+
kindProfileBoost: 0.06,
|
|
18773
|
+
roleBoost: 0.05,
|
|
18774
|
+
confidence: 0.08
|
|
18775
|
+
};
|
|
18746
18776
|
function tokenize(text) {
|
|
18747
18777
|
return new Set(text.toLowerCase().replace(/[^\w\s-]/g, " ").split(/\s+/).map((token) => token.trim()).filter(Boolean));
|
|
18748
18778
|
}
|
|
@@ -18848,7 +18878,7 @@ function scoreMemoryRecordDetailed(record, request, context) {
|
|
|
18848
18878
|
if (request.mode === "injection" && request.requireQuerySignal !== false && !hasQuerySignal) {
|
|
18849
18879
|
return { item: null, skipReason: "no_signal" };
|
|
18850
18880
|
}
|
|
18851
|
-
const score = textOverlap *
|
|
18881
|
+
const score = textOverlap * SCORING_WEIGHTS.textOverlap + tagOverlap * SCORING_WEIGHTS.tagOverlap + fileOverlap * SCORING_WEIGHTS.fileOverlap + symbolOverlap * SCORING_WEIGHTS.symbolOverlap + taskTermOverlap * SCORING_WEIGHTS.taskTermOverlap + scopeSpecificityBoost(record.scope) * SCORING_WEIGHTS.scopeSpecificityBoost + kindProfileBoost(record.kind, request) * SCORING_WEIGHTS.kindProfileBoost + roleBoost * SCORING_WEIGHTS.roleBoost + record.confidence * SCORING_WEIGHTS.confidence;
|
|
18852
18882
|
const reasonParts = [
|
|
18853
18883
|
textOverlap > 0 ? `text_overlap=${textOverlap.toFixed(2)}` : null,
|
|
18854
18884
|
tagOverlap > 0 ? `tag_overlap=${tagOverlap.toFixed(2)}` : null,
|
|
@@ -19548,7 +19578,6 @@ function loadDatabaseCtor2() {
|
|
|
19548
19578
|
_DatabaseCtor2 = req("bun:sqlite").Database;
|
|
19549
19579
|
return _DatabaseCtor2;
|
|
19550
19580
|
}
|
|
19551
|
-
var FTS_SCHEMA_MIGRATION_VERSION = 3;
|
|
19552
19581
|
var FTS_SCHEMA_MIGRATION_NAME = "create_memory_fts5_shadow_index";
|
|
19553
19582
|
var FTS_TABLE_NAME = "memory_items_fts";
|
|
19554
19583
|
var FTS_INDEX_COLUMNS = [
|
|
@@ -19637,6 +19666,15 @@ var MIGRATIONS2 = [
|
|
|
19637
19666
|
CREATE INDEX IF NOT EXISTS idx_memory_recall_usage_bundle
|
|
19638
19667
|
ON memory_recall_usage(bundle_id);
|
|
19639
19668
|
`
|
|
19669
|
+
},
|
|
19670
|
+
{
|
|
19671
|
+
version: 3,
|
|
19672
|
+
name: "create_memory_fts5_shadow_index",
|
|
19673
|
+
sql: `
|
|
19674
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS ${FTS_TABLE_NAME} USING fts5(
|
|
19675
|
+
${ftsCreateColumnsSql()}
|
|
19676
|
+
);
|
|
19677
|
+
`
|
|
19640
19678
|
}
|
|
19641
19679
|
];
|
|
19642
19680
|
|
|
@@ -19645,6 +19683,7 @@ class SQLiteMemoryProvider {
|
|
|
19645
19683
|
rootDirectory;
|
|
19646
19684
|
config;
|
|
19647
19685
|
initialized = false;
|
|
19686
|
+
initPromise = null;
|
|
19648
19687
|
db = null;
|
|
19649
19688
|
ftsAvailable = false;
|
|
19650
19689
|
memories = new Map;
|
|
@@ -19688,6 +19727,15 @@ class SQLiteMemoryProvider {
|
|
|
19688
19727
|
async initialize() {
|
|
19689
19728
|
if (this.initialized)
|
|
19690
19729
|
return;
|
|
19730
|
+
if (!this.initPromise) {
|
|
19731
|
+
this.initPromise = this.doInitialize().catch((err) => {
|
|
19732
|
+
this.initPromise = null;
|
|
19733
|
+
throw err;
|
|
19734
|
+
});
|
|
19735
|
+
}
|
|
19736
|
+
return this.initPromise;
|
|
19737
|
+
}
|
|
19738
|
+
async doInitialize() {
|
|
19691
19739
|
const dbPath = this.databasePath();
|
|
19692
19740
|
mkdirSync15(path40.dirname(dbPath), { recursive: true });
|
|
19693
19741
|
const Db = loadDatabaseCtor2();
|
|
@@ -19883,6 +19931,7 @@ class SQLiteMemoryProvider {
|
|
|
19883
19931
|
this.db = null;
|
|
19884
19932
|
this.ftsAvailable = false;
|
|
19885
19933
|
this.initialized = false;
|
|
19934
|
+
this.initPromise = null;
|
|
19886
19935
|
this.lastAutomaticJsonlMigration = null;
|
|
19887
19936
|
}
|
|
19888
19937
|
async importJsonl() {
|
|
@@ -20019,8 +20068,6 @@ class SQLiteMemoryProvider {
|
|
|
20019
20068
|
try {
|
|
20020
20069
|
if (!this.hasMigration(FTS_SCHEMA_MIGRATION_NAME)) {
|
|
20021
20070
|
this.recreateFtsIndex();
|
|
20022
|
-
this.markMigration(FTS_SCHEMA_MIGRATION_VERSION, FTS_SCHEMA_MIGRATION_NAME);
|
|
20023
|
-
this.insertEvent("migration", String(FTS_SCHEMA_MIGRATION_VERSION), FTS_SCHEMA_MIGRATION_NAME);
|
|
20024
20071
|
} else {
|
|
20025
20072
|
db.run(`CREATE VIRTUAL TABLE IF NOT EXISTS ${FTS_TABLE_NAME} USING fts5(
|
|
20026
20073
|
${ftsCreateColumnsSql()}
|
|
@@ -20353,12 +20400,60 @@ class SQLiteMemoryProvider {
|
|
|
20353
20400
|
}
|
|
20354
20401
|
requireDb() {
|
|
20355
20402
|
if (!this.db)
|
|
20356
|
-
throw new
|
|
20403
|
+
throw new MemoryValidationError("SQLite memory provider is not initialized", "provider_not_initialized");
|
|
20357
20404
|
return this.db;
|
|
20358
20405
|
}
|
|
20359
20406
|
}
|
|
20360
20407
|
function splitSql(sql) {
|
|
20361
|
-
|
|
20408
|
+
const statements = [];
|
|
20409
|
+
let current = "";
|
|
20410
|
+
let inSingleQuote = false;
|
|
20411
|
+
let inLineComment = false;
|
|
20412
|
+
for (let i = 0;i < sql.length; i++) {
|
|
20413
|
+
const char = sql[i];
|
|
20414
|
+
const next = sql[i + 1];
|
|
20415
|
+
if (inLineComment) {
|
|
20416
|
+
if (char === `
|
|
20417
|
+
`) {
|
|
20418
|
+
inLineComment = false;
|
|
20419
|
+
}
|
|
20420
|
+
continue;
|
|
20421
|
+
}
|
|
20422
|
+
if (inSingleQuote) {
|
|
20423
|
+
if (char === "'" && next === "'") {
|
|
20424
|
+
current += "''";
|
|
20425
|
+
i++;
|
|
20426
|
+
continue;
|
|
20427
|
+
}
|
|
20428
|
+
current += char;
|
|
20429
|
+
if (char === "'") {
|
|
20430
|
+
inSingleQuote = false;
|
|
20431
|
+
}
|
|
20432
|
+
continue;
|
|
20433
|
+
}
|
|
20434
|
+
if (char === "-" && next === "-") {
|
|
20435
|
+
inLineComment = true;
|
|
20436
|
+
i++;
|
|
20437
|
+
continue;
|
|
20438
|
+
}
|
|
20439
|
+
if (char === "'") {
|
|
20440
|
+
inSingleQuote = true;
|
|
20441
|
+
current += char;
|
|
20442
|
+
continue;
|
|
20443
|
+
}
|
|
20444
|
+
if (char === ";") {
|
|
20445
|
+
const trimmed2 = current.trim();
|
|
20446
|
+
if (trimmed2)
|
|
20447
|
+
statements.push(trimmed2);
|
|
20448
|
+
current = "";
|
|
20449
|
+
continue;
|
|
20450
|
+
}
|
|
20451
|
+
current += char;
|
|
20452
|
+
}
|
|
20453
|
+
const trimmed = current.trim();
|
|
20454
|
+
if (trimmed)
|
|
20455
|
+
statements.push(trimmed);
|
|
20456
|
+
return statements;
|
|
20362
20457
|
}
|
|
20363
20458
|
var FTS_STOP_WORDS = new Set([
|
|
20364
20459
|
"a",
|
|
@@ -21087,7 +21182,16 @@ function parseEvaluateArgs(directory, args) {
|
|
|
21087
21182
|
error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
|
|
21088
21183
|
};
|
|
21089
21184
|
}
|
|
21090
|
-
|
|
21185
|
+
const resolvedFixtures = path42.resolve(directory, next);
|
|
21186
|
+
const canonical = path42.normalize(resolvedFixtures) + path42.sep;
|
|
21187
|
+
const allowedRootA = path42.normalize(directory) + path42.sep;
|
|
21188
|
+
const allowedRootB = path42.normalize(path42.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path42.sep;
|
|
21189
|
+
if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
|
|
21190
|
+
return {
|
|
21191
|
+
error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
|
|
21192
|
+
};
|
|
21193
|
+
}
|
|
21194
|
+
fixtureDirectory = resolvedFixtures;
|
|
21091
21195
|
i++;
|
|
21092
21196
|
continue;
|
|
21093
21197
|
}
|
|
@@ -29151,7 +29255,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
29151
29255
|
async function handleHelpCommand(ctx) {
|
|
29152
29256
|
const targetCommand = ctx.args.join(" ");
|
|
29153
29257
|
if (!targetCommand) {
|
|
29154
|
-
const { buildHelpText } = await import("./index-
|
|
29258
|
+
const { buildHelpText } = await import("./index-dsjyfd3g.js");
|
|
29155
29259
|
return buildHelpText();
|
|
29156
29260
|
}
|
|
29157
29261
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -29160,7 +29264,7 @@ async function handleHelpCommand(ctx) {
|
|
|
29160
29264
|
return _internals44.buildDetailedHelp(resolved.key, resolved.entry);
|
|
29161
29265
|
}
|
|
29162
29266
|
const similar = _internals44.findSimilarCommands(targetCommand);
|
|
29163
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
29267
|
+
const { buildHelpText: fullHelp } = await import("./index-dsjyfd3g.js");
|
|
29164
29268
|
if (similar.length > 0) {
|
|
29165
29269
|
return `Command '/swarm ${targetCommand}' not found.
|
|
29166
29270
|
|
|
@@ -29293,7 +29397,7 @@ var COMMAND_REGISTRY = {
|
|
|
29293
29397
|
},
|
|
29294
29398
|
"guardrail explain": {
|
|
29295
29399
|
handler: async (ctx) => {
|
|
29296
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
29400
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-scym5r5y.js");
|
|
29297
29401
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
29298
29402
|
},
|
|
29299
29403
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
package/dist/cli/index.js
CHANGED
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.87.
|
|
72
|
+
version: "7.87.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",
|
|
@@ -82494,7 +82494,26 @@ var init_redaction = __esm(() => {
|
|
|
82494
82494
|
},
|
|
82495
82495
|
{
|
|
82496
82496
|
type: "env_secret",
|
|
82497
|
-
pattern: /\b(?:[A-Z0-9]+_)
|
|
82497
|
+
pattern: /\b(?:[A-Z][A-Z0-9]+_)+(?:KEY|TOKEN|SECRET|PASSWORD)\b\s*=\s*["']?[^\s"'`]{8,}["']?/gi
|
|
82498
|
+
},
|
|
82499
|
+
{ type: "gitlab_token", pattern: /\bgl(?:pat|ptt)-[A-Za-z0-9_-]{15,}\b/g },
|
|
82500
|
+
{ type: "slack_token", pattern: /\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g },
|
|
82501
|
+
{
|
|
82502
|
+
type: "jwt_token",
|
|
82503
|
+
pattern: /\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g
|
|
82504
|
+
},
|
|
82505
|
+
{
|
|
82506
|
+
type: "aws_secret_access_key",
|
|
82507
|
+
pattern: /\b(?:aws_secret_access_key|AWS_SECRET_ACCESS_KEY)\s*[=:]\s*[A-Za-z0-9/+=]{40}\b/g
|
|
82508
|
+
},
|
|
82509
|
+
{
|
|
82510
|
+
type: "stripe_secret_key",
|
|
82511
|
+
pattern: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{24,}\b/g
|
|
82512
|
+
},
|
|
82513
|
+
{ type: "google_api_key", pattern: /\bAIza[0-9A-Za-z_-]{35}\b/g },
|
|
82514
|
+
{
|
|
82515
|
+
type: "openssh_private_key_block",
|
|
82516
|
+
pattern: /-----BEGIN[ ]OPENSSH[ ]PRIVATE[ ]KEY-----[\s\S]*?-----END[ ]OPENSSH[ ]PRIVATE[ ]KEY-----/g
|
|
82498
82517
|
}
|
|
82499
82518
|
];
|
|
82500
82519
|
});
|
|
@@ -83012,7 +83031,7 @@ function normalizeMemoryAgentRole(agentRole) {
|
|
|
83012
83031
|
if (base === "critic" || base === "critic_sounding_board" || base === "critic_drift_verifier" || base === "critic_hallucination_verifier" || base === "critic_architecture_supervisor") {
|
|
83013
83032
|
return "security";
|
|
83014
83033
|
}
|
|
83015
|
-
if (base === "curator_init" || base === "curator_phase")
|
|
83034
|
+
if (base === "curator_init" || base === "curator_phase" || base === "curator_postmortem")
|
|
83016
83035
|
return "curator";
|
|
83017
83036
|
if (base === "docs")
|
|
83018
83037
|
return "sme";
|
|
@@ -83202,7 +83221,7 @@ function scoreMemoryRecordDetailed(record3, request, context) {
|
|
|
83202
83221
|
if (request.mode === "injection" && request.requireQuerySignal !== false && !hasQuerySignal) {
|
|
83203
83222
|
return { item: null, skipReason: "no_signal" };
|
|
83204
83223
|
}
|
|
83205
|
-
const score = textOverlap *
|
|
83224
|
+
const score = textOverlap * SCORING_WEIGHTS.textOverlap + tagOverlap * SCORING_WEIGHTS.tagOverlap + fileOverlap * SCORING_WEIGHTS.fileOverlap + symbolOverlap * SCORING_WEIGHTS.symbolOverlap + taskTermOverlap * SCORING_WEIGHTS.taskTermOverlap + scopeSpecificityBoost(record3.scope) * SCORING_WEIGHTS.scopeSpecificityBoost + kindProfileBoost(record3.kind, request) * SCORING_WEIGHTS.kindProfileBoost + roleBoost * SCORING_WEIGHTS.roleBoost + record3.confidence * SCORING_WEIGHTS.confidence;
|
|
83206
83225
|
const reasonParts = [
|
|
83207
83226
|
textOverlap > 0 ? `text_overlap=${textOverlap.toFixed(2)}` : null,
|
|
83208
83227
|
tagOverlap > 0 ? `tag_overlap=${tagOverlap.toFixed(2)}` : null,
|
|
@@ -83278,9 +83297,21 @@ function unionTokens(...sets) {
|
|
|
83278
83297
|
}
|
|
83279
83298
|
return union3;
|
|
83280
83299
|
}
|
|
83300
|
+
var SCORING_WEIGHTS;
|
|
83281
83301
|
var init_scoring = __esm(() => {
|
|
83282
83302
|
init_role_profiles();
|
|
83283
83303
|
init_schema2();
|
|
83304
|
+
SCORING_WEIGHTS = {
|
|
83305
|
+
textOverlap: 0.38,
|
|
83306
|
+
tagOverlap: 0.16,
|
|
83307
|
+
fileOverlap: 0.12,
|
|
83308
|
+
symbolOverlap: 0.08,
|
|
83309
|
+
taskTermOverlap: 0.08,
|
|
83310
|
+
scopeSpecificityBoost: 0.12,
|
|
83311
|
+
kindProfileBoost: 0.06,
|
|
83312
|
+
roleBoost: 0.05,
|
|
83313
|
+
confidence: 0.08
|
|
83314
|
+
};
|
|
83284
83315
|
});
|
|
83285
83316
|
|
|
83286
83317
|
// src/memory/local-jsonl-provider.ts
|
|
@@ -84013,6 +84044,7 @@ class SQLiteMemoryProvider {
|
|
|
84013
84044
|
rootDirectory;
|
|
84014
84045
|
config;
|
|
84015
84046
|
initialized = false;
|
|
84047
|
+
initPromise = null;
|
|
84016
84048
|
db = null;
|
|
84017
84049
|
ftsAvailable = false;
|
|
84018
84050
|
memories = new Map;
|
|
@@ -84056,6 +84088,15 @@ class SQLiteMemoryProvider {
|
|
|
84056
84088
|
async initialize() {
|
|
84057
84089
|
if (this.initialized)
|
|
84058
84090
|
return;
|
|
84091
|
+
if (!this.initPromise) {
|
|
84092
|
+
this.initPromise = this.doInitialize().catch((err2) => {
|
|
84093
|
+
this.initPromise = null;
|
|
84094
|
+
throw err2;
|
|
84095
|
+
});
|
|
84096
|
+
}
|
|
84097
|
+
return this.initPromise;
|
|
84098
|
+
}
|
|
84099
|
+
async doInitialize() {
|
|
84059
84100
|
const dbPath = this.databasePath();
|
|
84060
84101
|
mkdirSync27(path76.dirname(dbPath), { recursive: true });
|
|
84061
84102
|
const Db = loadDatabaseCtor2();
|
|
@@ -84251,6 +84292,7 @@ class SQLiteMemoryProvider {
|
|
|
84251
84292
|
this.db = null;
|
|
84252
84293
|
this.ftsAvailable = false;
|
|
84253
84294
|
this.initialized = false;
|
|
84295
|
+
this.initPromise = null;
|
|
84254
84296
|
this.lastAutomaticJsonlMigration = null;
|
|
84255
84297
|
}
|
|
84256
84298
|
async importJsonl() {
|
|
@@ -84387,8 +84429,6 @@ class SQLiteMemoryProvider {
|
|
|
84387
84429
|
try {
|
|
84388
84430
|
if (!this.hasMigration(FTS_SCHEMA_MIGRATION_NAME)) {
|
|
84389
84431
|
this.recreateFtsIndex();
|
|
84390
|
-
this.markMigration(FTS_SCHEMA_MIGRATION_VERSION, FTS_SCHEMA_MIGRATION_NAME);
|
|
84391
|
-
this.insertEvent("migration", String(FTS_SCHEMA_MIGRATION_VERSION), FTS_SCHEMA_MIGRATION_NAME);
|
|
84392
84432
|
} else {
|
|
84393
84433
|
db.run(`CREATE VIRTUAL TABLE IF NOT EXISTS ${FTS_TABLE_NAME} USING fts5(
|
|
84394
84434
|
${ftsCreateColumnsSql()}
|
|
@@ -84721,12 +84761,60 @@ class SQLiteMemoryProvider {
|
|
|
84721
84761
|
}
|
|
84722
84762
|
requireDb() {
|
|
84723
84763
|
if (!this.db)
|
|
84724
|
-
throw new
|
|
84764
|
+
throw new MemoryValidationError("SQLite memory provider is not initialized", "provider_not_initialized");
|
|
84725
84765
|
return this.db;
|
|
84726
84766
|
}
|
|
84727
84767
|
}
|
|
84728
84768
|
function splitSql(sql) {
|
|
84729
|
-
|
|
84769
|
+
const statements = [];
|
|
84770
|
+
let current = "";
|
|
84771
|
+
let inSingleQuote = false;
|
|
84772
|
+
let inLineComment = false;
|
|
84773
|
+
for (let i2 = 0;i2 < sql.length; i2++) {
|
|
84774
|
+
const char = sql[i2];
|
|
84775
|
+
const next = sql[i2 + 1];
|
|
84776
|
+
if (inLineComment) {
|
|
84777
|
+
if (char === `
|
|
84778
|
+
`) {
|
|
84779
|
+
inLineComment = false;
|
|
84780
|
+
}
|
|
84781
|
+
continue;
|
|
84782
|
+
}
|
|
84783
|
+
if (inSingleQuote) {
|
|
84784
|
+
if (char === "'" && next === "'") {
|
|
84785
|
+
current += "''";
|
|
84786
|
+
i2++;
|
|
84787
|
+
continue;
|
|
84788
|
+
}
|
|
84789
|
+
current += char;
|
|
84790
|
+
if (char === "'") {
|
|
84791
|
+
inSingleQuote = false;
|
|
84792
|
+
}
|
|
84793
|
+
continue;
|
|
84794
|
+
}
|
|
84795
|
+
if (char === "-" && next === "-") {
|
|
84796
|
+
inLineComment = true;
|
|
84797
|
+
i2++;
|
|
84798
|
+
continue;
|
|
84799
|
+
}
|
|
84800
|
+
if (char === "'") {
|
|
84801
|
+
inSingleQuote = true;
|
|
84802
|
+
current += char;
|
|
84803
|
+
continue;
|
|
84804
|
+
}
|
|
84805
|
+
if (char === ";") {
|
|
84806
|
+
const trimmed2 = current.trim();
|
|
84807
|
+
if (trimmed2)
|
|
84808
|
+
statements.push(trimmed2);
|
|
84809
|
+
current = "";
|
|
84810
|
+
continue;
|
|
84811
|
+
}
|
|
84812
|
+
current += char;
|
|
84813
|
+
}
|
|
84814
|
+
const trimmed = current.trim();
|
|
84815
|
+
if (trimmed)
|
|
84816
|
+
statements.push(trimmed);
|
|
84817
|
+
return statements;
|
|
84730
84818
|
}
|
|
84731
84819
|
function buildFtsQuery(request) {
|
|
84732
84820
|
const text = request.mode === "injection" && request.task ? `${request.task}
|
|
@@ -84790,7 +84878,7 @@ function rerankWithFts(items, ftsOrder) {
|
|
|
84790
84878
|
};
|
|
84791
84879
|
}).sort((a, b) => b.score - a.score || a.record.id.localeCompare(b.record.id));
|
|
84792
84880
|
}
|
|
84793
|
-
var _DatabaseCtor2 = null,
|
|
84881
|
+
var _DatabaseCtor2 = null, FTS_SCHEMA_MIGRATION_NAME = "create_memory_fts5_shadow_index", FTS_TABLE_NAME = "memory_items_fts", FTS_INDEX_COLUMNS, FTS_INSERT_COLUMNS, MIGRATIONS2, FTS_STOP_WORDS;
|
|
84794
84882
|
var init_sqlite_provider = __esm(() => {
|
|
84795
84883
|
init_utils2();
|
|
84796
84884
|
init_config3();
|
|
@@ -84886,6 +84974,15 @@ var init_sqlite_provider = __esm(() => {
|
|
|
84886
84974
|
CREATE INDEX IF NOT EXISTS idx_memory_recall_usage_bundle
|
|
84887
84975
|
ON memory_recall_usage(bundle_id);
|
|
84888
84976
|
`
|
|
84977
|
+
},
|
|
84978
|
+
{
|
|
84979
|
+
version: 3,
|
|
84980
|
+
name: "create_memory_fts5_shadow_index",
|
|
84981
|
+
sql: `
|
|
84982
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS ${FTS_TABLE_NAME} USING fts5(
|
|
84983
|
+
${ftsCreateColumnsSql()}
|
|
84984
|
+
);
|
|
84985
|
+
`
|
|
84889
84986
|
}
|
|
84890
84987
|
];
|
|
84891
84988
|
FTS_STOP_WORDS = new Set([
|
|
@@ -86036,65 +86133,69 @@ async function recallForAgent(input) {
|
|
|
86036
86133
|
agentId: input.agentId,
|
|
86037
86134
|
runId: input.sessionID
|
|
86038
86135
|
}, { config: input.config });
|
|
86039
|
-
|
|
86040
|
-
|
|
86041
|
-
|
|
86042
|
-
|
|
86043
|
-
|
|
86044
|
-
|
|
86045
|
-
|
|
86046
|
-
|
|
86047
|
-
|
|
86048
|
-
|
|
86049
|
-
|
|
86050
|
-
|
|
86051
|
-
|
|
86052
|
-
|
|
86053
|
-
|
|
86054
|
-
|
|
86055
|
-
|
|
86056
|
-
|
|
86057
|
-
|
|
86058
|
-
|
|
86059
|
-
|
|
86060
|
-
|
|
86061
|
-
|
|
86062
|
-
|
|
86063
|
-
|
|
86064
|
-
|
|
86065
|
-
|
|
86136
|
+
try {
|
|
86137
|
+
const resolvedConfig = resolveMemoryConfig(input.config);
|
|
86138
|
+
if (!gateway.isEnabled()) {
|
|
86139
|
+
await logInjectionSkipped(input, "disabled");
|
|
86140
|
+
return null;
|
|
86141
|
+
}
|
|
86142
|
+
if (!resolvedConfig.recall.injection.enabled) {
|
|
86143
|
+
await logInjectionSkipped(input, "disabled");
|
|
86144
|
+
return null;
|
|
86145
|
+
}
|
|
86146
|
+
const scopes = gateway.deriveAllowedScopes();
|
|
86147
|
+
const planInput = {
|
|
86148
|
+
userGoal: compactText(input.userGoal),
|
|
86149
|
+
runId: input.sessionID ?? "unknown",
|
|
86150
|
+
agentRole: input.agentRole,
|
|
86151
|
+
agentId: input.agentId,
|
|
86152
|
+
agentTask: compactText(input.agentTask),
|
|
86153
|
+
touchedFiles: extractTouchedFiles(input.agentTask)
|
|
86154
|
+
};
|
|
86155
|
+
const plan = buildMemoryRecallPlan(planInput, { scopes });
|
|
86156
|
+
plan.maxItems = resolvedConfig.recall.injection.maxItems;
|
|
86157
|
+
plan.tokenBudget = resolvedConfig.recall.injection.tokenBudget;
|
|
86158
|
+
await input.appendRunLog(input.directory, input.sessionID, {
|
|
86159
|
+
event: "recall_requested",
|
|
86160
|
+
runId: input.sessionID ?? "unknown",
|
|
86161
|
+
agentRole: input.agentRole,
|
|
86162
|
+
agentId: input.agentId,
|
|
86163
|
+
metadata: {
|
|
86164
|
+
kinds: plan.kinds,
|
|
86165
|
+
maxItems: plan.maxItems,
|
|
86166
|
+
tokenBudget: plan.tokenBudget,
|
|
86167
|
+
scopeTypes: plan.scopes.map((scope) => scope.type)
|
|
86168
|
+
}
|
|
86169
|
+
});
|
|
86170
|
+
const recallInput = {
|
|
86171
|
+
query: plan.query,
|
|
86172
|
+
task: planInput.agentTask,
|
|
86173
|
+
mode: "injection",
|
|
86174
|
+
scopes: plan.scopes,
|
|
86066
86175
|
kinds: plan.kinds,
|
|
86067
86176
|
maxItems: plan.maxItems,
|
|
86068
86177
|
tokenBudget: plan.tokenBudget,
|
|
86069
|
-
|
|
86178
|
+
minScore: resolvedConfig.recall.injection.minScore,
|
|
86179
|
+
requireQuerySignal: resolvedConfig.recall.injection.requireQuerySignal
|
|
86180
|
+
};
|
|
86181
|
+
const bundle = await gateway.recall(recallInput);
|
|
86182
|
+
await input.appendRunLog(input.directory, input.sessionID, {
|
|
86183
|
+
event: "recall_returned",
|
|
86184
|
+
runId: input.sessionID ?? "unknown",
|
|
86185
|
+
agentRole: input.agentRole,
|
|
86186
|
+
agentId: input.agentId,
|
|
86187
|
+
bundleId: bundle.id,
|
|
86188
|
+
memoryIds: bundle.items.map((item) => item.record.id),
|
|
86189
|
+
scores: bundle.items.map((item) => item.score),
|
|
86190
|
+
tokenEstimate: bundle.tokenEstimate
|
|
86191
|
+
});
|
|
86192
|
+
if (bundle.items.length === 0) {
|
|
86193
|
+
await logInjectionSkipped(input, bundle.diagnostics?.injectionSkipReason ?? "no_results", bundle);
|
|
86070
86194
|
}
|
|
86071
|
-
|
|
86072
|
-
|
|
86073
|
-
|
|
86074
|
-
task: planInput.agentTask,
|
|
86075
|
-
mode: "injection",
|
|
86076
|
-
scopes: plan.scopes,
|
|
86077
|
-
kinds: plan.kinds,
|
|
86078
|
-
maxItems: plan.maxItems,
|
|
86079
|
-
tokenBudget: plan.tokenBudget,
|
|
86080
|
-
minScore: resolvedConfig.recall.injection.minScore,
|
|
86081
|
-
requireQuerySignal: resolvedConfig.recall.injection.requireQuerySignal
|
|
86082
|
-
};
|
|
86083
|
-
const bundle = await gateway.recall(recallInput);
|
|
86084
|
-
await input.appendRunLog(input.directory, input.sessionID, {
|
|
86085
|
-
event: "recall_returned",
|
|
86086
|
-
runId: input.sessionID ?? "unknown",
|
|
86087
|
-
agentRole: input.agentRole,
|
|
86088
|
-
agentId: input.agentId,
|
|
86089
|
-
bundleId: bundle.id,
|
|
86090
|
-
memoryIds: bundle.items.map((item) => item.record.id),
|
|
86091
|
-
scores: bundle.items.map((item) => item.score),
|
|
86092
|
-
tokenEstimate: bundle.tokenEstimate
|
|
86093
|
-
});
|
|
86094
|
-
if (bundle.items.length === 0) {
|
|
86095
|
-
await logInjectionSkipped(input, bundle.diagnostics?.injectionSkipReason ?? "no_results", bundle);
|
|
86195
|
+
return { bundle, scopes };
|
|
86196
|
+
} finally {
|
|
86197
|
+
await gateway.dispose?.();
|
|
86096
86198
|
}
|
|
86097
|
-
return { bundle, scopes };
|
|
86098
86199
|
}
|
|
86099
86200
|
async function logInjectionSkipped(input, reason, bundle) {
|
|
86100
86201
|
await input.appendRunLog(input.directory, input.sessionID, {
|
|
@@ -86136,7 +86237,7 @@ function parseTaskToolInput(input) {
|
|
|
86136
86237
|
};
|
|
86137
86238
|
}
|
|
86138
86239
|
function isCuratorAgent(agentRole) {
|
|
86139
|
-
return agentRole === "curator" || agentRole === "curator_init" || agentRole === "curator_phase";
|
|
86240
|
+
return agentRole === "curator" || agentRole === "curator_init" || agentRole === "curator_phase" || agentRole === "curator_postmortem";
|
|
86140
86241
|
}
|
|
86141
86242
|
function messagesContainRecall(messages) {
|
|
86142
86243
|
return messages.some((message) => message?.parts?.some((part) => typeof part?.text === "string" && (part.text.includes(MEMORY_SENTINEL) || part.text.includes("Retrieved Swarm Memory"))));
|
|
@@ -86509,7 +86610,16 @@ function parseEvaluateArgs(directory, args2) {
|
|
|
86509
86610
|
error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
|
|
86510
86611
|
};
|
|
86511
86612
|
}
|
|
86512
|
-
|
|
86613
|
+
const resolvedFixtures = path80.resolve(directory, next);
|
|
86614
|
+
const canonical = path80.normalize(resolvedFixtures) + path80.sep;
|
|
86615
|
+
const allowedRootA = path80.normalize(directory) + path80.sep;
|
|
86616
|
+
const allowedRootB = path80.normalize(path80.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path80.sep;
|
|
86617
|
+
if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
|
|
86618
|
+
return {
|
|
86619
|
+
error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
|
|
86620
|
+
};
|
|
86621
|
+
}
|
|
86622
|
+
fixtureDirectory = resolvedFixtures;
|
|
86513
86623
|
i2++;
|
|
86514
86624
|
continue;
|
|
86515
86625
|
}
|
|
@@ -103626,9 +103736,9 @@ function validateFilename(filename) {
|
|
|
103626
103736
|
throw new Error("Invalid filename: contains null byte");
|
|
103627
103737
|
}
|
|
103628
103738
|
const pathSeparators = ["/", "\\", ".."];
|
|
103629
|
-
for (const
|
|
103630
|
-
if (filename.includes(
|
|
103631
|
-
throw new Error(`Invalid filename: contains path separator '${
|
|
103739
|
+
for (const sep14 of pathSeparators) {
|
|
103740
|
+
if (filename.includes(sep14)) {
|
|
103741
|
+
throw new Error(`Invalid filename: contains path separator '${sep14}'`);
|
|
103632
103742
|
}
|
|
103633
103743
|
}
|
|
103634
103744
|
if (filename.startsWith("/") || filename.startsWith("\\") || /^[a-zA-Z]:/.test(filename)) {
|
package/dist/memory/scoring.d.ts
CHANGED
|
@@ -7,6 +7,24 @@ export interface RecallScoringDiagnostics {
|
|
|
7
7
|
noSignalCount: number;
|
|
8
8
|
belowThresholdCount: number;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Recall scoring weight coefficients. Sum is 1.13 (scores are an unnormalised
|
|
12
|
+
* weighted sum; may exceed 1.0). minScore thresholds in DEFAULT_MEMORY_CONFIG
|
|
13
|
+
* are calibrated against these weights.
|
|
14
|
+
*
|
|
15
|
+
* Pinned by tests/unit/memory/scoring.test.ts to detect drift.
|
|
16
|
+
*/
|
|
17
|
+
export declare const SCORING_WEIGHTS: {
|
|
18
|
+
readonly textOverlap: 0.38;
|
|
19
|
+
readonly tagOverlap: 0.16;
|
|
20
|
+
readonly fileOverlap: 0.12;
|
|
21
|
+
readonly symbolOverlap: 0.08;
|
|
22
|
+
readonly taskTermOverlap: 0.08;
|
|
23
|
+
readonly scopeSpecificityBoost: 0.12;
|
|
24
|
+
readonly kindProfileBoost: 0.06;
|
|
25
|
+
readonly roleBoost: 0.05;
|
|
26
|
+
readonly confidence: 0.08;
|
|
27
|
+
};
|
|
10
28
|
export declare function sameScope(a: MemoryScopeRef, b: MemoryScopeRef): boolean;
|
|
11
29
|
export declare function scopeAllowed(recordScope: MemoryScopeRef, allowedScopes: MemoryScopeRef[]): boolean;
|
|
12
30
|
export declare function scoreMemoryRecord(record: MemoryRecord, request: RecallRequest): RecallResultItem | null;
|
|
@@ -3,6 +3,12 @@ import { type JsonlMigrationReport } from './jsonl-migration';
|
|
|
3
3
|
import type { MemoryCompactOptions, MemoryCompactResult, MemoryProposalStore, MemoryProvider, MemoryRecallUsageEvent, MemoryRecallUsageFilter } from './provider';
|
|
4
4
|
import type { RecallScoringDiagnostics } from './scoring';
|
|
5
5
|
import type { AppliedMemoryChange, MemoryListFilter, MemoryProposal, MemoryRecord, RecallRequest, RecallResultItem, ResolvedCuratorMemoryDecision } from './types';
|
|
6
|
+
interface Migration {
|
|
7
|
+
version: number;
|
|
8
|
+
name: string;
|
|
9
|
+
sql: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const MIGRATIONS: Migration[];
|
|
6
12
|
export interface SQLiteJsonlImportResult {
|
|
7
13
|
importedMemories: number;
|
|
8
14
|
importedProposals: number;
|
|
@@ -14,6 +20,7 @@ export declare class SQLiteMemoryProvider implements MemoryProvider, MemoryPropo
|
|
|
14
20
|
private readonly rootDirectory;
|
|
15
21
|
private readonly config;
|
|
16
22
|
private initialized;
|
|
23
|
+
private initPromise;
|
|
17
24
|
private db;
|
|
18
25
|
private ftsAvailable;
|
|
19
26
|
private memories;
|
|
@@ -22,6 +29,7 @@ export declare class SQLiteMemoryProvider implements MemoryProvider, MemoryPropo
|
|
|
22
29
|
constructor(rootDirectory: string, config?: Partial<MemoryConfig>);
|
|
23
30
|
private databasePath;
|
|
24
31
|
initialize(): Promise<void>;
|
|
32
|
+
private doInitialize;
|
|
25
33
|
upsert(record: MemoryRecord): Promise<MemoryRecord>;
|
|
26
34
|
get(id: string): Promise<MemoryRecord | null>;
|
|
27
35
|
delete(id: string, reason?: string): Promise<void>;
|
|
@@ -75,9 +83,11 @@ export declare class SQLiteMemoryProvider implements MemoryProvider, MemoryPropo
|
|
|
75
83
|
private insertEvent;
|
|
76
84
|
private requireDb;
|
|
77
85
|
}
|
|
86
|
+
declare function splitSql(sql: string): string[];
|
|
78
87
|
declare function buildFtsQuery(request: RecallRequest): string | null;
|
|
79
88
|
declare function extractFtsTerms(text: string): Set<string>;
|
|
80
89
|
export declare const _test_exports: {
|
|
90
|
+
splitSql: typeof splitSql;
|
|
81
91
|
buildFtsQuery: typeof buildFtsQuery;
|
|
82
92
|
extractFtsTerms: typeof extractFtsTerms;
|
|
83
93
|
FTS_SCHEMA_MIGRATION_NAME: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.87.
|
|
3
|
+
"version": "7.87.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",
|