opencode-swarm 7.55.0 → 7.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +133 -16
- package/dist/index.js +102 -29
- package/dist/services/skill-generator.d.ts +2 -1
- package/dist/services/skill-improver.d.ts +6 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "opencode-swarm",
|
|
55
|
-
version: "7.
|
|
55
|
+
version: "7.56.0",
|
|
56
56
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
57
57
|
main: "dist/index.js",
|
|
58
58
|
types: "dist/index.d.ts",
|
|
@@ -36811,7 +36811,7 @@ function clusterEntries(entries) {
|
|
|
36811
36811
|
function uniqueStrings(arr) {
|
|
36812
36812
|
return [...new Set(arr.filter((s) => typeof s === "string" && s.length > 0))];
|
|
36813
36813
|
}
|
|
36814
|
-
function renderSkillMarkdown(cluster, mode = "active") {
|
|
36814
|
+
function renderSkillMarkdown(cluster, mode = "active", generatedAt = new Date().toISOString()) {
|
|
36815
36815
|
const description = cluster.title.length > 200 ? `${cluster.title.slice(0, 197)}\u2026` : cluster.title;
|
|
36816
36816
|
const ids = cluster.entries.map((e) => ` - ${e.id}`).join(`
|
|
36817
36817
|
`);
|
|
@@ -36821,6 +36821,9 @@ function renderSkillMarkdown(cluster, mode = "active") {
|
|
|
36821
36821
|
lines.push(`description: ${escapeYaml(description)}`);
|
|
36822
36822
|
lines.push("generated_from_knowledge:");
|
|
36823
36823
|
lines.push(ids);
|
|
36824
|
+
lines.push("source_knowledge_ids:");
|
|
36825
|
+
lines.push(ids);
|
|
36826
|
+
lines.push(`generated_at: ${generatedAt}`);
|
|
36824
36827
|
lines.push(`confidence: ${cluster.avgConfidence.toFixed(2)}`);
|
|
36825
36828
|
lines.push(`status: ${mode === "active" ? "active" : "draft"}`);
|
|
36826
36829
|
lines.push("---");
|
|
@@ -37009,6 +37012,62 @@ async function stampSourceEntries(directory, slug, ids) {
|
|
|
37009
37012
|
if (touchedHive)
|
|
37010
37013
|
await rewriteKnowledge(hivePath, hive);
|
|
37011
37014
|
}
|
|
37015
|
+
function parseDraftFrontmatter(content) {
|
|
37016
|
+
const stripped = content.charCodeAt(0) === 65279 ? content.slice(1) : content;
|
|
37017
|
+
const openFence = stripped.match(/^---[ \t]*\r?\n/);
|
|
37018
|
+
if (!openFence)
|
|
37019
|
+
return null;
|
|
37020
|
+
const fenceLen = openFence[0].length;
|
|
37021
|
+
const closeFence = stripped.slice(fenceLen).match(/\n---[ \t]*(\r?\n|$)/);
|
|
37022
|
+
if (!closeFence)
|
|
37023
|
+
return null;
|
|
37024
|
+
const closeStart = fenceLen + (closeFence.index ?? 0);
|
|
37025
|
+
const body = stripped.slice(fenceLen, closeStart).replace(/\r\n/g, `
|
|
37026
|
+
`);
|
|
37027
|
+
const lines = body.split(`
|
|
37028
|
+
`);
|
|
37029
|
+
const out = {
|
|
37030
|
+
sourceKnowledgeIds: []
|
|
37031
|
+
};
|
|
37032
|
+
let inLegacyIdsList = false;
|
|
37033
|
+
let inSourceIdsList = false;
|
|
37034
|
+
for (const raw of lines) {
|
|
37035
|
+
const line = raw;
|
|
37036
|
+
if (inLegacyIdsList || inSourceIdsList) {
|
|
37037
|
+
const m = line.match(/^\s+-\s+(\S{1,64})\s*$/);
|
|
37038
|
+
if (m) {
|
|
37039
|
+
out.sourceKnowledgeIds.push(m[1]);
|
|
37040
|
+
continue;
|
|
37041
|
+
}
|
|
37042
|
+
inLegacyIdsList = false;
|
|
37043
|
+
inSourceIdsList = false;
|
|
37044
|
+
}
|
|
37045
|
+
const nm = line.match(/^name:\s*(\S+)\s*$/);
|
|
37046
|
+
if (nm) {
|
|
37047
|
+
out.name = nm[1];
|
|
37048
|
+
continue;
|
|
37049
|
+
}
|
|
37050
|
+
const st = line.match(/^status:\s*(\S+)\s*$/);
|
|
37051
|
+
if (st) {
|
|
37052
|
+
out.status = st[1];
|
|
37053
|
+
continue;
|
|
37054
|
+
}
|
|
37055
|
+
const ga = line.match(/^generated_at:\s*(\S+)\s*$/);
|
|
37056
|
+
if (ga) {
|
|
37057
|
+
out.generatedAt = ga[1];
|
|
37058
|
+
continue;
|
|
37059
|
+
}
|
|
37060
|
+
if (/^generated_from_knowledge:\s*$/.test(line)) {
|
|
37061
|
+
inLegacyIdsList = true;
|
|
37062
|
+
continue;
|
|
37063
|
+
}
|
|
37064
|
+
if (/^source_knowledge_ids:\s*$/.test(line)) {
|
|
37065
|
+
out.sourceKnowledgeIds = [];
|
|
37066
|
+
inSourceIdsList = true;
|
|
37067
|
+
}
|
|
37068
|
+
}
|
|
37069
|
+
return out;
|
|
37070
|
+
}
|
|
37012
37071
|
async function listSkills(directory) {
|
|
37013
37072
|
const result = {
|
|
37014
37073
|
proposals: [],
|
|
@@ -38338,7 +38397,7 @@ var init_skill_improver_quota = __esm(() => {
|
|
|
38338
38397
|
|
|
38339
38398
|
// src/services/skill-improver.ts
|
|
38340
38399
|
import { existsSync as existsSync12 } from "fs";
|
|
38341
|
-
import { mkdir as mkdir7, rename as rename5, writeFile as writeFile6 } from "fs/promises";
|
|
38400
|
+
import { mkdir as mkdir7, readFile as readFile7, rename as rename5, writeFile as writeFile6 } from "fs/promises";
|
|
38342
38401
|
import * as path18 from "path";
|
|
38343
38402
|
function timestampSlug(d) {
|
|
38344
38403
|
return d.toISOString().replace(/[:.]/g, "-");
|
|
@@ -38355,15 +38414,63 @@ async function gatherInventory(directory) {
|
|
|
38355
38414
|
const hive = existsSync12(hivePath) ? await readKnowledge(hivePath) : [];
|
|
38356
38415
|
const archived = [...swarm, ...hive].filter((e) => e.status === "archived").length;
|
|
38357
38416
|
const skills = await listSkills(directory);
|
|
38417
|
+
const knowledgeById = new Map([...swarm, ...hive].map((entry) => [entry.id, entry]));
|
|
38418
|
+
const staleActiveSkills = [];
|
|
38419
|
+
let metadataReadable = 0;
|
|
38420
|
+
for (const skill of skills.active) {
|
|
38421
|
+
let content;
|
|
38422
|
+
try {
|
|
38423
|
+
content = await readFile7(skill.path, "utf-8");
|
|
38424
|
+
} catch {
|
|
38425
|
+
continue;
|
|
38426
|
+
}
|
|
38427
|
+
const fm = parseDraftFrontmatter(content);
|
|
38428
|
+
if (!fm)
|
|
38429
|
+
continue;
|
|
38430
|
+
metadataReadable += 1;
|
|
38431
|
+
const reasons = [];
|
|
38432
|
+
if (fm.sourceKnowledgeIds.length === 0) {
|
|
38433
|
+
reasons.push("missing_source_knowledge_ids");
|
|
38434
|
+
}
|
|
38435
|
+
if (!fm.generatedAt) {
|
|
38436
|
+
reasons.push("missing_generated_at");
|
|
38437
|
+
} else {
|
|
38438
|
+
const generatedAtMs = Date.parse(fm.generatedAt);
|
|
38439
|
+
if (!Number.isFinite(generatedAtMs)) {
|
|
38440
|
+
reasons.push("invalid_generated_at");
|
|
38441
|
+
} else {
|
|
38442
|
+
for (const id of fm.sourceKnowledgeIds) {
|
|
38443
|
+
const source = knowledgeById.get(id);
|
|
38444
|
+
if (!source) {
|
|
38445
|
+
reasons.push(`missing_source:${id}`);
|
|
38446
|
+
continue;
|
|
38447
|
+
}
|
|
38448
|
+
const updatedAtMs = Date.parse(source.updated_at);
|
|
38449
|
+
if (Number.isFinite(updatedAtMs) && updatedAtMs > generatedAtMs) {
|
|
38450
|
+
reasons.push(`updated_after_generation:${id}`);
|
|
38451
|
+
}
|
|
38452
|
+
}
|
|
38453
|
+
}
|
|
38454
|
+
}
|
|
38455
|
+
if (reasons.length > 0) {
|
|
38456
|
+
staleActiveSkills.push({
|
|
38457
|
+
slug: skill.slug,
|
|
38458
|
+
reasons: reasons.slice(0, 6)
|
|
38459
|
+
});
|
|
38460
|
+
}
|
|
38461
|
+
}
|
|
38358
38462
|
const matureCandidates = swarm.concat(hive).filter((e) => e.status !== "archived" && e.confidence >= 0.85 && !e.generated_skill_slug && (e.confirmed_by ?? []).length >= 2);
|
|
38359
38463
|
return {
|
|
38360
38464
|
knowledge: { swarm: swarm.length, hive: hive.length, archived },
|
|
38361
38465
|
skills: {
|
|
38362
38466
|
proposals: skills.proposals.length,
|
|
38363
|
-
active: skills.active.length
|
|
38467
|
+
active: skills.active.length,
|
|
38468
|
+
stale: staleActiveSkills.length,
|
|
38469
|
+
metadataReadable
|
|
38364
38470
|
},
|
|
38365
38471
|
highConfidenceClusters: matureCandidates.length,
|
|
38366
|
-
matureCandidates
|
|
38472
|
+
matureCandidates,
|
|
38473
|
+
staleActiveSkills
|
|
38367
38474
|
};
|
|
38368
38475
|
}
|
|
38369
38476
|
function buildSystemPrompt(targets, cfg) {
|
|
@@ -38387,10 +38494,16 @@ hive_entries: ${inv.knowledge.hive}
|
|
|
38387
38494
|
archived: ${inv.knowledge.archived}
|
|
38388
38495
|
draft_skills: ${inv.skills.proposals}
|
|
38389
38496
|
active_skills: ${inv.skills.active}
|
|
38497
|
+
active_skills_with_readable_metadata: ${inv.skills.metadataReadable}
|
|
38498
|
+
stale_active_skills: ${inv.skills.stale}
|
|
38390
38499
|
mature_uncompiled_clusters: ${inv.highConfidenceClusters}
|
|
38391
38500
|
|
|
38392
38501
|
TOP MATURE CANDIDATES (first 25):
|
|
38393
38502
|
${matureRows || "(none)"}
|
|
38503
|
+
|
|
38504
|
+
STALE ACTIVE SKILLS (first 10):
|
|
38505
|
+
${inv.staleActiveSkills.slice(0, 10).map((s) => `- ${s.slug} | ${s.reasons.join(", ")}`).join(`
|
|
38506
|
+
`) || "(none)"}
|
|
38394
38507
|
`;
|
|
38395
38508
|
}
|
|
38396
38509
|
function isAbortError(err) {
|
|
@@ -38419,7 +38532,11 @@ function buildDeterministicProposal(args) {
|
|
|
38419
38532
|
lines.push("## Inventory snapshot");
|
|
38420
38533
|
lines.push(`- Knowledge entries: swarm=${args.inventory.knowledge.swarm}, hive=${args.inventory.knowledge.hive}, archived=${args.inventory.knowledge.archived}`);
|
|
38421
38534
|
lines.push(`- Generated skills: proposals=${args.inventory.skills.proposals}, active=${args.inventory.skills.active}`);
|
|
38535
|
+
lines.push(`- Active skills with readable metadata: ${args.inventory.skills.metadataReadable} (stale=${args.inventory.skills.stale})`);
|
|
38422
38536
|
lines.push(`- High-confidence un-skill'd clusters: ${args.inventory.highConfidenceClusters}`);
|
|
38537
|
+
if (args.inventory.staleActiveSkills.length > 0) {
|
|
38538
|
+
lines.push(`- Stale active skills: ${args.inventory.staleActiveSkills.map((s) => s.slug).join(", ")}`);
|
|
38539
|
+
}
|
|
38423
38540
|
lines.push("");
|
|
38424
38541
|
lines.push("## Recommendations");
|
|
38425
38542
|
if (args.inventory.highConfidenceClusters > 0) {
|
|
@@ -39914,7 +40031,7 @@ var init_curate = __esm(() => {
|
|
|
39914
40031
|
// src/tools/co-change-analyzer.ts
|
|
39915
40032
|
import * as child_process3 from "child_process";
|
|
39916
40033
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
39917
|
-
import { readdir, readFile as
|
|
40034
|
+
import { readdir, readFile as readFile8, stat as stat2 } from "fs/promises";
|
|
39918
40035
|
import * as path21 from "path";
|
|
39919
40036
|
import { promisify } from "util";
|
|
39920
40037
|
function getExecFileAsync() {
|
|
@@ -40041,7 +40158,7 @@ async function getStaticEdges(directory) {
|
|
|
40041
40158
|
const sourceFiles = await scanSourceFiles(directory);
|
|
40042
40159
|
for (const sourceFile of sourceFiles) {
|
|
40043
40160
|
try {
|
|
40044
|
-
const content = await
|
|
40161
|
+
const content = await readFile8(sourceFile, "utf-8");
|
|
40045
40162
|
const importRegex = /(?:import|require)\s*(?:\(?\s*['"`]|.*?from\s+['"`])([^'"`]+)['"`]/g;
|
|
40046
40163
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
40047
40164
|
const importPath = match[1].trim();
|
|
@@ -40825,11 +40942,11 @@ var init_version_check = __esm(() => {
|
|
|
40825
40942
|
|
|
40826
40943
|
// src/services/knowledge-diagnostics.ts
|
|
40827
40944
|
import { existsSync as existsSync14 } from "fs";
|
|
40828
|
-
import { readFile as
|
|
40945
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
40829
40946
|
async function readRawLines(filePath) {
|
|
40830
40947
|
if (!existsSync14(filePath))
|
|
40831
40948
|
return { entries: [], corrupt: 0 };
|
|
40832
|
-
const content = await
|
|
40949
|
+
const content = await readFile9(filePath, "utf-8");
|
|
40833
40950
|
const entries = [];
|
|
40834
40951
|
let corrupt = 0;
|
|
40835
40952
|
for (const line of content.split(`
|
|
@@ -46049,7 +46166,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
|
46049
46166
|
// src/hooks/knowledge-migrator.ts
|
|
46050
46167
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
46051
46168
|
import { existsSync as existsSync19, readFileSync as readFileSync13 } from "fs";
|
|
46052
|
-
import { mkdir as mkdir8, readFile as
|
|
46169
|
+
import { mkdir as mkdir8, readFile as readFile10, writeFile as writeFile7 } from "fs/promises";
|
|
46053
46170
|
import * as path29 from "path";
|
|
46054
46171
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
46055
46172
|
return {
|
|
@@ -46082,7 +46199,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
46082
46199
|
skippedReason: "no-context-file"
|
|
46083
46200
|
};
|
|
46084
46201
|
}
|
|
46085
|
-
const contextContent = await
|
|
46202
|
+
const contextContent = await readFile10(contextPath, "utf-8");
|
|
46086
46203
|
if (contextContent.trim().length === 0) {
|
|
46087
46204
|
return {
|
|
46088
46205
|
migrated: false,
|
|
@@ -47331,7 +47448,7 @@ import { existsSync as existsSync20 } from "fs";
|
|
|
47331
47448
|
import {
|
|
47332
47449
|
appendFile as appendFile5,
|
|
47333
47450
|
mkdir as mkdir9,
|
|
47334
|
-
readFile as
|
|
47451
|
+
readFile as readFile11,
|
|
47335
47452
|
rename as rename6,
|
|
47336
47453
|
writeFile as writeFile8
|
|
47337
47454
|
} from "fs/promises";
|
|
@@ -47680,7 +47797,7 @@ function validateLoadedProposals(values, config3) {
|
|
|
47680
47797
|
async function readJsonl(filePath) {
|
|
47681
47798
|
if (!existsSync20(filePath))
|
|
47682
47799
|
return [];
|
|
47683
|
-
const content = await
|
|
47800
|
+
const content = await readFile11(filePath, "utf-8");
|
|
47684
47801
|
const records = [];
|
|
47685
47802
|
for (const line of content.split(`
|
|
47686
47803
|
`)) {
|
|
@@ -47765,7 +47882,7 @@ var init_prompt_block = __esm(() => {
|
|
|
47765
47882
|
|
|
47766
47883
|
// src/memory/jsonl-migration.ts
|
|
47767
47884
|
import { existsSync as existsSync21 } from "fs";
|
|
47768
|
-
import { copyFile, mkdir as mkdir10, readFile as
|
|
47885
|
+
import { copyFile, mkdir as mkdir10, readFile as readFile12, stat as stat3, writeFile as writeFile9 } from "fs/promises";
|
|
47769
47886
|
import * as path31 from "path";
|
|
47770
47887
|
function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
|
|
47771
47888
|
const resolved = resolveConfig(config3);
|
|
@@ -47829,7 +47946,7 @@ async function readMigrationReport(rootDirectory, config3 = {}) {
|
|
|
47829
47946
|
if (!existsSync21(reportPath))
|
|
47830
47947
|
return null;
|
|
47831
47948
|
try {
|
|
47832
|
-
return JSON.parse(await
|
|
47949
|
+
return JSON.parse(await readFile12(reportPath, "utf-8"));
|
|
47833
47950
|
} catch {
|
|
47834
47951
|
return null;
|
|
47835
47952
|
}
|
|
@@ -47930,7 +48047,7 @@ async function readJsonlRows(filePath) {
|
|
|
47930
48047
|
if (!existsSync21(filePath)) {
|
|
47931
48048
|
return { rows: [], invalidRows: [], totalRows: 0 };
|
|
47932
48049
|
}
|
|
47933
|
-
const content = await
|
|
48050
|
+
const content = await readFile12(filePath, "utf-8");
|
|
47934
48051
|
const rows = [];
|
|
47935
48052
|
const invalidRows = [];
|
|
47936
48053
|
let totalRows = 0;
|
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.
|
|
72
|
+
version: "7.56.0",
|
|
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",
|
|
@@ -57856,7 +57856,7 @@ function clusterEntries(entries) {
|
|
|
57856
57856
|
function uniqueStrings(arr) {
|
|
57857
57857
|
return [...new Set(arr.filter((s) => typeof s === "string" && s.length > 0))];
|
|
57858
57858
|
}
|
|
57859
|
-
function renderSkillMarkdown(cluster, mode = "active") {
|
|
57859
|
+
function renderSkillMarkdown(cluster, mode = "active", generatedAt = new Date().toISOString()) {
|
|
57860
57860
|
const description = cluster.title.length > 200 ? `${cluster.title.slice(0, 197)}…` : cluster.title;
|
|
57861
57861
|
const ids = cluster.entries.map((e) => ` - ${e.id}`).join(`
|
|
57862
57862
|
`);
|
|
@@ -57866,6 +57866,9 @@ function renderSkillMarkdown(cluster, mode = "active") {
|
|
|
57866
57866
|
lines.push(`description: ${escapeYaml(description)}`);
|
|
57867
57867
|
lines.push("generated_from_knowledge:");
|
|
57868
57868
|
lines.push(ids);
|
|
57869
|
+
lines.push("source_knowledge_ids:");
|
|
57870
|
+
lines.push(ids);
|
|
57871
|
+
lines.push(`generated_at: ${generatedAt}`);
|
|
57869
57872
|
lines.push(`confidence: ${cluster.avgConfidence.toFixed(2)}`);
|
|
57870
57873
|
lines.push(`status: ${mode === "active" ? "active" : "draft"}`);
|
|
57871
57874
|
lines.push("---");
|
|
@@ -58071,16 +58074,18 @@ function parseDraftFrontmatter(content) {
|
|
|
58071
58074
|
const out2 = {
|
|
58072
58075
|
sourceKnowledgeIds: []
|
|
58073
58076
|
};
|
|
58074
|
-
let
|
|
58077
|
+
let inLegacyIdsList = false;
|
|
58078
|
+
let inSourceIdsList = false;
|
|
58075
58079
|
for (const raw of lines) {
|
|
58076
58080
|
const line = raw;
|
|
58077
|
-
if (
|
|
58081
|
+
if (inLegacyIdsList || inSourceIdsList) {
|
|
58078
58082
|
const m = line.match(/^\s+-\s+(\S{1,64})\s*$/);
|
|
58079
58083
|
if (m) {
|
|
58080
58084
|
out2.sourceKnowledgeIds.push(m[1]);
|
|
58081
58085
|
continue;
|
|
58082
58086
|
}
|
|
58083
|
-
|
|
58087
|
+
inLegacyIdsList = false;
|
|
58088
|
+
inSourceIdsList = false;
|
|
58084
58089
|
}
|
|
58085
58090
|
const nm = line.match(/^name:\s*(\S+)\s*$/);
|
|
58086
58091
|
if (nm) {
|
|
@@ -58092,8 +58097,18 @@ function parseDraftFrontmatter(content) {
|
|
|
58092
58097
|
out2.status = st[1];
|
|
58093
58098
|
continue;
|
|
58094
58099
|
}
|
|
58100
|
+
const ga = line.match(/^generated_at:\s*(\S+)\s*$/);
|
|
58101
|
+
if (ga) {
|
|
58102
|
+
out2.generatedAt = ga[1];
|
|
58103
|
+
continue;
|
|
58104
|
+
}
|
|
58095
58105
|
if (/^generated_from_knowledge:\s*$/.test(line)) {
|
|
58096
|
-
|
|
58106
|
+
inLegacyIdsList = true;
|
|
58107
|
+
continue;
|
|
58108
|
+
}
|
|
58109
|
+
if (/^source_knowledge_ids:\s*$/.test(line)) {
|
|
58110
|
+
out2.sourceKnowledgeIds = [];
|
|
58111
|
+
inSourceIdsList = true;
|
|
58097
58112
|
}
|
|
58098
58113
|
}
|
|
58099
58114
|
return out2;
|
|
@@ -60763,7 +60778,7 @@ var init_skill_improver_quota = __esm(() => {
|
|
|
60763
60778
|
|
|
60764
60779
|
// src/services/skill-improver.ts
|
|
60765
60780
|
import { existsSync as existsSync18 } from "node:fs";
|
|
60766
|
-
import { mkdir as mkdir8, rename as rename5, writeFile as writeFile6 } from "node:fs/promises";
|
|
60781
|
+
import { mkdir as mkdir8, readFile as readFile9, rename as rename5, writeFile as writeFile6 } from "node:fs/promises";
|
|
60767
60782
|
import * as path31 from "node:path";
|
|
60768
60783
|
function timestampSlug(d) {
|
|
60769
60784
|
return d.toISOString().replace(/[:.]/g, "-");
|
|
@@ -60780,15 +60795,63 @@ async function gatherInventory(directory) {
|
|
|
60780
60795
|
const hive = existsSync18(hivePath) ? await readKnowledge(hivePath) : [];
|
|
60781
60796
|
const archived = [...swarm, ...hive].filter((e) => e.status === "archived").length;
|
|
60782
60797
|
const skills = await listSkills(directory);
|
|
60798
|
+
const knowledgeById = new Map([...swarm, ...hive].map((entry) => [entry.id, entry]));
|
|
60799
|
+
const staleActiveSkills = [];
|
|
60800
|
+
let metadataReadable = 0;
|
|
60801
|
+
for (const skill of skills.active) {
|
|
60802
|
+
let content;
|
|
60803
|
+
try {
|
|
60804
|
+
content = await readFile9(skill.path, "utf-8");
|
|
60805
|
+
} catch {
|
|
60806
|
+
continue;
|
|
60807
|
+
}
|
|
60808
|
+
const fm = parseDraftFrontmatter(content);
|
|
60809
|
+
if (!fm)
|
|
60810
|
+
continue;
|
|
60811
|
+
metadataReadable += 1;
|
|
60812
|
+
const reasons = [];
|
|
60813
|
+
if (fm.sourceKnowledgeIds.length === 0) {
|
|
60814
|
+
reasons.push("missing_source_knowledge_ids");
|
|
60815
|
+
}
|
|
60816
|
+
if (!fm.generatedAt) {
|
|
60817
|
+
reasons.push("missing_generated_at");
|
|
60818
|
+
} else {
|
|
60819
|
+
const generatedAtMs = Date.parse(fm.generatedAt);
|
|
60820
|
+
if (!Number.isFinite(generatedAtMs)) {
|
|
60821
|
+
reasons.push("invalid_generated_at");
|
|
60822
|
+
} else {
|
|
60823
|
+
for (const id of fm.sourceKnowledgeIds) {
|
|
60824
|
+
const source = knowledgeById.get(id);
|
|
60825
|
+
if (!source) {
|
|
60826
|
+
reasons.push(`missing_source:${id}`);
|
|
60827
|
+
continue;
|
|
60828
|
+
}
|
|
60829
|
+
const updatedAtMs = Date.parse(source.updated_at);
|
|
60830
|
+
if (Number.isFinite(updatedAtMs) && updatedAtMs > generatedAtMs) {
|
|
60831
|
+
reasons.push(`updated_after_generation:${id}`);
|
|
60832
|
+
}
|
|
60833
|
+
}
|
|
60834
|
+
}
|
|
60835
|
+
}
|
|
60836
|
+
if (reasons.length > 0) {
|
|
60837
|
+
staleActiveSkills.push({
|
|
60838
|
+
slug: skill.slug,
|
|
60839
|
+
reasons: reasons.slice(0, 6)
|
|
60840
|
+
});
|
|
60841
|
+
}
|
|
60842
|
+
}
|
|
60783
60843
|
const matureCandidates = swarm.concat(hive).filter((e) => e.status !== "archived" && e.confidence >= 0.85 && !e.generated_skill_slug && (e.confirmed_by ?? []).length >= 2);
|
|
60784
60844
|
return {
|
|
60785
60845
|
knowledge: { swarm: swarm.length, hive: hive.length, archived },
|
|
60786
60846
|
skills: {
|
|
60787
60847
|
proposals: skills.proposals.length,
|
|
60788
|
-
active: skills.active.length
|
|
60848
|
+
active: skills.active.length,
|
|
60849
|
+
stale: staleActiveSkills.length,
|
|
60850
|
+
metadataReadable
|
|
60789
60851
|
},
|
|
60790
60852
|
highConfidenceClusters: matureCandidates.length,
|
|
60791
|
-
matureCandidates
|
|
60853
|
+
matureCandidates,
|
|
60854
|
+
staleActiveSkills
|
|
60792
60855
|
};
|
|
60793
60856
|
}
|
|
60794
60857
|
function buildSystemPrompt(targets, cfg) {
|
|
@@ -60812,10 +60875,16 @@ hive_entries: ${inv.knowledge.hive}
|
|
|
60812
60875
|
archived: ${inv.knowledge.archived}
|
|
60813
60876
|
draft_skills: ${inv.skills.proposals}
|
|
60814
60877
|
active_skills: ${inv.skills.active}
|
|
60878
|
+
active_skills_with_readable_metadata: ${inv.skills.metadataReadable}
|
|
60879
|
+
stale_active_skills: ${inv.skills.stale}
|
|
60815
60880
|
mature_uncompiled_clusters: ${inv.highConfidenceClusters}
|
|
60816
60881
|
|
|
60817
60882
|
TOP MATURE CANDIDATES (first 25):
|
|
60818
60883
|
${matureRows || "(none)"}
|
|
60884
|
+
|
|
60885
|
+
STALE ACTIVE SKILLS (first 10):
|
|
60886
|
+
${inv.staleActiveSkills.slice(0, 10).map((s) => `- ${s.slug} | ${s.reasons.join(", ")}`).join(`
|
|
60887
|
+
`) || "(none)"}
|
|
60819
60888
|
`;
|
|
60820
60889
|
}
|
|
60821
60890
|
function isAbortError(err2) {
|
|
@@ -60844,7 +60913,11 @@ function buildDeterministicProposal(args2) {
|
|
|
60844
60913
|
lines.push("## Inventory snapshot");
|
|
60845
60914
|
lines.push(`- Knowledge entries: swarm=${args2.inventory.knowledge.swarm}, hive=${args2.inventory.knowledge.hive}, archived=${args2.inventory.knowledge.archived}`);
|
|
60846
60915
|
lines.push(`- Generated skills: proposals=${args2.inventory.skills.proposals}, active=${args2.inventory.skills.active}`);
|
|
60916
|
+
lines.push(`- Active skills with readable metadata: ${args2.inventory.skills.metadataReadable} (stale=${args2.inventory.skills.stale})`);
|
|
60847
60917
|
lines.push(`- High-confidence un-skill'd clusters: ${args2.inventory.highConfidenceClusters}`);
|
|
60918
|
+
if (args2.inventory.staleActiveSkills.length > 0) {
|
|
60919
|
+
lines.push(`- Stale active skills: ${args2.inventory.staleActiveSkills.map((s) => s.slug).join(", ")}`);
|
|
60920
|
+
}
|
|
60848
60921
|
lines.push("");
|
|
60849
60922
|
lines.push("## Recommendations");
|
|
60850
60923
|
if (args2.inventory.highConfidenceClusters > 0) {
|
|
@@ -62350,7 +62423,7 @@ __export(exports_co_change_analyzer, {
|
|
|
62350
62423
|
});
|
|
62351
62424
|
import * as child_process3 from "node:child_process";
|
|
62352
62425
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
62353
|
-
import { readdir as readdir2, readFile as
|
|
62426
|
+
import { readdir as readdir2, readFile as readFile10, stat as stat3 } from "node:fs/promises";
|
|
62354
62427
|
import * as path34 from "node:path";
|
|
62355
62428
|
import { promisify } from "node:util";
|
|
62356
62429
|
function getExecFileAsync() {
|
|
@@ -62477,7 +62550,7 @@ async function getStaticEdges(directory) {
|
|
|
62477
62550
|
const sourceFiles = await scanSourceFiles(directory);
|
|
62478
62551
|
for (const sourceFile of sourceFiles) {
|
|
62479
62552
|
try {
|
|
62480
|
-
const content = await
|
|
62553
|
+
const content = await readFile10(sourceFile, "utf-8");
|
|
62481
62554
|
const importRegex = /(?:import|require)\s*(?:\(?\s*['"`]|.*?from\s+['"`])([^'"`]+)['"`]/g;
|
|
62482
62555
|
for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
|
|
62483
62556
|
const importPath = match[1].trim();
|
|
@@ -63239,11 +63312,11 @@ var init_version_check = __esm(() => {
|
|
|
63239
63312
|
|
|
63240
63313
|
// src/services/knowledge-diagnostics.ts
|
|
63241
63314
|
import { existsSync as existsSync20 } from "node:fs";
|
|
63242
|
-
import { readFile as
|
|
63315
|
+
import { readFile as readFile11 } from "node:fs/promises";
|
|
63243
63316
|
async function readRawLines(filePath) {
|
|
63244
63317
|
if (!existsSync20(filePath))
|
|
63245
63318
|
return { entries: [], corrupt: 0 };
|
|
63246
|
-
const content = await
|
|
63319
|
+
const content = await readFile11(filePath, "utf-8");
|
|
63247
63320
|
const entries = [];
|
|
63248
63321
|
let corrupt = 0;
|
|
63249
63322
|
for (const line of content.split(`
|
|
@@ -68601,7 +68674,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
|
68601
68674
|
// src/hooks/knowledge-migrator.ts
|
|
68602
68675
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
68603
68676
|
import { existsSync as existsSync25, readFileSync as readFileSync14 } from "node:fs";
|
|
68604
|
-
import { mkdir as mkdir9, readFile as
|
|
68677
|
+
import { mkdir as mkdir9, readFile as readFile12, writeFile as writeFile7 } from "node:fs/promises";
|
|
68605
68678
|
import * as path42 from "node:path";
|
|
68606
68679
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
68607
68680
|
return {
|
|
@@ -68634,7 +68707,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
68634
68707
|
skippedReason: "no-context-file"
|
|
68635
68708
|
};
|
|
68636
68709
|
}
|
|
68637
|
-
const contextContent = await
|
|
68710
|
+
const contextContent = await readFile12(contextPath, "utf-8");
|
|
68638
68711
|
if (contextContent.trim().length === 0) {
|
|
68639
68712
|
return {
|
|
68640
68713
|
migrated: false,
|
|
@@ -69912,7 +69985,7 @@ import { existsSync as existsSync26 } from "node:fs";
|
|
|
69912
69985
|
import {
|
|
69913
69986
|
appendFile as appendFile6,
|
|
69914
69987
|
mkdir as mkdir10,
|
|
69915
|
-
readFile as
|
|
69988
|
+
readFile as readFile13,
|
|
69916
69989
|
rename as rename6,
|
|
69917
69990
|
writeFile as writeFile8
|
|
69918
69991
|
} from "node:fs/promises";
|
|
@@ -70261,7 +70334,7 @@ function validateLoadedProposals(values, config3) {
|
|
|
70261
70334
|
async function readJsonl(filePath) {
|
|
70262
70335
|
if (!existsSync26(filePath))
|
|
70263
70336
|
return [];
|
|
70264
|
-
const content = await
|
|
70337
|
+
const content = await readFile13(filePath, "utf-8");
|
|
70265
70338
|
const records = [];
|
|
70266
70339
|
for (const line of content.split(`
|
|
70267
70340
|
`)) {
|
|
@@ -70420,7 +70493,7 @@ var init_prompt_block = __esm(() => {
|
|
|
70420
70493
|
|
|
70421
70494
|
// src/memory/jsonl-migration.ts
|
|
70422
70495
|
import { existsSync as existsSync27 } from "node:fs";
|
|
70423
|
-
import { copyFile, mkdir as mkdir11, readFile as
|
|
70496
|
+
import { copyFile, mkdir as mkdir11, readFile as readFile14, stat as stat4, writeFile as writeFile9 } from "node:fs/promises";
|
|
70424
70497
|
import * as path44 from "node:path";
|
|
70425
70498
|
function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
|
|
70426
70499
|
const resolved = resolveConfig(config3);
|
|
@@ -70484,7 +70557,7 @@ async function readMigrationReport(rootDirectory, config3 = {}) {
|
|
|
70484
70557
|
if (!existsSync27(reportPath))
|
|
70485
70558
|
return null;
|
|
70486
70559
|
try {
|
|
70487
|
-
return JSON.parse(await
|
|
70560
|
+
return JSON.parse(await readFile14(reportPath, "utf-8"));
|
|
70488
70561
|
} catch {
|
|
70489
70562
|
return null;
|
|
70490
70563
|
}
|
|
@@ -70585,7 +70658,7 @@ async function readJsonlRows(filePath) {
|
|
|
70585
70658
|
if (!existsSync27(filePath)) {
|
|
70586
70659
|
return { rows: [], invalidRows: [], totalRows: 0 };
|
|
70587
70660
|
}
|
|
70588
|
-
const content = await
|
|
70661
|
+
const content = await readFile14(filePath, "utf-8");
|
|
70589
70662
|
const rows = [];
|
|
70590
70663
|
const invalidRows = [];
|
|
70591
70664
|
let totalRows = 0;
|
|
@@ -91719,7 +91792,7 @@ import * as fs65 from "node:fs";
|
|
|
91719
91792
|
import {
|
|
91720
91793
|
mkdir as mkdir16,
|
|
91721
91794
|
readdir as readdir6,
|
|
91722
|
-
readFile as
|
|
91795
|
+
readFile as readFile17,
|
|
91723
91796
|
realpath as realpath3,
|
|
91724
91797
|
stat as stat7,
|
|
91725
91798
|
writeFile as writeFile12
|
|
@@ -91797,7 +91870,7 @@ async function scanDocIndex(directory) {
|
|
|
91797
91870
|
];
|
|
91798
91871
|
const allPatterns = [...defaultPatterns, ...extraPatterns];
|
|
91799
91872
|
try {
|
|
91800
|
-
const manifestContent = await
|
|
91873
|
+
const manifestContent = await readFile17(manifestPath, "utf-8");
|
|
91801
91874
|
const existingManifest = JSON.parse(manifestContent);
|
|
91802
91875
|
if (existingManifest.schema_version === 1 && existingManifest.files) {
|
|
91803
91876
|
let cacheValid = true;
|
|
@@ -91878,7 +91951,7 @@ async function scanDocIndex(directory) {
|
|
|
91878
91951
|
}
|
|
91879
91952
|
let content;
|
|
91880
91953
|
try {
|
|
91881
|
-
content = await
|
|
91954
|
+
content = await readFile17(fullPath, "utf-8");
|
|
91882
91955
|
} catch {
|
|
91883
91956
|
continue;
|
|
91884
91957
|
}
|
|
@@ -91961,7 +92034,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
91961
92034
|
const manifestPath = path102.join(directory, ".swarm", "doc-manifest.json");
|
|
91962
92035
|
let manifest;
|
|
91963
92036
|
try {
|
|
91964
|
-
const content = await
|
|
92037
|
+
const content = await readFile17(manifestPath, "utf-8");
|
|
91965
92038
|
manifest = JSON.parse(content);
|
|
91966
92039
|
} catch {
|
|
91967
92040
|
const result = await scanDocIndex(directory);
|
|
@@ -91984,7 +92057,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
|
|
|
91984
92057
|
}
|
|
91985
92058
|
let fullContent;
|
|
91986
92059
|
try {
|
|
91987
|
-
fullContent = await
|
|
92060
|
+
fullContent = await readFile17(path102.join(directory, docFile.path), "utf-8");
|
|
91988
92061
|
} catch {
|
|
91989
92062
|
skippedCount++;
|
|
91990
92063
|
continue;
|
|
@@ -92134,7 +92207,7 @@ var init_doc_scan = __esm(() => {
|
|
|
92134
92207
|
|
|
92135
92208
|
// src/hooks/knowledge-reader.ts
|
|
92136
92209
|
import { existsSync as existsSync57 } from "node:fs";
|
|
92137
|
-
import { readFile as
|
|
92210
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
92138
92211
|
import * as path103 from "node:path";
|
|
92139
92212
|
function inferCategoriesFromPhase(phaseDescription) {
|
|
92140
92213
|
const lower = phaseDescription.toLowerCase();
|
|
@@ -92184,7 +92257,7 @@ async function transactShownFile(shownFile, mutate) {
|
|
|
92184
92257
|
if (!existsSync57(filePath))
|
|
92185
92258
|
return {};
|
|
92186
92259
|
try {
|
|
92187
|
-
const content = await
|
|
92260
|
+
const content = await readFile18(filePath, "utf-8");
|
|
92188
92261
|
return JSON.parse(content);
|
|
92189
92262
|
} catch {
|
|
92190
92263
|
return {};
|
|
@@ -92311,7 +92384,7 @@ async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
|
92311
92384
|
}
|
|
92312
92385
|
let shownIds;
|
|
92313
92386
|
try {
|
|
92314
|
-
const content = await
|
|
92387
|
+
const content = await readFile18(shownFile, "utf-8");
|
|
92315
92388
|
const shownData = JSON.parse(content);
|
|
92316
92389
|
shownIds = shownData[phaseInfo];
|
|
92317
92390
|
} catch {
|
|
@@ -104427,7 +104500,7 @@ init_logger();
|
|
|
104427
104500
|
init_knowledge_store();
|
|
104428
104501
|
var import_proper_lockfile8 = __toESM(require_proper_lockfile(), 1);
|
|
104429
104502
|
import { existsSync as existsSync61 } from "node:fs";
|
|
104430
|
-
import { appendFile as appendFile9, mkdir as mkdir17, readFile as
|
|
104503
|
+
import { appendFile as appendFile9, mkdir as mkdir17, readFile as readFile19 } from "node:fs/promises";
|
|
104431
104504
|
import * as path107 from "node:path";
|
|
104432
104505
|
function resolveApplicationLogPath(directory) {
|
|
104433
104506
|
return path107.join(directory, ".swarm", "knowledge-application.jsonl");
|
|
@@ -42,7 +42,7 @@ export declare function selectCandidateEntries(directory: string, opts: Candidat
|
|
|
42
42
|
*/
|
|
43
43
|
declare function jaccardSimilarity(setA: string[], setB: string[]): number;
|
|
44
44
|
export declare function clusterEntries(entries: KnowledgeEntryBase[]): KnowledgeCluster[];
|
|
45
|
-
export declare function renderSkillMarkdown(cluster: KnowledgeCluster, mode?: GenerateMode): string;
|
|
45
|
+
export declare function renderSkillMarkdown(cluster: KnowledgeCluster, mode?: GenerateMode, generatedAt?: string): string;
|
|
46
46
|
export type GenerateMode = 'draft' | 'active';
|
|
47
47
|
export interface GenerateRequest {
|
|
48
48
|
directory: string;
|
|
@@ -84,6 +84,7 @@ declare function stampSourceEntries(directory: string, slug: string, ids: string
|
|
|
84
84
|
export declare function parseDraftFrontmatter(content: string): {
|
|
85
85
|
name?: string;
|
|
86
86
|
status?: string;
|
|
87
|
+
generatedAt?: string;
|
|
87
88
|
sourceKnowledgeIds: string[];
|
|
88
89
|
} | null;
|
|
89
90
|
export declare function activateProposal(directory: string, slug: string, force?: boolean): Promise<{
|
|
@@ -72,9 +72,15 @@ interface InventorySnapshot {
|
|
|
72
72
|
skills: {
|
|
73
73
|
proposals: number;
|
|
74
74
|
active: number;
|
|
75
|
+
stale: number;
|
|
76
|
+
metadataReadable: number;
|
|
75
77
|
};
|
|
76
78
|
highConfidenceClusters: number;
|
|
77
79
|
matureCandidates: SwarmKnowledgeEntry[];
|
|
80
|
+
staleActiveSkills: Array<{
|
|
81
|
+
slug: string;
|
|
82
|
+
reasons: string[];
|
|
83
|
+
}>;
|
|
78
84
|
}
|
|
79
85
|
declare function gatherInventory(directory: string): Promise<InventorySnapshot>;
|
|
80
86
|
declare function buildSystemPrompt(targets: SkillImproverTarget[], cfg: SkillImproverConfigInput): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.56.0",
|
|
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",
|