opencode-swarm 7.76.0 → 7.76.2
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 +322 -295
- package/dist/commands/registry.d.ts +7 -0
- package/dist/config/bundled-skills.d.ts +9 -3
- package/dist/hooks/abort-utils.d.ts +8 -0
- package/dist/index.js +531 -465
- package/dist/turbo/lean/integration.d.ts +1 -1
- package/dist/turbo/lean/reviewer.d.ts +1 -1
- package/dist/turbo/lean/runner.d.ts +4 -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.76.
|
|
55
|
+
version: "7.76.2",
|
|
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",
|
|
@@ -154,43 +154,56 @@ var init_package = __esm(() => {
|
|
|
154
154
|
|
|
155
155
|
// src/config/bundled-skills.ts
|
|
156
156
|
import * as fs from "fs";
|
|
157
|
+
import * as fsp from "fs/promises";
|
|
157
158
|
import * as path from "path";
|
|
158
|
-
function
|
|
159
|
+
function getSyncCacheKey(projectDirectory, packageRoot) {
|
|
160
|
+
return `${path.resolve(projectDirectory)}\x00${path.resolve(packageRoot)}`;
|
|
161
|
+
}
|
|
162
|
+
function warnBundledSkillSyncFailure(err) {
|
|
163
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
164
|
+
console.warn(`[opencode-swarm] Could not install bundled project skills; continuing without sync: ${message}`);
|
|
165
|
+
}
|
|
166
|
+
async function isSymbolicLinkAsync(p) {
|
|
159
167
|
try {
|
|
160
|
-
return
|
|
168
|
+
return (await fsp.lstat(p)).isSymbolicLink();
|
|
161
169
|
} catch {
|
|
162
170
|
return false;
|
|
163
171
|
}
|
|
164
172
|
}
|
|
165
|
-
function
|
|
173
|
+
async function ensureNotSymlinkedDirectoryAsync(p) {
|
|
166
174
|
try {
|
|
167
|
-
const
|
|
168
|
-
return
|
|
175
|
+
const stat2 = await fsp.lstat(p);
|
|
176
|
+
return stat2.isDirectory() && !stat2.isSymbolicLink();
|
|
169
177
|
} catch (err) {
|
|
170
178
|
return err.code === "ENOENT";
|
|
171
179
|
}
|
|
172
180
|
}
|
|
173
|
-
function
|
|
174
|
-
|
|
181
|
+
async function pathExistsAsync(p) {
|
|
182
|
+
try {
|
|
183
|
+
await fsp.access(p);
|
|
184
|
+
return true;
|
|
185
|
+
} catch {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
175
188
|
}
|
|
176
|
-
function
|
|
189
|
+
async function collectBundledSkillFilesBoundedAsync(sourceDir, state, relativeDir = "") {
|
|
177
190
|
const currentSource = path.join(sourceDir, relativeDir);
|
|
178
|
-
const entries =
|
|
191
|
+
const entries = await fsp.readdir(currentSource, { withFileTypes: true });
|
|
179
192
|
const files = [];
|
|
180
193
|
for (const entry of entries) {
|
|
181
194
|
const relativeEntry = path.join(relativeDir, entry.name);
|
|
182
195
|
const sourcePath = path.join(sourceDir, relativeEntry);
|
|
183
|
-
if (entry.isSymbolicLink() ||
|
|
196
|
+
if (entry.isSymbolicLink() || await isSymbolicLinkAsync(sourcePath))
|
|
184
197
|
continue;
|
|
185
198
|
if (entry.isDirectory()) {
|
|
186
|
-
files.push(...
|
|
199
|
+
files.push(...await collectBundledSkillFilesBoundedAsync(sourceDir, state, relativeEntry));
|
|
187
200
|
continue;
|
|
188
201
|
}
|
|
189
202
|
if (!entry.isFile())
|
|
190
203
|
continue;
|
|
191
|
-
const
|
|
204
|
+
const stat2 = await fsp.stat(sourcePath);
|
|
192
205
|
const nextFiles = state.files + 1;
|
|
193
|
-
const nextBytes = state.bytes +
|
|
206
|
+
const nextBytes = state.bytes + stat2.size;
|
|
194
207
|
if (nextFiles > MAX_SKILL_FILES || nextBytes > MAX_SKILL_BYTES) {
|
|
195
208
|
throw new Error("bundled skill package exceeds copy bounds");
|
|
196
209
|
}
|
|
@@ -200,7 +213,7 @@ function collectBundledSkillFilesBounded(sourceDir, state, relativeDir = "") {
|
|
|
200
213
|
}
|
|
201
214
|
return files;
|
|
202
215
|
}
|
|
203
|
-
function
|
|
216
|
+
async function rollbackCopiedFilesAsync(copiedFiles, destDir) {
|
|
204
217
|
const safeDestDir = path.resolve(destDir);
|
|
205
218
|
const dirs = new Set;
|
|
206
219
|
for (const copiedFile of copiedFiles) {
|
|
@@ -209,7 +222,7 @@ function rollbackCopiedFiles(copiedFiles, destDir) {
|
|
|
209
222
|
if (relative2.startsWith("..") || path.isAbsolute(relative2))
|
|
210
223
|
continue;
|
|
211
224
|
try {
|
|
212
|
-
|
|
225
|
+
await fsp.rm(resolvedFile, { force: true });
|
|
213
226
|
} catch {}
|
|
214
227
|
dirs.add(path.dirname(resolvedFile));
|
|
215
228
|
}
|
|
@@ -218,12 +231,12 @@ function rollbackCopiedFiles(copiedFiles, destDir) {
|
|
|
218
231
|
if (relative2.startsWith("..") || path.isAbsolute(relative2))
|
|
219
232
|
continue;
|
|
220
233
|
try {
|
|
221
|
-
|
|
234
|
+
await fsp.rmdir(dir);
|
|
222
235
|
} catch {}
|
|
223
236
|
}
|
|
224
237
|
}
|
|
225
|
-
function
|
|
226
|
-
const files =
|
|
238
|
+
async function copyBundledDirectoryBoundedAsync(sourceDir, destDir) {
|
|
239
|
+
const files = await collectBundledSkillFilesBoundedAsync(sourceDir, {
|
|
227
240
|
files: 0,
|
|
228
241
|
bytes: 0
|
|
229
242
|
});
|
|
@@ -232,9 +245,9 @@ function copyBundledDirectoryBounded(sourceDir, destDir) {
|
|
|
232
245
|
for (const file of files) {
|
|
233
246
|
const sourcePath = path.join(sourceDir, file.relativePath);
|
|
234
247
|
const destPath = path.join(destDir, file.relativePath);
|
|
235
|
-
|
|
248
|
+
await fsp.mkdir(path.dirname(destPath), { recursive: true });
|
|
236
249
|
try {
|
|
237
|
-
|
|
250
|
+
await fsp.copyFile(sourcePath, destPath, fs.constants.COPYFILE_EXCL);
|
|
238
251
|
copiedFiles.push(destPath);
|
|
239
252
|
} catch (err) {
|
|
240
253
|
if (err.code !== "EEXIST")
|
|
@@ -242,15 +255,11 @@ function copyBundledDirectoryBounded(sourceDir, destDir) {
|
|
|
242
255
|
}
|
|
243
256
|
}
|
|
244
257
|
} catch (err) {
|
|
245
|
-
|
|
258
|
+
await rollbackCopiedFilesAsync(copiedFiles, destDir);
|
|
246
259
|
throw err;
|
|
247
260
|
}
|
|
248
261
|
}
|
|
249
|
-
function
|
|
250
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
251
|
-
console.warn(`[opencode-swarm] Could not install bundled project skills; continuing without sync: ${message}`);
|
|
252
|
-
}
|
|
253
|
-
function syncBundledProjectSkillsIfMissing(projectDirectory, packageRoot, quiet = false) {
|
|
262
|
+
async function syncBundledProjectSkillsIfMissingAsync(projectDirectory, packageRoot, quiet = false) {
|
|
254
263
|
try {
|
|
255
264
|
const cacheKey = getSyncCacheKey(projectDirectory, packageRoot);
|
|
256
265
|
if (syncedProjectSkillTargets.has(cacheKey))
|
|
@@ -259,23 +268,23 @@ function syncBundledProjectSkillsIfMissing(projectDirectory, packageRoot, quiet
|
|
|
259
268
|
const opencodeDir = path.join(projectDirectory, ".opencode");
|
|
260
269
|
const skillsDir = path.join(opencodeDir, "skills");
|
|
261
270
|
let sawBundledSource = false;
|
|
262
|
-
if (!
|
|
271
|
+
if (!await ensureNotSymlinkedDirectoryAsync(opencodeDir))
|
|
263
272
|
return;
|
|
264
|
-
if (!
|
|
273
|
+
if (!await ensureNotSymlinkedDirectoryAsync(skillsDir))
|
|
265
274
|
return;
|
|
266
275
|
for (const slug of BUNDLED_PROJECT_SKILLS) {
|
|
267
276
|
const sourceDir = path.join(sourceRoot, slug);
|
|
268
277
|
const sourceSkill = path.join(sourceDir, "SKILL.md");
|
|
269
278
|
const destDir = path.join(skillsDir, slug);
|
|
270
279
|
const destSkill = path.join(destDir, "SKILL.md");
|
|
271
|
-
if (!
|
|
280
|
+
if (!await pathExistsAsync(sourceSkill))
|
|
272
281
|
continue;
|
|
273
282
|
sawBundledSource = true;
|
|
274
|
-
if (
|
|
283
|
+
if (await pathExistsAsync(destSkill))
|
|
275
284
|
continue;
|
|
276
|
-
if (!
|
|
285
|
+
if (!await ensureNotSymlinkedDirectoryAsync(destDir))
|
|
277
286
|
continue;
|
|
278
|
-
|
|
287
|
+
await copyBundledDirectoryBoundedAsync(sourceDir, destDir);
|
|
279
288
|
if (!quiet) {
|
|
280
289
|
console.warn(`[opencode-swarm] Installed bundled skill .opencode/skills/${slug}/SKILL.md for first-class /swarm command support`);
|
|
281
290
|
}
|
|
@@ -15027,21 +15036,21 @@ function hash2(content) {
|
|
|
15027
15036
|
return createHash("sha256").update(content, "utf-8").digest("hex");
|
|
15028
15037
|
}
|
|
15029
15038
|
function readTextBounded(absPath) {
|
|
15030
|
-
const
|
|
15031
|
-
if (!
|
|
15039
|
+
const stat3 = fs2.lstatSync(absPath);
|
|
15040
|
+
if (!stat3.isFile() || stat3.size > MAX_SOURCE_BYTES) {
|
|
15032
15041
|
return null;
|
|
15033
15042
|
}
|
|
15034
15043
|
return fs2.readFileSync(absPath, "utf-8");
|
|
15035
15044
|
}
|
|
15036
15045
|
function fileArtifact(root, absPath) {
|
|
15037
15046
|
try {
|
|
15038
|
-
const
|
|
15039
|
-
if (!
|
|
15047
|
+
const stat3 = fs2.lstatSync(absPath);
|
|
15048
|
+
if (!stat3.isFile() || stat3.size > MAX_SOURCE_BYTES)
|
|
15040
15049
|
return null;
|
|
15041
15050
|
return {
|
|
15042
15051
|
relPath: toPosix(path4.relative(root, absPath)),
|
|
15043
|
-
bytes:
|
|
15044
|
-
mtimeMs:
|
|
15052
|
+
bytes: stat3.size,
|
|
15053
|
+
mtimeMs: stat3.mtimeMs
|
|
15045
15054
|
};
|
|
15046
15055
|
} catch {
|
|
15047
15056
|
return null;
|
|
@@ -15332,14 +15341,14 @@ function readEffectiveSpecSync(directory) {
|
|
|
15332
15341
|
const root = path4.resolve(directory);
|
|
15333
15342
|
const swSpecPath = path4.join(root, SWARM_SPEC_REL);
|
|
15334
15343
|
try {
|
|
15335
|
-
const
|
|
15336
|
-
if (
|
|
15344
|
+
const stat3 = fs2.lstatSync(swSpecPath);
|
|
15345
|
+
if (stat3.isFile() && stat3.size <= MAX_SPEC_BYTES) {
|
|
15337
15346
|
const content = fs2.readFileSync(swSpecPath, "utf-8");
|
|
15338
15347
|
return {
|
|
15339
15348
|
source: "swarm",
|
|
15340
15349
|
content,
|
|
15341
15350
|
hash: hash2(content),
|
|
15342
|
-
mtime:
|
|
15351
|
+
mtime: stat3.mtime.toISOString(),
|
|
15343
15352
|
sourcePaths: [toPosix(SWARM_SPEC_REL)],
|
|
15344
15353
|
warnings: []
|
|
15345
15354
|
};
|
|
@@ -15878,9 +15887,9 @@ var init_ledger = __esm(() => {
|
|
|
15878
15887
|
|
|
15879
15888
|
// src/plan/manager.ts
|
|
15880
15889
|
import {
|
|
15881
|
-
copyFileSync
|
|
15882
|
-
existsSync as
|
|
15883
|
-
readdirSync as
|
|
15890
|
+
copyFileSync,
|
|
15891
|
+
existsSync as existsSync3,
|
|
15892
|
+
readdirSync as readdirSync2,
|
|
15884
15893
|
renameSync as renameSync3,
|
|
15885
15894
|
unlinkSync
|
|
15886
15895
|
} from "fs";
|
|
@@ -16324,7 +16333,7 @@ async function savePlan(directory, plan, options) {
|
|
|
16324
16333
|
const oldLedgerPath = path6.join(swarmDir2, "plan-ledger.jsonl");
|
|
16325
16334
|
const oldLedgerBackupPath = path6.join(swarmDir2, `plan-ledger.backup-${Date.now()}-${Math.floor(Math.random() * 1e9)}.jsonl`);
|
|
16326
16335
|
let backupExists = false;
|
|
16327
|
-
if (
|
|
16336
|
+
if (existsSync3(oldLedgerPath)) {
|
|
16328
16337
|
try {
|
|
16329
16338
|
renameSync3(oldLedgerPath, oldLedgerBackupPath);
|
|
16330
16339
|
backupExists = true;
|
|
@@ -16341,15 +16350,15 @@ async function savePlan(directory, plan, options) {
|
|
|
16341
16350
|
const errorMessage = String(initErr);
|
|
16342
16351
|
if (errorMessage.includes("already initialized")) {
|
|
16343
16352
|
try {
|
|
16344
|
-
if (
|
|
16353
|
+
if (existsSync3(oldLedgerBackupPath))
|
|
16345
16354
|
unlinkSync(oldLedgerBackupPath);
|
|
16346
16355
|
} catch {}
|
|
16347
16356
|
} else {
|
|
16348
|
-
if (
|
|
16357
|
+
if (existsSync3(oldLedgerBackupPath)) {
|
|
16349
16358
|
try {
|
|
16350
16359
|
renameSync3(oldLedgerBackupPath, oldLedgerPath);
|
|
16351
16360
|
} catch {
|
|
16352
|
-
|
|
16361
|
+
copyFileSync(oldLedgerBackupPath, oldLedgerPath);
|
|
16353
16362
|
try {
|
|
16354
16363
|
unlinkSync(oldLedgerBackupPath);
|
|
16355
16364
|
} catch {}
|
|
@@ -16367,19 +16376,19 @@ async function savePlan(directory, plan, options) {
|
|
|
16367
16376
|
} catch (renameErr) {
|
|
16368
16377
|
warn(`[savePlan] Could not archive old ledger (rename failed: ${renameErr instanceof Error ? renameErr.message : String(renameErr)}). Old ledger may still exist at ${oldLedgerBackupPath}.`);
|
|
16369
16378
|
try {
|
|
16370
|
-
if (
|
|
16379
|
+
if (existsSync3(oldLedgerBackupPath))
|
|
16371
16380
|
unlinkSync(oldLedgerBackupPath);
|
|
16372
16381
|
} catch {}
|
|
16373
16382
|
}
|
|
16374
16383
|
} else if (!initSucceeded && backupExists) {
|
|
16375
16384
|
try {
|
|
16376
|
-
if (
|
|
16385
|
+
if (existsSync3(oldLedgerBackupPath))
|
|
16377
16386
|
unlinkSync(oldLedgerBackupPath);
|
|
16378
16387
|
} catch {}
|
|
16379
16388
|
}
|
|
16380
16389
|
const MAX_ARCHIVED_SIBLINGS = 5;
|
|
16381
16390
|
try {
|
|
16382
|
-
const allFiles =
|
|
16391
|
+
const allFiles = readdirSync2(swarmDir2);
|
|
16383
16392
|
const archivedSiblings = allFiles.filter((f) => f.startsWith("plan-ledger.archived-") && f.endsWith(".jsonl")).sort();
|
|
16384
16393
|
if (archivedSiblings.length > MAX_ARCHIVED_SIBLINGS) {
|
|
16385
16394
|
const toRemove = archivedSiblings.slice(0, archivedSiblings.length - MAX_ARCHIVED_SIBLINGS);
|
|
@@ -19203,11 +19212,11 @@ function handleAgentsCommand(agents, guardrails) {
|
|
|
19203
19212
|
const temp = agent.config.temperature !== undefined ? agent.config.temperature.toString() : "default";
|
|
19204
19213
|
const tools = agent.config.tools || {};
|
|
19205
19214
|
const isReadOnly = tools.write === false || tools.edit === false;
|
|
19206
|
-
const
|
|
19215
|
+
const access3 = isReadOnly ? "\uD83D\uDD12 read-only" : "\u270F\uFE0F read-write";
|
|
19207
19216
|
const desc = agent.description || agent.config.description || "";
|
|
19208
19217
|
const hasCustomProfile = guardrails?.profiles?.[key] !== undefined;
|
|
19209
19218
|
const profileIndicator = hasCustomProfile ? " | \u26A1 custom limits" : "";
|
|
19210
|
-
lines.push(`- **${key}** | model: \`${model}\` | temp: ${temp} | ${
|
|
19219
|
+
lines.push(`- **${key}** | model: \`${model}\` | temp: ${temp} | ${access3}${profileIndicator}`);
|
|
19211
19220
|
if (desc) {
|
|
19212
19221
|
lines.push(` ${desc}`);
|
|
19213
19222
|
}
|
|
@@ -20252,8 +20261,8 @@ GFS4: `);
|
|
|
20252
20261
|
}
|
|
20253
20262
|
var fs$copyFile = fs6.copyFile;
|
|
20254
20263
|
if (fs$copyFile)
|
|
20255
|
-
fs6.copyFile =
|
|
20256
|
-
function
|
|
20264
|
+
fs6.copyFile = copyFile2;
|
|
20265
|
+
function copyFile2(src, dest, flags, cb) {
|
|
20257
20266
|
if (typeof flags === "function") {
|
|
20258
20267
|
cb = flags;
|
|
20259
20268
|
flags = 0;
|
|
@@ -20271,9 +20280,9 @@ GFS4: `);
|
|
|
20271
20280
|
}
|
|
20272
20281
|
}
|
|
20273
20282
|
var fs$readdir = fs6.readdir;
|
|
20274
|
-
fs6.readdir =
|
|
20283
|
+
fs6.readdir = readdir2;
|
|
20275
20284
|
var noReaddirOptionVersions = /^v[0-5]\./;
|
|
20276
|
-
function
|
|
20285
|
+
function readdir2(path8, options, cb) {
|
|
20277
20286
|
if (typeof options === "function")
|
|
20278
20287
|
cb = options, options = null;
|
|
20279
20288
|
var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path9, options2, cb2, startTime) {
|
|
@@ -20862,11 +20871,11 @@ var require_mtime_precision = __commonJS((exports, module) => {
|
|
|
20862
20871
|
function probe(file2, fs5, callback) {
|
|
20863
20872
|
const cachedPrecision = fs5[cacheSymbol];
|
|
20864
20873
|
if (cachedPrecision) {
|
|
20865
|
-
return fs5.stat(file2, (err,
|
|
20874
|
+
return fs5.stat(file2, (err, stat3) => {
|
|
20866
20875
|
if (err) {
|
|
20867
20876
|
return callback(err);
|
|
20868
20877
|
}
|
|
20869
|
-
callback(null,
|
|
20878
|
+
callback(null, stat3.mtime, cachedPrecision);
|
|
20870
20879
|
});
|
|
20871
20880
|
}
|
|
20872
20881
|
const mtime = new Date(Math.ceil(Date.now() / 1000) * 1000 + 5);
|
|
@@ -20874,13 +20883,13 @@ var require_mtime_precision = __commonJS((exports, module) => {
|
|
|
20874
20883
|
if (err) {
|
|
20875
20884
|
return callback(err);
|
|
20876
20885
|
}
|
|
20877
|
-
fs5.stat(file2, (err2,
|
|
20886
|
+
fs5.stat(file2, (err2, stat3) => {
|
|
20878
20887
|
if (err2) {
|
|
20879
20888
|
return callback(err2);
|
|
20880
20889
|
}
|
|
20881
|
-
const precision =
|
|
20890
|
+
const precision = stat3.mtime.getTime() % 1000 === 0 ? "s" : "ms";
|
|
20882
20891
|
Object.defineProperty(fs5, cacheSymbol, { value: precision });
|
|
20883
|
-
callback(null,
|
|
20892
|
+
callback(null, stat3.mtime, precision);
|
|
20884
20893
|
});
|
|
20885
20894
|
});
|
|
20886
20895
|
}
|
|
@@ -20930,14 +20939,14 @@ var require_lockfile = __commonJS((exports, module) => {
|
|
|
20930
20939
|
if (options.stale <= 0) {
|
|
20931
20940
|
return callback(Object.assign(new Error("Lock file is already being held"), { code: "ELOCKED", file: file2 }));
|
|
20932
20941
|
}
|
|
20933
|
-
options.fs.stat(lockfilePath, (err2,
|
|
20942
|
+
options.fs.stat(lockfilePath, (err2, stat3) => {
|
|
20934
20943
|
if (err2) {
|
|
20935
20944
|
if (err2.code === "ENOENT") {
|
|
20936
20945
|
return acquireLock(file2, { ...options, stale: 0 }, callback);
|
|
20937
20946
|
}
|
|
20938
20947
|
return callback(err2);
|
|
20939
20948
|
}
|
|
20940
|
-
if (!isLockStale(
|
|
20949
|
+
if (!isLockStale(stat3, options)) {
|
|
20941
20950
|
return callback(Object.assign(new Error("Lock file is already being held"), { code: "ELOCKED", file: file2 }));
|
|
20942
20951
|
}
|
|
20943
20952
|
removeLock(file2, options, (err3) => {
|
|
@@ -20949,8 +20958,8 @@ var require_lockfile = __commonJS((exports, module) => {
|
|
|
20949
20958
|
});
|
|
20950
20959
|
});
|
|
20951
20960
|
}
|
|
20952
|
-
function isLockStale(
|
|
20953
|
-
return
|
|
20961
|
+
function isLockStale(stat3, options) {
|
|
20962
|
+
return stat3.mtime.getTime() < Date.now() - options.stale;
|
|
20954
20963
|
}
|
|
20955
20964
|
function removeLock(file2, options, callback) {
|
|
20956
20965
|
options.fs.rmdir(getLockFile(file2, options), (err) => {
|
|
@@ -20968,7 +20977,7 @@ var require_lockfile = __commonJS((exports, module) => {
|
|
|
20968
20977
|
lock2.updateDelay = lock2.updateDelay || options.update;
|
|
20969
20978
|
lock2.updateTimeout = setTimeout(() => {
|
|
20970
20979
|
lock2.updateTimeout = null;
|
|
20971
|
-
options.fs.stat(lock2.lockfilePath, (err,
|
|
20980
|
+
options.fs.stat(lock2.lockfilePath, (err, stat3) => {
|
|
20972
20981
|
const isOverThreshold = lock2.lastUpdate + options.stale < Date.now();
|
|
20973
20982
|
if (err) {
|
|
20974
20983
|
if (err.code === "ENOENT" || isOverThreshold) {
|
|
@@ -20977,7 +20986,7 @@ var require_lockfile = __commonJS((exports, module) => {
|
|
|
20977
20986
|
lock2.updateDelay = 1000;
|
|
20978
20987
|
return updateLock(file2, options);
|
|
20979
20988
|
}
|
|
20980
|
-
const isMtimeOurs = lock2.mtime.getTime() ===
|
|
20989
|
+
const isMtimeOurs = lock2.mtime.getTime() === stat3.mtime.getTime();
|
|
20981
20990
|
if (!isMtimeOurs) {
|
|
20982
20991
|
return setLockAsCompromised(file2, lock2, Object.assign(new Error("Unable to update lock within the stale threshold"), { code: "ECOMPROMISED" }));
|
|
20983
20992
|
}
|
|
@@ -21095,11 +21104,11 @@ var require_lockfile = __commonJS((exports, module) => {
|
|
|
21095
21104
|
if (err) {
|
|
21096
21105
|
return callback(err);
|
|
21097
21106
|
}
|
|
21098
|
-
options.fs.stat(getLockFile(file3, options), (err2,
|
|
21107
|
+
options.fs.stat(getLockFile(file3, options), (err2, stat3) => {
|
|
21099
21108
|
if (err2) {
|
|
21100
21109
|
return err2.code === "ENOENT" ? callback(null, false) : callback(err2);
|
|
21101
21110
|
}
|
|
21102
|
-
return callback(null, !isLockStale(
|
|
21111
|
+
return callback(null, !isLockStale(stat3, options));
|
|
21103
21112
|
});
|
|
21104
21113
|
});
|
|
21105
21114
|
}
|
|
@@ -21407,11 +21416,11 @@ var init_task_id = __esm(() => {
|
|
|
21407
21416
|
|
|
21408
21417
|
// src/evidence/manager.ts
|
|
21409
21418
|
import {
|
|
21410
|
-
mkdirSync as
|
|
21411
|
-
readdirSync as
|
|
21419
|
+
mkdirSync as mkdirSync4,
|
|
21420
|
+
readdirSync as readdirSync4,
|
|
21412
21421
|
realpathSync,
|
|
21413
|
-
rmSync
|
|
21414
|
-
statSync as
|
|
21422
|
+
rmSync,
|
|
21423
|
+
statSync as statSync4
|
|
21415
21424
|
} from "fs";
|
|
21416
21425
|
import * as fs6 from "fs/promises";
|
|
21417
21426
|
import * as path9 from "path";
|
|
@@ -21437,11 +21446,11 @@ function validateProjectRoot(directory) {
|
|
|
21437
21446
|
break;
|
|
21438
21447
|
const parentSwarm = path9.join(parent, ".swarm");
|
|
21439
21448
|
try {
|
|
21440
|
-
if (
|
|
21449
|
+
if (statSync4(parentSwarm).isDirectory()) {
|
|
21441
21450
|
let hasProjectIndicator = false;
|
|
21442
21451
|
for (const indicator of PROJECT_INDICATORS) {
|
|
21443
21452
|
try {
|
|
21444
|
-
const indicatorStat =
|
|
21453
|
+
const indicatorStat = statSync4(path9.join(parent, indicator));
|
|
21445
21454
|
if (indicatorStat.isFile() || indicatorStat.isDirectory()) {
|
|
21446
21455
|
hasProjectIndicator = true;
|
|
21447
21456
|
break;
|
|
@@ -21515,14 +21524,14 @@ async function saveEvidence(directory, taskId, evidence) {
|
|
|
21515
21524
|
if (bundleJson.length > EVIDENCE_MAX_JSON_BYTES) {
|
|
21516
21525
|
throw new Error(`Evidence bundle size (${bundleJson.length} bytes) exceeds maximum (${EVIDENCE_MAX_JSON_BYTES} bytes)`);
|
|
21517
21526
|
}
|
|
21518
|
-
|
|
21527
|
+
mkdirSync4(evidenceDir, { recursive: true });
|
|
21519
21528
|
const tempPath = path9.join(evidenceDir, `evidence.json.tmp.${Date.now()}.${process.pid}`);
|
|
21520
21529
|
try {
|
|
21521
21530
|
await bunWrite(tempPath, bundleJson);
|
|
21522
21531
|
await fs6.rename(tempPath, evidencePath);
|
|
21523
21532
|
} catch (error49) {
|
|
21524
21533
|
try {
|
|
21525
|
-
|
|
21534
|
+
rmSync(tempPath, { force: true });
|
|
21526
21535
|
} catch {}
|
|
21527
21536
|
throw error49;
|
|
21528
21537
|
}
|
|
@@ -21581,7 +21590,7 @@ async function loadEvidence(directory, taskId) {
|
|
|
21581
21590
|
await fs6.rename(tempPath, evidencePath);
|
|
21582
21591
|
} catch (writeError) {
|
|
21583
21592
|
try {
|
|
21584
|
-
|
|
21593
|
+
rmSync(tempPath, { force: true });
|
|
21585
21594
|
} catch {}
|
|
21586
21595
|
warn(`Failed to persist repaired flat retrospective for task ${sanitizedTaskId}: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
|
|
21587
21596
|
}
|
|
@@ -21608,13 +21617,13 @@ async function loadEvidence(directory, taskId) {
|
|
|
21608
21617
|
async function listEvidenceTaskIds(directory) {
|
|
21609
21618
|
const evidenceBasePath = validateSwarmPath(directory, "evidence");
|
|
21610
21619
|
try {
|
|
21611
|
-
|
|
21620
|
+
statSync4(evidenceBasePath);
|
|
21612
21621
|
} catch {
|
|
21613
21622
|
return [];
|
|
21614
21623
|
}
|
|
21615
21624
|
let entries;
|
|
21616
21625
|
try {
|
|
21617
|
-
entries =
|
|
21626
|
+
entries = readdirSync4(evidenceBasePath);
|
|
21618
21627
|
} catch {
|
|
21619
21628
|
return [];
|
|
21620
21629
|
}
|
|
@@ -21622,7 +21631,7 @@ async function listEvidenceTaskIds(directory) {
|
|
|
21622
21631
|
for (const entry of entries) {
|
|
21623
21632
|
const entryPath = path9.join(evidenceBasePath, entry);
|
|
21624
21633
|
try {
|
|
21625
|
-
const stats =
|
|
21634
|
+
const stats = statSync4(entryPath);
|
|
21626
21635
|
if (!stats.isDirectory()) {
|
|
21627
21636
|
continue;
|
|
21628
21637
|
}
|
|
@@ -21641,12 +21650,12 @@ async function deleteEvidence(directory, taskId) {
|
|
|
21641
21650
|
const relativePath = path9.join("evidence", sanitizedTaskId);
|
|
21642
21651
|
const evidenceDir = validateSwarmPath(directory, relativePath);
|
|
21643
21652
|
try {
|
|
21644
|
-
|
|
21653
|
+
statSync4(evidenceDir);
|
|
21645
21654
|
} catch {
|
|
21646
21655
|
return false;
|
|
21647
21656
|
}
|
|
21648
21657
|
try {
|
|
21649
|
-
|
|
21658
|
+
rmSync(evidenceDir, { recursive: true, force: true });
|
|
21650
21659
|
return true;
|
|
21651
21660
|
} catch (error49) {
|
|
21652
21661
|
warn(`Failed to delete evidence for task ${sanitizedTaskId}: ${error49 instanceof Error ? error49.message : String(error49)}`);
|
|
@@ -21832,7 +21841,7 @@ var init_archive = __esm(() => {
|
|
|
21832
21841
|
});
|
|
21833
21842
|
|
|
21834
21843
|
// src/db/project-db.ts
|
|
21835
|
-
import { existsSync as
|
|
21844
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync5 } from "fs";
|
|
21836
21845
|
import { createRequire } from "module";
|
|
21837
21846
|
import { join as join9, resolve as resolve7 } from "path";
|
|
21838
21847
|
function loadDatabaseCtor() {
|
|
@@ -21867,7 +21876,7 @@ function projectDbPath(directory) {
|
|
|
21867
21876
|
return join9(resolve7(directory), ".swarm", "swarm.db");
|
|
21868
21877
|
}
|
|
21869
21878
|
function projectDbExists(directory) {
|
|
21870
|
-
return
|
|
21879
|
+
return existsSync6(projectDbPath(directory));
|
|
21871
21880
|
}
|
|
21872
21881
|
function getProjectDb(directory) {
|
|
21873
21882
|
const key = resolve7(directory);
|
|
@@ -21875,7 +21884,7 @@ function getProjectDb(directory) {
|
|
|
21875
21884
|
if (existing)
|
|
21876
21885
|
return existing;
|
|
21877
21886
|
const swarmDir = join9(key, ".swarm");
|
|
21878
|
-
|
|
21887
|
+
mkdirSync5(swarmDir, { recursive: true });
|
|
21879
21888
|
const Db = loadDatabaseCtor();
|
|
21880
21889
|
const db = new Db(join9(swarmDir, "swarm.db"));
|
|
21881
21890
|
db.run("PRAGMA journal_mode = WAL;");
|
|
@@ -37416,6 +37425,14 @@ var init_branch = __esm(() => {
|
|
|
37416
37425
|
};
|
|
37417
37426
|
});
|
|
37418
37427
|
|
|
37428
|
+
// src/hooks/abort-utils.ts
|
|
37429
|
+
function isAbortError(err) {
|
|
37430
|
+
if (typeof err !== "object" || err === null)
|
|
37431
|
+
return false;
|
|
37432
|
+
const name = err.name;
|
|
37433
|
+
return name === "AbortError" || name === "TimeoutError";
|
|
37434
|
+
}
|
|
37435
|
+
|
|
37419
37436
|
// src/hooks/curator-llm-factory.ts
|
|
37420
37437
|
function resolveCuratorAgentName(mode, sessionId) {
|
|
37421
37438
|
const suffixMap = {
|
|
@@ -37484,13 +37501,19 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
|
|
|
37484
37501
|
}
|
|
37485
37502
|
};
|
|
37486
37503
|
if (signal?.aborted) {
|
|
37487
|
-
cleanup();
|
|
37488
37504
|
throw new Error("CURATOR_LLM_TIMEOUT");
|
|
37489
37505
|
}
|
|
37490
|
-
signal
|
|
37506
|
+
const sdkOpts = signal ? { signal } : {};
|
|
37491
37507
|
try {
|
|
37492
37508
|
const createResult = await client.session.create({
|
|
37493
|
-
|
|
37509
|
+
...sessionId ? {
|
|
37510
|
+
body: {
|
|
37511
|
+
parentID: sessionId,
|
|
37512
|
+
title: `curator_${mode} background`
|
|
37513
|
+
}
|
|
37514
|
+
} : {},
|
|
37515
|
+
query: { directory },
|
|
37516
|
+
...sdkOpts
|
|
37494
37517
|
});
|
|
37495
37518
|
if (!createResult.data) {
|
|
37496
37519
|
throw new Error(`Failed to create curator session: ${JSON.stringify(createResult.error)}`);
|
|
@@ -37500,30 +37523,27 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
|
|
|
37500
37523
|
throw new Error("CURATOR_LLM_TIMEOUT");
|
|
37501
37524
|
}
|
|
37502
37525
|
const agentName = resolveCuratorAgentName(mode, sessionId);
|
|
37503
|
-
|
|
37504
|
-
|
|
37505
|
-
|
|
37506
|
-
|
|
37507
|
-
|
|
37508
|
-
|
|
37509
|
-
|
|
37510
|
-
|
|
37511
|
-
|
|
37512
|
-
});
|
|
37513
|
-
} catch (promptErr) {
|
|
37514
|
-
if (signal?.aborted) {
|
|
37515
|
-
throw new Error("CURATOR_LLM_TIMEOUT");
|
|
37516
|
-
}
|
|
37517
|
-
throw promptErr;
|
|
37518
|
-
}
|
|
37526
|
+
const promptResult = await client.session.prompt({
|
|
37527
|
+
path: { id: ephemeralSessionId },
|
|
37528
|
+
body: {
|
|
37529
|
+
agent: agentName,
|
|
37530
|
+
tools: { write: false, edit: false, patch: false },
|
|
37531
|
+
parts: [{ type: "text", text: userInput }]
|
|
37532
|
+
},
|
|
37533
|
+
...sdkOpts
|
|
37534
|
+
});
|
|
37519
37535
|
if (!promptResult.data) {
|
|
37520
37536
|
throw new Error(`Curator LLM prompt failed: ${JSON.stringify(promptResult.error)}`);
|
|
37521
37537
|
}
|
|
37522
37538
|
const textParts = promptResult.data.parts.filter((p) => p.type === "text");
|
|
37523
37539
|
return textParts.map((p) => p.text).join(`
|
|
37524
37540
|
`);
|
|
37541
|
+
} catch (err) {
|
|
37542
|
+
if (isAbortError(err)) {
|
|
37543
|
+
throw new Error("CURATOR_LLM_TIMEOUT");
|
|
37544
|
+
}
|
|
37545
|
+
throw err;
|
|
37525
37546
|
} finally {
|
|
37526
|
-
signal?.removeEventListener("abort", cleanup);
|
|
37527
37547
|
cleanup();
|
|
37528
37548
|
}
|
|
37529
37549
|
};
|
|
@@ -37633,8 +37653,8 @@ var init_task_file = __esm(() => {
|
|
|
37633
37653
|
});
|
|
37634
37654
|
|
|
37635
37655
|
// src/hooks/knowledge-events.ts
|
|
37636
|
-
import { existsSync as
|
|
37637
|
-
import { appendFile as appendFile2, mkdir as
|
|
37656
|
+
import { existsSync as existsSync8 } from "fs";
|
|
37657
|
+
import { appendFile as appendFile2, mkdir as mkdir3, readFile as readFile2, stat as stat3 } from "fs/promises";
|
|
37638
37658
|
import * as path13 from "path";
|
|
37639
37659
|
function resolveKnowledgeEventsPath(directory) {
|
|
37640
37660
|
return path13.join(directory, ".swarm", "knowledge-events.jsonl");
|
|
@@ -37647,7 +37667,7 @@ function resolveLegacyApplicationLogPath(directory) {
|
|
|
37647
37667
|
}
|
|
37648
37668
|
async function readKnowledgeEvents(directory) {
|
|
37649
37669
|
const filePath = resolveKnowledgeEventsPath(directory);
|
|
37650
|
-
if (!
|
|
37670
|
+
if (!existsSync8(filePath))
|
|
37651
37671
|
return [];
|
|
37652
37672
|
const content = await readFile2(filePath, "utf-8");
|
|
37653
37673
|
return parseEventLines(content.split(`
|
|
@@ -37655,7 +37675,7 @@ async function readKnowledgeEvents(directory) {
|
|
|
37655
37675
|
}
|
|
37656
37676
|
async function readLegacyApplicationRecords(directory) {
|
|
37657
37677
|
const filePath = resolveLegacyApplicationLogPath(directory);
|
|
37658
|
-
if (!
|
|
37678
|
+
if (!existsSync8(filePath))
|
|
37659
37679
|
return [];
|
|
37660
37680
|
const content = await readFile2(filePath, "utf-8");
|
|
37661
37681
|
const out = [];
|
|
@@ -37725,7 +37745,7 @@ function maxIso(current, candidate) {
|
|
|
37725
37745
|
}
|
|
37726
37746
|
async function readCounterBaseline(directory) {
|
|
37727
37747
|
const filePath = resolveKnowledgeCounterBaselinePath(directory);
|
|
37728
|
-
if (!
|
|
37748
|
+
if (!existsSync8(filePath))
|
|
37729
37749
|
return new Map;
|
|
37730
37750
|
const raw = JSON.parse(await readFile2(filePath, "utf-8"));
|
|
37731
37751
|
const map3 = new Map;
|
|
@@ -37736,7 +37756,7 @@ async function readCounterBaseline(directory) {
|
|
|
37736
37756
|
}
|
|
37737
37757
|
async function statCacheKey(filePath) {
|
|
37738
37758
|
try {
|
|
37739
|
-
const fileStat = await
|
|
37759
|
+
const fileStat = await stat3(filePath);
|
|
37740
37760
|
return `${fileStat.mtimeMs}:${fileStat.ctimeMs}:${fileStat.size}`;
|
|
37741
37761
|
} catch (err) {
|
|
37742
37762
|
if (err?.code === "ENOENT")
|
|
@@ -37921,8 +37941,8 @@ var init_knowledge_events = __esm(() => {
|
|
|
37921
37941
|
});
|
|
37922
37942
|
|
|
37923
37943
|
// src/hooks/knowledge-store.ts
|
|
37924
|
-
import { existsSync as
|
|
37925
|
-
import { appendFile as appendFile3, mkdir as
|
|
37944
|
+
import { existsSync as existsSync9 } from "fs";
|
|
37945
|
+
import { appendFile as appendFile3, mkdir as mkdir4, readFile as readFile3 } from "fs/promises";
|
|
37926
37946
|
import * as os4 from "os";
|
|
37927
37947
|
import * as path14 from "path";
|
|
37928
37948
|
function resolveSwarmKnowledgePath(directory) {
|
|
@@ -37952,7 +37972,7 @@ function resolveHiveRejectedPath() {
|
|
|
37952
37972
|
return path14.join(path14.dirname(hivePath), "shared-learnings-rejected.jsonl");
|
|
37953
37973
|
}
|
|
37954
37974
|
async function readKnowledge(filePath) {
|
|
37955
|
-
if (!
|
|
37975
|
+
if (!existsSync9(filePath))
|
|
37956
37976
|
return [];
|
|
37957
37977
|
const content = await readFile3(filePath, "utf-8");
|
|
37958
37978
|
const results = [];
|
|
@@ -38047,7 +38067,7 @@ async function appendRetractionRecord(directory, record3) {
|
|
|
38047
38067
|
}
|
|
38048
38068
|
async function appendKnowledge(filePath, entry) {
|
|
38049
38069
|
const dir = path14.dirname(filePath);
|
|
38050
|
-
await
|
|
38070
|
+
await mkdir4(dir, { recursive: true });
|
|
38051
38071
|
let release = null;
|
|
38052
38072
|
try {
|
|
38053
38073
|
release = await import_proper_lockfile4.default.lock(dir, {
|
|
@@ -38066,7 +38086,7 @@ async function appendKnowledge(filePath, entry) {
|
|
|
38066
38086
|
}
|
|
38067
38087
|
async function rewriteKnowledge(filePath, entries) {
|
|
38068
38088
|
const dir = path14.dirname(filePath);
|
|
38069
|
-
await
|
|
38089
|
+
await mkdir4(dir, { recursive: true });
|
|
38070
38090
|
let release = null;
|
|
38071
38091
|
try {
|
|
38072
38092
|
release = await import_proper_lockfile4.default.lock(dir, {
|
|
@@ -38088,7 +38108,7 @@ async function rewriteKnowledge(filePath, entries) {
|
|
|
38088
38108
|
async function transactFile(filePath, read, write, mutate) {
|
|
38089
38109
|
const dir = path14.dirname(filePath);
|
|
38090
38110
|
try {
|
|
38091
|
-
await
|
|
38111
|
+
await mkdir4(dir, { recursive: true });
|
|
38092
38112
|
} catch {
|
|
38093
38113
|
return false;
|
|
38094
38114
|
}
|
|
@@ -38279,7 +38299,7 @@ async function applyConfidenceDeltas(filePath, deltas) {
|
|
|
38279
38299
|
let release = null;
|
|
38280
38300
|
try {
|
|
38281
38301
|
const dir = path14.dirname(filePath);
|
|
38282
|
-
await
|
|
38302
|
+
await mkdir4(dir, { recursive: true });
|
|
38283
38303
|
release = await import_proper_lockfile4.default.lock(dir, {
|
|
38284
38304
|
retries: { retries: 5, minTimeout: 100, maxTimeout: 500 },
|
|
38285
38305
|
stale: 5000
|
|
@@ -38737,7 +38757,7 @@ var init_learning_metrics = __esm(() => {
|
|
|
38737
38757
|
});
|
|
38738
38758
|
|
|
38739
38759
|
// src/hooks/knowledge-validator.ts
|
|
38740
|
-
import { appendFile as appendFile4, mkdir as
|
|
38760
|
+
import { appendFile as appendFile4, mkdir as mkdir5 } from "fs/promises";
|
|
38741
38761
|
import * as path15 from "path";
|
|
38742
38762
|
function normalizeText(text) {
|
|
38743
38763
|
return text.normalize("NFKC").toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -39008,7 +39028,7 @@ function resolveUnactionablePath(directory) {
|
|
|
39008
39028
|
async function appendUnactionable(directory, entry, reason) {
|
|
39009
39029
|
const filePath = resolveUnactionablePath(directory);
|
|
39010
39030
|
const dirPath = path15.dirname(filePath);
|
|
39011
|
-
await
|
|
39031
|
+
await mkdir5(dirPath, { recursive: true });
|
|
39012
39032
|
await transactKnowledge(filePath, (existing) => {
|
|
39013
39033
|
const record3 = {
|
|
39014
39034
|
...entry,
|
|
@@ -39045,7 +39065,7 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
39045
39065
|
const quarantinePath = path15.join(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
39046
39066
|
const rejectedPath = path15.join(directory, ".swarm", "knowledge-rejected.jsonl");
|
|
39047
39067
|
const swarmDir = path15.join(directory, ".swarm");
|
|
39048
|
-
await
|
|
39068
|
+
await mkdir5(swarmDir, { recursive: true });
|
|
39049
39069
|
let release;
|
|
39050
39070
|
try {
|
|
39051
39071
|
release = await import_proper_lockfile5.default.lock(swarmDir, {
|
|
@@ -39109,7 +39129,7 @@ async function restoreEntry(directory, entryId) {
|
|
|
39109
39129
|
const quarantinePath = path15.join(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
39110
39130
|
const rejectedPath = path15.join(directory, ".swarm", "knowledge-rejected.jsonl");
|
|
39111
39131
|
const swarmDir = path15.join(directory, ".swarm");
|
|
39112
|
-
await
|
|
39132
|
+
await mkdir5(swarmDir, { recursive: true });
|
|
39113
39133
|
let release;
|
|
39114
39134
|
try {
|
|
39115
39135
|
release = await import_proper_lockfile5.default.lock(swarmDir, {
|
|
@@ -39287,7 +39307,7 @@ var init_knowledge_validator = __esm(() => {
|
|
|
39287
39307
|
});
|
|
39288
39308
|
|
|
39289
39309
|
// src/services/skill-changelog.ts
|
|
39290
|
-
import { appendFile as appendFile5, mkdir as
|
|
39310
|
+
import { appendFile as appendFile5, mkdir as mkdir6, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
|
|
39291
39311
|
import * as path16 from "path";
|
|
39292
39312
|
function resolveSkillChangelogPath(directory, slug) {
|
|
39293
39313
|
if (slug.includes("..") || slug.includes("/") || slug.includes("\\")) {
|
|
@@ -39298,7 +39318,7 @@ function resolveSkillChangelogPath(directory, slug) {
|
|
|
39298
39318
|
async function appendSkillChangelog(directory, slug, entry) {
|
|
39299
39319
|
const filePath = resolveSkillChangelogPath(directory, slug);
|
|
39300
39320
|
const dirPath = path16.dirname(filePath);
|
|
39301
|
-
await
|
|
39321
|
+
await mkdir6(dirPath, { recursive: true });
|
|
39302
39322
|
await appendFile5(filePath, `${JSON.stringify(entry)}
|
|
39303
39323
|
`, "utf-8");
|
|
39304
39324
|
try {
|
|
@@ -39321,8 +39341,8 @@ var init_skill_changelog = __esm(() => {
|
|
|
39321
39341
|
});
|
|
39322
39342
|
|
|
39323
39343
|
// src/services/skill-generator.ts
|
|
39324
|
-
import { existsSync as
|
|
39325
|
-
import { mkdir as
|
|
39344
|
+
import { existsSync as existsSync10, unlinkSync as unlinkSync5 } from "fs";
|
|
39345
|
+
import { mkdir as mkdir7, readFile as readFile5, rename as rename3, writeFile as writeFile4 } from "fs/promises";
|
|
39326
39346
|
import * as path17 from "path";
|
|
39327
39347
|
function sanitizeSlug(input) {
|
|
39328
39348
|
const lc = input.toLowerCase().trim();
|
|
@@ -39345,7 +39365,7 @@ function activeRepoRelativePath(slug) {
|
|
|
39345
39365
|
async function selectCandidateEntries(directory, opts) {
|
|
39346
39366
|
const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
39347
39367
|
const hivePath = resolveHiveKnowledgePath();
|
|
39348
|
-
const hive =
|
|
39368
|
+
const hive = existsSync10(hivePath) ? await readKnowledge(hivePath) : [];
|
|
39349
39369
|
const all = [...swarm, ...hive];
|
|
39350
39370
|
const counterRollups = await readKnowledgeCounterRollups(directory);
|
|
39351
39371
|
const selected = [];
|
|
@@ -39546,7 +39566,7 @@ function escapeMarkdown(s) {
|
|
|
39546
39566
|
return s.replace(/[\r\n]+/g, " ").slice(0, 280);
|
|
39547
39567
|
}
|
|
39548
39568
|
async function atomicWrite(p, content) {
|
|
39549
|
-
await
|
|
39569
|
+
await mkdir7(path17.dirname(p), { recursive: true });
|
|
39550
39570
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
39551
39571
|
await writeFile4(tmp, content, "utf-8");
|
|
39552
39572
|
await rename3(tmp, p);
|
|
@@ -39563,7 +39583,7 @@ async function generateSkills(req) {
|
|
|
39563
39583
|
const idSet = new Set(req.sourceKnowledgeIds);
|
|
39564
39584
|
const swarm = await readKnowledge(resolveSwarmKnowledgePath(req.directory));
|
|
39565
39585
|
const hivePath = resolveHiveKnowledgePath();
|
|
39566
|
-
const hive =
|
|
39586
|
+
const hive = existsSync10(hivePath) ? await readKnowledge(hivePath) : [];
|
|
39567
39587
|
pool = [...swarm, ...hive].filter((e) => idSet.has(e.id) && e.status !== "archived");
|
|
39568
39588
|
} else {
|
|
39569
39589
|
pool = candidates;
|
|
@@ -39600,7 +39620,7 @@ async function generateSkills(req) {
|
|
|
39600
39620
|
continue;
|
|
39601
39621
|
}
|
|
39602
39622
|
let preserved = false;
|
|
39603
|
-
if (req.mode === "active" &&
|
|
39623
|
+
if (req.mode === "active" && existsSync10(targetPath) && !req.force) {
|
|
39604
39624
|
const existing = await readFile5(targetPath, "utf-8");
|
|
39605
39625
|
if (!existing.includes("generated by opencode-swarm skill-generator")) {
|
|
39606
39626
|
preserved = true;
|
|
@@ -39645,7 +39665,7 @@ async function stampSourceEntries(directory, slug, ids) {
|
|
|
39645
39665
|
if (touched)
|
|
39646
39666
|
await rewriteKnowledge(swarmPath, swarm);
|
|
39647
39667
|
const hivePath = resolveHiveKnowledgePath();
|
|
39648
|
-
if (!
|
|
39668
|
+
if (!existsSync10(hivePath))
|
|
39649
39669
|
return;
|
|
39650
39670
|
const hive = await readKnowledge(hivePath);
|
|
39651
39671
|
let touchedHive = false;
|
|
@@ -39743,7 +39763,7 @@ async function activateProposal(directory, slug, force = false) {
|
|
|
39743
39763
|
}
|
|
39744
39764
|
const from = proposalPath(directory, cleanSlug);
|
|
39745
39765
|
const to = activePath(directory, cleanSlug);
|
|
39746
|
-
if (!
|
|
39766
|
+
if (!existsSync10(from)) {
|
|
39747
39767
|
return {
|
|
39748
39768
|
activated: false,
|
|
39749
39769
|
from,
|
|
@@ -39751,7 +39771,7 @@ async function activateProposal(directory, slug, force = false) {
|
|
|
39751
39771
|
reason: `proposal not found: ${from}`
|
|
39752
39772
|
};
|
|
39753
39773
|
}
|
|
39754
|
-
if (
|
|
39774
|
+
if (existsSync10(to) && !force) {
|
|
39755
39775
|
const existing = await readFile5(to, "utf-8");
|
|
39756
39776
|
if (!existing.includes("generated by opencode-swarm skill-generator")) {
|
|
39757
39777
|
return {
|
|
@@ -39815,7 +39835,7 @@ async function listSkills(directory) {
|
|
|
39815
39835
|
const proposalsDir = path17.join(directory, ".swarm", "skills", "proposals");
|
|
39816
39836
|
const activeDir = path17.join(directory, ".opencode", "skills", "generated");
|
|
39817
39837
|
const fs9 = await import("fs/promises");
|
|
39818
|
-
if (
|
|
39838
|
+
if (existsSync10(proposalsDir)) {
|
|
39819
39839
|
const entries = await fs9.readdir(proposalsDir);
|
|
39820
39840
|
for (const f of entries) {
|
|
39821
39841
|
if (!f.endsWith(".md"))
|
|
@@ -39827,16 +39847,16 @@ async function listSkills(directory) {
|
|
|
39827
39847
|
});
|
|
39828
39848
|
}
|
|
39829
39849
|
}
|
|
39830
|
-
if (
|
|
39850
|
+
if (existsSync10(activeDir)) {
|
|
39831
39851
|
const entries = await fs9.readdir(activeDir, { withFileTypes: true });
|
|
39832
39852
|
for (const e of entries) {
|
|
39833
39853
|
if (!e.isDirectory())
|
|
39834
39854
|
continue;
|
|
39835
39855
|
const retiredMarker = path17.join(activeDir, e.name, "retired.marker");
|
|
39836
|
-
if (
|
|
39856
|
+
if (existsSync10(retiredMarker))
|
|
39837
39857
|
continue;
|
|
39838
39858
|
const skillPath = path17.join(activeDir, e.name, "SKILL.md");
|
|
39839
|
-
if (
|
|
39859
|
+
if (existsSync10(skillPath)) {
|
|
39840
39860
|
result.active.push({
|
|
39841
39861
|
slug: e.name,
|
|
39842
39862
|
path: skillPath
|
|
@@ -39915,7 +39935,7 @@ async function inspectSkill(directory, slug, prefer = "auto") {
|
|
|
39915
39935
|
if (prefer === "proposal" || prefer === "auto")
|
|
39916
39936
|
candidates.push({ p: proposalPath(directory, cleanSlug), m: "draft" });
|
|
39917
39937
|
for (const c of candidates) {
|
|
39918
|
-
if (
|
|
39938
|
+
if (existsSync10(c.p)) {
|
|
39919
39939
|
const content = await readFile5(c.p, "utf-8");
|
|
39920
39940
|
return { found: true, path: c.p, content, mode: c.m };
|
|
39921
39941
|
}
|
|
@@ -39933,7 +39953,7 @@ async function retireSkill(directory, slug, reason) {
|
|
|
39933
39953
|
};
|
|
39934
39954
|
}
|
|
39935
39955
|
const skillPath = activePath(directory, cleanSlug);
|
|
39936
|
-
if (!
|
|
39956
|
+
if (!existsSync10(skillPath)) {
|
|
39937
39957
|
return {
|
|
39938
39958
|
retired: false,
|
|
39939
39959
|
path: skillPath,
|
|
@@ -39947,7 +39967,7 @@ async function retireSkill(directory, slug, reason) {
|
|
|
39947
39967
|
retiredAt: new Date().toISOString(),
|
|
39948
39968
|
reason: reason ?? "manual_retire"
|
|
39949
39969
|
});
|
|
39950
|
-
await
|
|
39970
|
+
await mkdir7(markerDir, { recursive: true });
|
|
39951
39971
|
await writeFile4(markerPath, markerContent, "utf-8");
|
|
39952
39972
|
return {
|
|
39953
39973
|
retired: true,
|
|
@@ -39967,7 +39987,7 @@ async function regenerateSkill(directory, slug) {
|
|
|
39967
39987
|
};
|
|
39968
39988
|
}
|
|
39969
39989
|
const skillPath = activePath(directory, cleanSlug);
|
|
39970
|
-
if (!
|
|
39990
|
+
if (!existsSync10(skillPath)) {
|
|
39971
39991
|
return {
|
|
39972
39992
|
regenerated: false,
|
|
39973
39993
|
path: skillPath,
|
|
@@ -39992,7 +40012,7 @@ async function regenerateSkill(directory, slug) {
|
|
|
39992
40012
|
try {
|
|
39993
40013
|
const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
39994
40014
|
const hivePath = resolveHiveKnowledgePath();
|
|
39995
|
-
const hive =
|
|
40015
|
+
const hive = existsSync10(hivePath) ? await readKnowledge(hivePath) : [];
|
|
39996
40016
|
const all = [...swarm, ...hive];
|
|
39997
40017
|
const idSet = new Set(fm.sourceKnowledgeIds);
|
|
39998
40018
|
matchedEntries = all.filter((e) => idSet.has(e.id));
|
|
@@ -40141,8 +40161,8 @@ var init_skill_generator = __esm(() => {
|
|
|
40141
40161
|
});
|
|
40142
40162
|
|
|
40143
40163
|
// src/services/skill-improver-quota.ts
|
|
40144
|
-
import { existsSync as
|
|
40145
|
-
import { mkdir as
|
|
40164
|
+
import { existsSync as existsSync11 } from "fs";
|
|
40165
|
+
import { mkdir as mkdir8, readFile as readFile6, rename as rename4, writeFile as writeFile5 } from "fs/promises";
|
|
40146
40166
|
import * as path18 from "path";
|
|
40147
40167
|
async function acquireLock(dir) {
|
|
40148
40168
|
const acquire = import_proper_lockfile6.default.lock(dir, LOCK_RETRY_OPTS);
|
|
@@ -40174,7 +40194,7 @@ function todayKey(window, now = new Date) {
|
|
|
40174
40194
|
return `${yr}-${m}-${d}`;
|
|
40175
40195
|
}
|
|
40176
40196
|
async function readState(filePath) {
|
|
40177
|
-
if (!
|
|
40197
|
+
if (!existsSync11(filePath))
|
|
40178
40198
|
return null;
|
|
40179
40199
|
try {
|
|
40180
40200
|
const raw = await readFile6(filePath, "utf-8");
|
|
@@ -40188,7 +40208,7 @@ async function readState(filePath) {
|
|
|
40188
40208
|
}
|
|
40189
40209
|
}
|
|
40190
40210
|
async function writeState(filePath, state) {
|
|
40191
|
-
await
|
|
40211
|
+
await mkdir8(path18.dirname(filePath), { recursive: true });
|
|
40192
40212
|
const tmp = `${filePath}.tmp-${process.pid}`;
|
|
40193
40213
|
await writeFile5(tmp, JSON.stringify(state, null, 2), "utf-8");
|
|
40194
40214
|
await rename4(tmp, filePath);
|
|
@@ -40211,7 +40231,7 @@ async function getQuotaState(directory, opts) {
|
|
|
40211
40231
|
}
|
|
40212
40232
|
async function reserveQuota(directory, opts) {
|
|
40213
40233
|
const filePath = resolveQuotaPath(directory, opts.scope);
|
|
40214
|
-
await
|
|
40234
|
+
await mkdir8(path18.dirname(filePath), { recursive: true });
|
|
40215
40235
|
let release = null;
|
|
40216
40236
|
try {
|
|
40217
40237
|
release = await acquireLock(path18.dirname(filePath));
|
|
@@ -40241,7 +40261,7 @@ async function reserveQuota(directory, opts) {
|
|
|
40241
40261
|
}
|
|
40242
40262
|
async function releaseQuota(directory, opts) {
|
|
40243
40263
|
const filePath = resolveQuotaPath(directory, opts.scope);
|
|
40244
|
-
await
|
|
40264
|
+
await mkdir8(path18.dirname(filePath), { recursive: true });
|
|
40245
40265
|
let release = null;
|
|
40246
40266
|
try {
|
|
40247
40267
|
release = await acquireLock(path18.dirname(filePath));
|
|
@@ -40426,8 +40446,8 @@ function appendSkillUsageEntry(directory, entry) {
|
|
|
40426
40446
|
_internals16.appendFileSync(resolved, `${JSON.stringify(fullEntry)}
|
|
40427
40447
|
`, "utf-8");
|
|
40428
40448
|
try {
|
|
40429
|
-
const
|
|
40430
|
-
if (
|
|
40449
|
+
const stat4 = _internals16.statSync(resolved);
|
|
40450
|
+
if (stat4.size > SKILL_USAGE_LOG_ROTATE_BYTES) {
|
|
40431
40451
|
_internals16.pruneSkillUsageLog(directory, SKILL_USAGE_LOG_MAX_ENTRIES_PER_SKILL);
|
|
40432
40452
|
}
|
|
40433
40453
|
} catch {}
|
|
@@ -40481,11 +40501,11 @@ function readSkillUsageEntriesTail(directory, filters, maxBytes = TAIL_BYTES_DEF
|
|
|
40481
40501
|
try {
|
|
40482
40502
|
const normalizedMaxBytes = Number.isFinite(maxBytes) ? maxBytes : TAIL_BYTES_DEFAULT;
|
|
40483
40503
|
const boundedMaxBytes = Math.min(Math.max(1, normalizedMaxBytes), MAX_TAIL_BYTES);
|
|
40484
|
-
const
|
|
40485
|
-
const start = Math.max(0,
|
|
40504
|
+
const stat4 = _internals16.statSync(logPath);
|
|
40505
|
+
const start = Math.max(0, stat4.size - boundedMaxBytes);
|
|
40486
40506
|
const fd = _internals16.openSync(logPath, "r");
|
|
40487
40507
|
try {
|
|
40488
|
-
const readLen =
|
|
40508
|
+
const readLen = stat4.size - start;
|
|
40489
40509
|
if (readLen === 0)
|
|
40490
40510
|
return [];
|
|
40491
40511
|
const buf = Buffer.alloc(readLen);
|
|
@@ -41028,10 +41048,10 @@ var init_hive_promoter = __esm(() => {
|
|
|
41028
41048
|
|
|
41029
41049
|
// src/services/synonym-map.ts
|
|
41030
41050
|
import {
|
|
41031
|
-
mkdir as
|
|
41051
|
+
mkdir as mkdir9,
|
|
41032
41052
|
readFile as readFile7,
|
|
41033
41053
|
rename as rename5,
|
|
41034
|
-
stat as
|
|
41054
|
+
stat as stat4,
|
|
41035
41055
|
unlink as unlink2,
|
|
41036
41056
|
writeFile as writeFile6
|
|
41037
41057
|
} from "fs/promises";
|
|
@@ -41174,7 +41194,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
|
|
|
41174
41194
|
}
|
|
41175
41195
|
try {
|
|
41176
41196
|
const ceiling = Math.max(MIN_READ_CEILING_BYTES, Math.floor(maxPairs) * APPROX_BYTES_PER_PAIR);
|
|
41177
|
-
const st = await
|
|
41197
|
+
const st = await stat4(filePath);
|
|
41178
41198
|
if (st.size > ceiling)
|
|
41179
41199
|
return emptySynonymMap();
|
|
41180
41200
|
const raw = await readFile7(filePath, "utf-8");
|
|
@@ -41184,7 +41204,7 @@ async function readSynonymMap(directory, maxPairs = DEFAULT_MAX_PAIRS) {
|
|
|
41184
41204
|
}
|
|
41185
41205
|
}
|
|
41186
41206
|
async function writeSynonymMapAtomic(filePath, map3) {
|
|
41187
|
-
await
|
|
41207
|
+
await mkdir9(path21.dirname(filePath), { recursive: true });
|
|
41188
41208
|
const tmp = `${filePath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
|
|
41189
41209
|
try {
|
|
41190
41210
|
await writeFile6(tmp, JSON.stringify(map3, null, 2), "utf-8");
|
|
@@ -41198,7 +41218,7 @@ async function writeSynonymMapAtomic(filePath, map3) {
|
|
|
41198
41218
|
async function rebuildSynonymMap(directory, entries, maxPairs = DEFAULT_MAX_PAIRS) {
|
|
41199
41219
|
const filePath = resolveSynonymMapPath(directory);
|
|
41200
41220
|
const dir = path21.dirname(filePath);
|
|
41201
|
-
await
|
|
41221
|
+
await mkdir9(dir, { recursive: true });
|
|
41202
41222
|
let release = null;
|
|
41203
41223
|
try {
|
|
41204
41224
|
release = await import_proper_lockfile7.default.lock(dir, {
|
|
@@ -41487,8 +41507,8 @@ function formatSkillIndexWithContext(skills, directory) {
|
|
|
41487
41507
|
const usageLogPath = path22.join(directory, ".swarm", "skill-usage.jsonl");
|
|
41488
41508
|
let hasHistory = false;
|
|
41489
41509
|
try {
|
|
41490
|
-
const
|
|
41491
|
-
hasHistory =
|
|
41510
|
+
const stat5 = fs10.statSync(usageLogPath);
|
|
41511
|
+
hasHistory = stat5.size > 0;
|
|
41492
41512
|
} catch {}
|
|
41493
41513
|
if (!hasHistory) {
|
|
41494
41514
|
return skills.map((sp) => {
|
|
@@ -42184,7 +42204,7 @@ var init_skill_propagation_gate = __esm(() => {
|
|
|
42184
42204
|
});
|
|
42185
42205
|
|
|
42186
42206
|
// src/hooks/micro-reflector.ts
|
|
42187
|
-
import { existsSync as
|
|
42207
|
+
import { existsSync as existsSync14 } from "fs";
|
|
42188
42208
|
import { readFile as readFile8, writeFile as writeFile7 } from "fs/promises";
|
|
42189
42209
|
import * as path24 from "path";
|
|
42190
42210
|
function resolveInsightCandidatesPath(directory) {
|
|
@@ -42194,7 +42214,7 @@ async function readTaskTrajectory(directory, taskId) {
|
|
|
42194
42214
|
try {
|
|
42195
42215
|
const rel = path24.join("evidence", sanitizeTaskId2(taskId), "trajectory.jsonl");
|
|
42196
42216
|
const filePath = validateSwarmPath(directory, rel);
|
|
42197
|
-
if (!
|
|
42217
|
+
if (!existsSync14(filePath))
|
|
42198
42218
|
return [];
|
|
42199
42219
|
const content = await readFile8(filePath, "utf-8");
|
|
42200
42220
|
const out = [];
|
|
@@ -42231,8 +42251,8 @@ var init_micro_reflector = __esm(() => {
|
|
|
42231
42251
|
});
|
|
42232
42252
|
|
|
42233
42253
|
// src/hooks/knowledge-curator.ts
|
|
42234
|
-
import { existsSync as
|
|
42235
|
-
import { appendFile as appendFile6, mkdir as
|
|
42254
|
+
import { existsSync as existsSync15 } from "fs";
|
|
42255
|
+
import { appendFile as appendFile6, mkdir as mkdir10, readFile as readFile9, writeFile as writeFile8 } from "fs/promises";
|
|
42236
42256
|
import * as path25 from "path";
|
|
42237
42257
|
function pruneSeenRetroSections() {
|
|
42238
42258
|
const cutoff = Date.now() - 86400000;
|
|
@@ -42494,7 +42514,7 @@ RETRY: your last output was missing ${result.missing.join("; ")}; produce valid
|
|
|
42494
42514
|
async function appendCuratorSkippedEvent(directory, record3) {
|
|
42495
42515
|
try {
|
|
42496
42516
|
const filePath = path25.join(directory, ".swarm", "events.jsonl");
|
|
42497
|
-
await
|
|
42517
|
+
await mkdir10(path25.dirname(filePath), { recursive: true });
|
|
42498
42518
|
await appendFile6(filePath, `${JSON.stringify({
|
|
42499
42519
|
timestamp: new Date().toISOString(),
|
|
42500
42520
|
event: "curator_skipped",
|
|
@@ -42521,7 +42541,7 @@ function readInsightJsonl(content) {
|
|
|
42521
42541
|
async function consumeInsightCandidates(directory, batchLimit = MESO_INSIGHT_BATCH_LIMIT) {
|
|
42522
42542
|
try {
|
|
42523
42543
|
const filePath = resolveInsightCandidatesPath(directory);
|
|
42524
|
-
if (!
|
|
42544
|
+
if (!existsSync15(filePath))
|
|
42525
42545
|
return [];
|
|
42526
42546
|
const consumed = [];
|
|
42527
42547
|
await transactFile(filePath, async (p) => readInsightJsonl(await readFile9(p, "utf-8").catch(() => "")), async (p, data) => {
|
|
@@ -42999,13 +43019,16 @@ function createSkillImproverLLMDelegate(directory, sessionId) {
|
|
|
42999
43019
|
}
|
|
43000
43020
|
};
|
|
43001
43021
|
if (signal?.aborted) {
|
|
43002
|
-
cleanup();
|
|
43003
43022
|
throw new Error("SKILL_IMPROVER_LLM_TIMEOUT");
|
|
43004
43023
|
}
|
|
43005
|
-
signal
|
|
43024
|
+
const sdkOpts = signal ? { signal } : {};
|
|
43006
43025
|
try {
|
|
43007
43026
|
const createResult = await client.session.create({
|
|
43008
|
-
|
|
43027
|
+
...sessionId ? {
|
|
43028
|
+
body: { parentID: sessionId, title: "skill_improver background" }
|
|
43029
|
+
} : {},
|
|
43030
|
+
query: { directory },
|
|
43031
|
+
...sdkOpts
|
|
43009
43032
|
});
|
|
43010
43033
|
if (!createResult.data) {
|
|
43011
43034
|
throw new Error(`Failed to create skill_improver session: ${JSON.stringify(createResult.error)}`);
|
|
@@ -43014,34 +43037,31 @@ function createSkillImproverLLMDelegate(directory, sessionId) {
|
|
|
43014
43037
|
if (signal?.aborted)
|
|
43015
43038
|
throw new Error("SKILL_IMPROVER_LLM_TIMEOUT");
|
|
43016
43039
|
const agentName = resolveSkillImproverAgentName(sessionId);
|
|
43017
|
-
|
|
43018
|
-
try {
|
|
43019
|
-
const prelude = systemPrompt ? `${systemPrompt}
|
|
43040
|
+
const prelude = systemPrompt ? `${systemPrompt}
|
|
43020
43041
|
|
|
43021
43042
|
---
|
|
43022
43043
|
|
|
43023
43044
|
${userInput}` : userInput;
|
|
43024
|
-
|
|
43025
|
-
|
|
43026
|
-
|
|
43027
|
-
|
|
43028
|
-
|
|
43029
|
-
|
|
43030
|
-
|
|
43031
|
-
|
|
43032
|
-
}
|
|
43033
|
-
if (signal?.aborted)
|
|
43034
|
-
throw new Error("SKILL_IMPROVER_LLM_TIMEOUT");
|
|
43035
|
-
throw err;
|
|
43036
|
-
}
|
|
43045
|
+
const promptResult = await client.session.prompt({
|
|
43046
|
+
path: { id: ephemeralSessionId },
|
|
43047
|
+
body: {
|
|
43048
|
+
agent: agentName,
|
|
43049
|
+
tools: { write: false, edit: false, patch: false },
|
|
43050
|
+
parts: [{ type: "text", text: prelude }]
|
|
43051
|
+
},
|
|
43052
|
+
...sdkOpts
|
|
43053
|
+
});
|
|
43037
43054
|
if (!promptResult.data) {
|
|
43038
43055
|
throw new Error(`skill_improver LLM prompt failed: ${JSON.stringify(promptResult.error)}`);
|
|
43039
43056
|
}
|
|
43040
43057
|
const textParts = promptResult.data.parts.filter((p) => p.type === "text");
|
|
43041
43058
|
return textParts.map((p) => p.text).join(`
|
|
43042
43059
|
`);
|
|
43060
|
+
} catch (err) {
|
|
43061
|
+
if (isAbortError(err))
|
|
43062
|
+
throw new Error("SKILL_IMPROVER_LLM_TIMEOUT");
|
|
43063
|
+
throw err;
|
|
43043
43064
|
} finally {
|
|
43044
|
-
signal?.removeEventListener("abort", cleanup);
|
|
43045
43065
|
cleanup();
|
|
43046
43066
|
}
|
|
43047
43067
|
};
|
|
@@ -43051,7 +43071,7 @@ var init_skill_improver_llm_factory = __esm(() => {
|
|
|
43051
43071
|
});
|
|
43052
43072
|
|
|
43053
43073
|
// src/services/trajectory-cluster.ts
|
|
43054
|
-
import { mkdir as
|
|
43074
|
+
import { mkdir as mkdir11, writeFile as writeFile9 } from "fs/promises";
|
|
43055
43075
|
import * as path26 from "path";
|
|
43056
43076
|
function failureKind(e) {
|
|
43057
43077
|
const tool3 = (e.tool ?? "").toLowerCase();
|
|
@@ -43182,7 +43202,7 @@ async function writeMotifProposals(directory, opts = {}) {
|
|
|
43182
43202
|
return result;
|
|
43183
43203
|
const max = opts.maxProposals ?? 10;
|
|
43184
43204
|
const proposalsDir = validateSwarmPath(directory, path26.join("skills", "proposals"));
|
|
43185
|
-
await
|
|
43205
|
+
await mkdir11(proposalsDir, { recursive: true });
|
|
43186
43206
|
for (const motif of motifs.slice(0, max)) {
|
|
43187
43207
|
const slug = `motif-${slugify2(motif.signature)}`;
|
|
43188
43208
|
const filePath = path26.join(proposalsDir, `${slug}.md`);
|
|
@@ -43326,7 +43346,7 @@ async function writeSuccessMotifProposals(directory, opts = {}) {
|
|
|
43326
43346
|
return result;
|
|
43327
43347
|
const max = opts.maxProposals ?? 10;
|
|
43328
43348
|
const proposalsDir = validateSwarmPath(directory, path26.join("skills", "proposals"));
|
|
43329
|
-
await
|
|
43349
|
+
await mkdir11(proposalsDir, { recursive: true });
|
|
43330
43350
|
for (const motif of motifs.slice(0, max)) {
|
|
43331
43351
|
const slug = workflowSlug(motif.signature);
|
|
43332
43352
|
const filePath = path26.join(proposalsDir, `${slug}.md`);
|
|
@@ -43348,12 +43368,12 @@ var init_trajectory_cluster = __esm(() => {
|
|
|
43348
43368
|
});
|
|
43349
43369
|
|
|
43350
43370
|
// src/services/unactionable-hardening.ts
|
|
43351
|
-
import { existsSync as
|
|
43371
|
+
import { existsSync as existsSync16 } from "fs";
|
|
43352
43372
|
async function hardenUnactionableEntries(params) {
|
|
43353
43373
|
const result = { hardened: 0, retired: 0, remaining: 0 };
|
|
43354
43374
|
try {
|
|
43355
43375
|
const queuePath = resolveUnactionablePath(params.directory);
|
|
43356
|
-
if (!
|
|
43376
|
+
if (!existsSync16(queuePath))
|
|
43357
43377
|
return result;
|
|
43358
43378
|
const limit = params.batchLimit ?? HARDENING_BATCH_LIMIT;
|
|
43359
43379
|
const dedupThreshold = params.dedupThreshold ?? 0.6;
|
|
@@ -43460,14 +43480,14 @@ var init_unactionable_hardening = __esm(() => {
|
|
|
43460
43480
|
});
|
|
43461
43481
|
|
|
43462
43482
|
// src/services/skill-improver.ts
|
|
43463
|
-
import { existsSync as
|
|
43464
|
-
import { mkdir as
|
|
43483
|
+
import { existsSync as existsSync17 } from "fs";
|
|
43484
|
+
import { mkdir as mkdir12, readFile as readFile10, rename as rename6, writeFile as writeFile10 } from "fs/promises";
|
|
43465
43485
|
import * as path27 from "path";
|
|
43466
43486
|
function timestampSlug(d) {
|
|
43467
43487
|
return d.toISOString().replace(/[:.]/g, "-");
|
|
43468
43488
|
}
|
|
43469
43489
|
async function atomicWrite2(p, content) {
|
|
43470
|
-
await
|
|
43490
|
+
await mkdir12(path27.dirname(p), { recursive: true });
|
|
43471
43491
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
43472
43492
|
await writeFile10(tmp, content, "utf-8");
|
|
43473
43493
|
await rename6(tmp, p);
|
|
@@ -43475,7 +43495,7 @@ async function atomicWrite2(p, content) {
|
|
|
43475
43495
|
async function gatherInventory(directory) {
|
|
43476
43496
|
const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
43477
43497
|
const hivePath = resolveHiveKnowledgePath();
|
|
43478
|
-
const hive =
|
|
43498
|
+
const hive = existsSync17(hivePath) ? await readKnowledge(hivePath) : [];
|
|
43479
43499
|
const archived = [...swarm, ...hive].filter((e) => e.status === "archived").length;
|
|
43480
43500
|
const skills = await listSkills(directory);
|
|
43481
43501
|
const knowledgeById = new Map([...swarm, ...hive].map((entry) => [entry.id, entry]));
|
|
@@ -43573,7 +43593,7 @@ ${inv.staleActiveSkills.slice(0, 10).map((s) => `- ${s.slug} | ${s.reasons.join(
|
|
|
43573
43593
|
`) || "(none)"}
|
|
43574
43594
|
`;
|
|
43575
43595
|
}
|
|
43576
|
-
function
|
|
43596
|
+
function isAbortError2(err) {
|
|
43577
43597
|
return err instanceof Error && (err.name === "AbortError" || err.message === "skill_improver_aborted");
|
|
43578
43598
|
}
|
|
43579
43599
|
function throwIfAborted(signal) {
|
|
@@ -43721,7 +43741,7 @@ async function runSkillImprover(req) {
|
|
|
43721
43741
|
inventory = await gatherInventory(req.directory);
|
|
43722
43742
|
throwIfAborted(req.signal);
|
|
43723
43743
|
} catch (err) {
|
|
43724
|
-
if (
|
|
43744
|
+
if (isAbortError2(err)) {
|
|
43725
43745
|
return await abortResult();
|
|
43726
43746
|
}
|
|
43727
43747
|
await releaseQuota(req.directory, {
|
|
@@ -43753,7 +43773,7 @@ async function runSkillImprover(req) {
|
|
|
43753
43773
|
}
|
|
43754
43774
|
source = "llm";
|
|
43755
43775
|
} catch (err) {
|
|
43756
|
-
if (
|
|
43776
|
+
if (isAbortError2(err)) {
|
|
43757
43777
|
return await abortResult();
|
|
43758
43778
|
}
|
|
43759
43779
|
return {
|
|
@@ -43770,7 +43790,7 @@ async function runSkillImprover(req) {
|
|
|
43770
43790
|
try {
|
|
43771
43791
|
throwIfAborted(req.signal);
|
|
43772
43792
|
} catch (err) {
|
|
43773
|
-
if (
|
|
43793
|
+
if (isAbortError2(err)) {
|
|
43774
43794
|
return await abortResult();
|
|
43775
43795
|
}
|
|
43776
43796
|
throw err;
|
|
@@ -43783,7 +43803,7 @@ async function runSkillImprover(req) {
|
|
|
43783
43803
|
try {
|
|
43784
43804
|
throwIfAborted(req.signal);
|
|
43785
43805
|
} catch (err) {
|
|
43786
|
-
if (
|
|
43806
|
+
if (isAbortError2(err)) {
|
|
43787
43807
|
return await abortResult();
|
|
43788
43808
|
}
|
|
43789
43809
|
throw err;
|
|
@@ -43804,7 +43824,7 @@ async function runSkillImprover(req) {
|
|
|
43804
43824
|
try {
|
|
43805
43825
|
throwIfAborted(req.signal);
|
|
43806
43826
|
} catch (err) {
|
|
43807
|
-
if (
|
|
43827
|
+
if (isAbortError2(err)) {
|
|
43808
43828
|
return await abortResult();
|
|
43809
43829
|
}
|
|
43810
43830
|
throw err;
|
|
@@ -44241,7 +44261,7 @@ __export(exports_curator_postmortem, {
|
|
|
44241
44261
|
runCuratorPostMortem: () => runCuratorPostMortem,
|
|
44242
44262
|
_internals: () => _internals21
|
|
44243
44263
|
});
|
|
44244
|
-
import { existsSync as
|
|
44264
|
+
import { existsSync as existsSync18, readdirSync as readdirSync6, readFileSync as readFileSync9 } from "fs";
|
|
44245
44265
|
import * as path28 from "path";
|
|
44246
44266
|
async function collectKnowledgeSummary(directory) {
|
|
44247
44267
|
const entries = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
@@ -44281,7 +44301,7 @@ async function collectKnowledgeSummary(directory) {
|
|
|
44281
44301
|
}
|
|
44282
44302
|
function readJsonlFile(filePath) {
|
|
44283
44303
|
try {
|
|
44284
|
-
if (!
|
|
44304
|
+
if (!existsSync18(filePath))
|
|
44285
44305
|
return [];
|
|
44286
44306
|
const content = readFileSync9(filePath, "utf-8");
|
|
44287
44307
|
const results = [];
|
|
@@ -44302,12 +44322,12 @@ function collectRetrospectives(directory) {
|
|
|
44302
44322
|
const results = [];
|
|
44303
44323
|
const evidenceDir = path28.join(directory, ".swarm", "evidence");
|
|
44304
44324
|
try {
|
|
44305
|
-
if (!
|
|
44325
|
+
if (!existsSync18(evidenceDir))
|
|
44306
44326
|
return results;
|
|
44307
|
-
for (const entry of
|
|
44327
|
+
for (const entry of readdirSync6(evidenceDir, { withFileTypes: true })) {
|
|
44308
44328
|
if (entry.isDirectory() && entry.name.startsWith("retro-")) {
|
|
44309
44329
|
const retroPath = path28.join(evidenceDir, entry.name, "evidence.json");
|
|
44310
|
-
if (
|
|
44330
|
+
if (existsSync18(retroPath)) {
|
|
44311
44331
|
try {
|
|
44312
44332
|
results.push(readFileSync9(retroPath, "utf-8"));
|
|
44313
44333
|
} catch {}
|
|
@@ -44321,9 +44341,9 @@ function collectDriftReports(directory) {
|
|
|
44321
44341
|
const results = [];
|
|
44322
44342
|
const swarmDir = path28.join(directory, ".swarm");
|
|
44323
44343
|
try {
|
|
44324
|
-
if (!
|
|
44344
|
+
if (!existsSync18(swarmDir))
|
|
44325
44345
|
return results;
|
|
44326
|
-
for (const entry of
|
|
44346
|
+
for (const entry of readdirSync6(swarmDir)) {
|
|
44327
44347
|
if (entry.startsWith("drift-report-phase-") && entry.endsWith(".json")) {
|
|
44328
44348
|
try {
|
|
44329
44349
|
results.push(readFileSync9(path28.join(swarmDir, entry), "utf-8"));
|
|
@@ -44336,7 +44356,7 @@ function collectDriftReports(directory) {
|
|
|
44336
44356
|
function collectPendingProposals(directory) {
|
|
44337
44357
|
const results = [];
|
|
44338
44358
|
const insightPath = path28.join(directory, ".swarm", "insight-candidates.jsonl");
|
|
44339
|
-
if (
|
|
44359
|
+
if (existsSync18(insightPath)) {
|
|
44340
44360
|
try {
|
|
44341
44361
|
results.push({
|
|
44342
44362
|
source: "insight-candidates",
|
|
@@ -44346,8 +44366,8 @@ function collectPendingProposals(directory) {
|
|
|
44346
44366
|
}
|
|
44347
44367
|
const proposalsDir = path28.join(directory, ".swarm", "skills", "proposals");
|
|
44348
44368
|
try {
|
|
44349
|
-
if (
|
|
44350
|
-
for (const entry of
|
|
44369
|
+
if (existsSync18(proposalsDir)) {
|
|
44370
|
+
for (const entry of readdirSync6(proposalsDir)) {
|
|
44351
44371
|
if (entry.endsWith(".md") || entry.endsWith(".json")) {
|
|
44352
44372
|
try {
|
|
44353
44373
|
results.push({
|
|
@@ -44501,7 +44521,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
44501
44521
|
warnings: [...warnings, "Invalid report path."]
|
|
44502
44522
|
};
|
|
44503
44523
|
}
|
|
44504
|
-
if (!options.force &&
|
|
44524
|
+
if (!options.force && existsSync18(reportPath)) {
|
|
44505
44525
|
return {
|
|
44506
44526
|
success: true,
|
|
44507
44527
|
planId,
|
|
@@ -44564,8 +44584,8 @@ ${llmOutput}`;
|
|
|
44564
44584
|
reportContent = buildDataOnlyReport(planId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
|
|
44565
44585
|
}
|
|
44566
44586
|
try {
|
|
44567
|
-
const { mkdirSync:
|
|
44568
|
-
|
|
44587
|
+
const { mkdirSync: mkdirSync10, writeFileSync: writeFileSync7 } = await import("fs");
|
|
44588
|
+
mkdirSync10(path28.dirname(reportPath), { recursive: true });
|
|
44569
44589
|
writeFileSync7(reportPath, reportContent, "utf-8");
|
|
44570
44590
|
} catch (err) {
|
|
44571
44591
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -44655,8 +44675,8 @@ async function copyDirRecursive(src, dest) {
|
|
|
44655
44675
|
const srcEntry = path29.join(src, entry);
|
|
44656
44676
|
const destEntry = path29.join(dest, entry);
|
|
44657
44677
|
try {
|
|
44658
|
-
const
|
|
44659
|
-
if (
|
|
44678
|
+
const stat5 = await fs12.stat(srcEntry);
|
|
44679
|
+
if (stat5.isDirectory()) {
|
|
44660
44680
|
const subCount = await copyDirRecursive(srcEntry, destEntry).catch(() => 0);
|
|
44661
44681
|
count += subCount;
|
|
44662
44682
|
} else {
|
|
@@ -44692,8 +44712,8 @@ function guaranteeAllPlansComplete(planData) {
|
|
|
44692
44712
|
async function handleCloseCommand(directory, args, options = {}) {
|
|
44693
44713
|
const swarmDir = path29.join(directory, ".swarm");
|
|
44694
44714
|
try {
|
|
44695
|
-
const
|
|
44696
|
-
if (
|
|
44715
|
+
const stat5 = fsSync2.lstatSync(swarmDir);
|
|
44716
|
+
if (stat5.isSymbolicLink()) {
|
|
44697
44717
|
return `\u274C Refused: .swarm/ is a symlink or junction. Refusing to operate on a redirected directory for safety.`;
|
|
44698
44718
|
}
|
|
44699
44719
|
} catch (err) {
|
|
@@ -45678,7 +45698,7 @@ var init_curate = __esm(() => {
|
|
|
45678
45698
|
// src/tools/co-change-analyzer.ts
|
|
45679
45699
|
import * as child_process3 from "child_process";
|
|
45680
45700
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
45681
|
-
import { readdir, readFile as readFile11, stat as
|
|
45701
|
+
import { readdir as readdir2, readFile as readFile11, stat as stat5 } from "fs/promises";
|
|
45682
45702
|
import * as path31 from "path";
|
|
45683
45703
|
import { promisify } from "util";
|
|
45684
45704
|
function getExecFileAsync() {
|
|
@@ -45781,7 +45801,7 @@ async function scanSourceFiles(dir) {
|
|
|
45781
45801
|
const results = [];
|
|
45782
45802
|
const skipDirs = new Set(["node_modules", ".swarm", "dist", "build"]);
|
|
45783
45803
|
try {
|
|
45784
|
-
const entries = await
|
|
45804
|
+
const entries = await readdir2(dir, { withFileTypes: true });
|
|
45785
45805
|
for (const entry of entries) {
|
|
45786
45806
|
const fullPath = path31.join(dir, entry.name);
|
|
45787
45807
|
if (entry.isDirectory()) {
|
|
@@ -45829,7 +45849,7 @@ async function getStaticEdges(directory) {
|
|
|
45829
45849
|
for (const ext of extensions) {
|
|
45830
45850
|
const testPath = resolvedPath + ext;
|
|
45831
45851
|
try {
|
|
45832
|
-
const testStat = await
|
|
45852
|
+
const testStat = await stat5(testPath);
|
|
45833
45853
|
if (testStat.isFile()) {
|
|
45834
45854
|
targetFile = testPath;
|
|
45835
45855
|
break;
|
|
@@ -46479,7 +46499,7 @@ function getPluginLockFilePaths() {
|
|
|
46479
46499
|
var init_cache_paths = () => {};
|
|
46480
46500
|
|
|
46481
46501
|
// src/gate-evidence.ts
|
|
46482
|
-
import { mkdirSync as
|
|
46502
|
+
import { mkdirSync as mkdirSync10, readFileSync as readFileSync10, realpathSync as realpathSync3 } from "fs";
|
|
46483
46503
|
function isValidTaskId(taskId) {
|
|
46484
46504
|
return isStrictTaskId(taskId);
|
|
46485
46505
|
}
|
|
@@ -46655,7 +46675,7 @@ var init_gate_bridge = __esm(() => {
|
|
|
46655
46675
|
});
|
|
46656
46676
|
|
|
46657
46677
|
// src/services/version-check.ts
|
|
46658
|
-
import { existsSync as
|
|
46678
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
|
|
46659
46679
|
import { homedir as homedir5 } from "os";
|
|
46660
46680
|
import { join as join30 } from "path";
|
|
46661
46681
|
function cacheDir() {
|
|
@@ -46669,7 +46689,7 @@ function cacheFile() {
|
|
|
46669
46689
|
function readVersionCache() {
|
|
46670
46690
|
try {
|
|
46671
46691
|
const path34 = cacheFile();
|
|
46672
|
-
if (!
|
|
46692
|
+
if (!existsSync19(path34))
|
|
46673
46693
|
return null;
|
|
46674
46694
|
const raw = readFileSync11(path34, "utf-8");
|
|
46675
46695
|
const parsed = JSON.parse(raw);
|
|
@@ -46709,10 +46729,10 @@ var init_version_check = __esm(() => {
|
|
|
46709
46729
|
});
|
|
46710
46730
|
|
|
46711
46731
|
// src/services/knowledge-diagnostics.ts
|
|
46712
|
-
import { existsSync as
|
|
46732
|
+
import { existsSync as existsSync20 } from "fs";
|
|
46713
46733
|
import { readFile as readFile12 } from "fs/promises";
|
|
46714
46734
|
async function readRawLines(filePath) {
|
|
46715
|
-
if (!
|
|
46735
|
+
if (!existsSync20(filePath))
|
|
46716
46736
|
return { entries: [], corrupt: 0 };
|
|
46717
46737
|
const content = await readFile12(filePath, "utf-8");
|
|
46718
46738
|
const entries = [];
|
|
@@ -46837,7 +46857,7 @@ async function computeKnowledgeDebug(directory) {
|
|
|
46837
46857
|
};
|
|
46838
46858
|
}
|
|
46839
46859
|
async function safeJsonlCount(filePath) {
|
|
46840
|
-
if (!filePath || !
|
|
46860
|
+
if (!filePath || !existsSync20(filePath))
|
|
46841
46861
|
return 0;
|
|
46842
46862
|
try {
|
|
46843
46863
|
const content = await readFile12(filePath, "utf-8");
|
|
@@ -46920,7 +46940,7 @@ var init_knowledge_diagnostics = __esm(() => {
|
|
|
46920
46940
|
|
|
46921
46941
|
// src/services/diagnose-service.ts
|
|
46922
46942
|
import * as child_process4 from "child_process";
|
|
46923
|
-
import { existsSync as
|
|
46943
|
+
import { existsSync as existsSync21, readdirSync as readdirSync7, readFileSync as readFileSync12, statSync as statSync9 } from "fs";
|
|
46924
46944
|
import path34 from "path";
|
|
46925
46945
|
import { fileURLToPath } from "url";
|
|
46926
46946
|
function validateTaskDag(plan) {
|
|
@@ -47137,7 +47157,7 @@ async function checkPlanSync(directory, plan) {
|
|
|
47137
47157
|
}
|
|
47138
47158
|
async function checkConfigBackups(directory) {
|
|
47139
47159
|
try {
|
|
47140
|
-
const files =
|
|
47160
|
+
const files = readdirSync7(directory);
|
|
47141
47161
|
const backupCount = files.filter((f) => /\.opencode-swarm\.yaml\.bak/.test(f)).length;
|
|
47142
47162
|
if (backupCount <= 5) {
|
|
47143
47163
|
return {
|
|
@@ -47168,7 +47188,7 @@ async function checkConfigBackups(directory) {
|
|
|
47168
47188
|
}
|
|
47169
47189
|
async function checkGitRepository(directory) {
|
|
47170
47190
|
try {
|
|
47171
|
-
if (!
|
|
47191
|
+
if (!existsSync21(directory) || !statSync9(directory).isDirectory()) {
|
|
47172
47192
|
return {
|
|
47173
47193
|
name: "Git Repository",
|
|
47174
47194
|
status: "\u274C",
|
|
@@ -47233,7 +47253,7 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
47233
47253
|
}
|
|
47234
47254
|
async function checkConfigParseability(directory) {
|
|
47235
47255
|
const configPath = path34.join(directory, ".opencode/opencode-swarm.json");
|
|
47236
|
-
if (!
|
|
47256
|
+
if (!existsSync21(configPath)) {
|
|
47237
47257
|
return {
|
|
47238
47258
|
name: "Config Parseability",
|
|
47239
47259
|
status: "\u2705",
|
|
@@ -47288,11 +47308,11 @@ async function checkGrammarWasmFiles() {
|
|
|
47288
47308
|
const thisDir = path34.dirname(fileURLToPath(import.meta.url));
|
|
47289
47309
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
47290
47310
|
const missing = [];
|
|
47291
|
-
if (!
|
|
47311
|
+
if (!existsSync21(path34.join(grammarDir, "tree-sitter.wasm"))) {
|
|
47292
47312
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
47293
47313
|
}
|
|
47294
47314
|
for (const file3 of grammarFiles) {
|
|
47295
|
-
if (!
|
|
47315
|
+
if (!existsSync21(path34.join(grammarDir, file3))) {
|
|
47296
47316
|
missing.push(file3);
|
|
47297
47317
|
}
|
|
47298
47318
|
}
|
|
@@ -47311,7 +47331,7 @@ async function checkGrammarWasmFiles() {
|
|
|
47311
47331
|
}
|
|
47312
47332
|
async function checkCheckpointManifest(directory) {
|
|
47313
47333
|
const manifestPath = path34.join(directory, ".swarm/checkpoints.json");
|
|
47314
|
-
if (!
|
|
47334
|
+
if (!existsSync21(manifestPath)) {
|
|
47315
47335
|
return {
|
|
47316
47336
|
name: "Checkpoint Manifest",
|
|
47317
47337
|
status: "\u2705",
|
|
@@ -47363,7 +47383,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
47363
47383
|
}
|
|
47364
47384
|
async function checkEventStreamIntegrity(directory) {
|
|
47365
47385
|
const eventsPath = path34.join(directory, ".swarm/events.jsonl");
|
|
47366
|
-
if (!
|
|
47386
|
+
if (!existsSync21(eventsPath)) {
|
|
47367
47387
|
return {
|
|
47368
47388
|
name: "Event Stream",
|
|
47369
47389
|
status: "\u2705",
|
|
@@ -47404,7 +47424,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
47404
47424
|
}
|
|
47405
47425
|
async function checkSteeringDirectives(directory) {
|
|
47406
47426
|
const eventsPath = path34.join(directory, ".swarm/events.jsonl");
|
|
47407
|
-
if (!
|
|
47427
|
+
if (!existsSync21(eventsPath)) {
|
|
47408
47428
|
return {
|
|
47409
47429
|
name: "Steering Directives",
|
|
47410
47430
|
status: "\u2705",
|
|
@@ -47460,7 +47480,7 @@ async function checkCurator(directory) {
|
|
|
47460
47480
|
};
|
|
47461
47481
|
}
|
|
47462
47482
|
const summaryPath = path34.join(directory, ".swarm/curator-summary.json");
|
|
47463
|
-
if (!
|
|
47483
|
+
if (!existsSync21(summaryPath)) {
|
|
47464
47484
|
return {
|
|
47465
47485
|
name: "Curator",
|
|
47466
47486
|
status: "\u2705",
|
|
@@ -47627,7 +47647,7 @@ async function getDiagnoseData(directory) {
|
|
|
47627
47647
|
checks5.push(await checkKnowledgeHealth(directory));
|
|
47628
47648
|
try {
|
|
47629
47649
|
const evidenceDir = path34.join(directory, ".swarm", "evidence");
|
|
47630
|
-
const snapshotFiles =
|
|
47650
|
+
const snapshotFiles = existsSync21(evidenceDir) ? readdirSync7(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
47631
47651
|
if (snapshotFiles.length > 0) {
|
|
47632
47652
|
const latest = snapshotFiles.sort().pop();
|
|
47633
47653
|
checks5.push({
|
|
@@ -47660,7 +47680,7 @@ async function getDiagnoseData(directory) {
|
|
|
47660
47680
|
const cacheRows = [];
|
|
47661
47681
|
for (const cachePath of cachePaths) {
|
|
47662
47682
|
try {
|
|
47663
|
-
if (!
|
|
47683
|
+
if (!existsSync21(cachePath)) {
|
|
47664
47684
|
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
47665
47685
|
continue;
|
|
47666
47686
|
}
|
|
@@ -50037,7 +50057,7 @@ var init_profiles = __esm(() => {
|
|
|
50037
50057
|
});
|
|
50038
50058
|
|
|
50039
50059
|
// src/lang/detector.ts
|
|
50040
|
-
import { access as
|
|
50060
|
+
import { access as access4, readdir as readdir3 } from "fs/promises";
|
|
50041
50061
|
import { extname as extname3, join as join32 } from "path";
|
|
50042
50062
|
async function detectProjectLanguages(projectDir) {
|
|
50043
50063
|
const detected = new Set;
|
|
@@ -50045,7 +50065,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
50045
50065
|
let dirEntries;
|
|
50046
50066
|
let entries;
|
|
50047
50067
|
try {
|
|
50048
|
-
dirEntries = await
|
|
50068
|
+
dirEntries = await readdir3(dir, { withFileTypes: true });
|
|
50049
50069
|
entries = dirEntries.map((e) => e.name);
|
|
50050
50070
|
} catch {
|
|
50051
50071
|
return;
|
|
@@ -50061,7 +50081,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
50061
50081
|
continue;
|
|
50062
50082
|
}
|
|
50063
50083
|
try {
|
|
50064
|
-
await
|
|
50084
|
+
await access4(join32(dir, detectFile));
|
|
50065
50085
|
detected.add(profile.id);
|
|
50066
50086
|
break;
|
|
50067
50087
|
} catch {}
|
|
@@ -50079,7 +50099,7 @@ async function detectProjectLanguages(projectDir) {
|
|
|
50079
50099
|
}
|
|
50080
50100
|
await scanDir(projectDir);
|
|
50081
50101
|
try {
|
|
50082
|
-
const topEntries = await
|
|
50102
|
+
const topEntries = await readdir3(projectDir, { withFileTypes: true });
|
|
50083
50103
|
for (const entry of topEntries) {
|
|
50084
50104
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
50085
50105
|
await scanDir(join32(projectDir, entry.name));
|
|
@@ -52083,7 +52103,7 @@ var init_handoff_service = __esm(() => {
|
|
|
52083
52103
|
});
|
|
52084
52104
|
|
|
52085
52105
|
// src/session/snapshot-writer.ts
|
|
52086
|
-
import { closeSync as closeSync5, fsyncSync as fsyncSync2, mkdirSync as
|
|
52106
|
+
import { closeSync as closeSync5, fsyncSync as fsyncSync2, mkdirSync as mkdirSync14, openSync as openSync5, renameSync as renameSync10 } from "fs";
|
|
52087
52107
|
import * as path38 from "path";
|
|
52088
52108
|
function serializeAgentSession(s) {
|
|
52089
52109
|
const gateLog = {};
|
|
@@ -52191,7 +52211,7 @@ async function writeSnapshot(directory, state) {
|
|
|
52191
52211
|
const content = JSON.stringify(snapshot, null, 2);
|
|
52192
52212
|
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
52193
52213
|
const dir = path38.dirname(resolvedPath);
|
|
52194
|
-
|
|
52214
|
+
mkdirSync14(dir, { recursive: true });
|
|
52195
52215
|
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
52196
52216
|
await bunWrite(tempPath, content);
|
|
52197
52217
|
try {
|
|
@@ -52730,8 +52750,8 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
|
52730
52750
|
|
|
52731
52751
|
// src/hooks/knowledge-migrator.ts
|
|
52732
52752
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
52733
|
-
import { existsSync as
|
|
52734
|
-
import { mkdir as
|
|
52753
|
+
import { existsSync as existsSync25, readFileSync as readFileSync16 } from "fs";
|
|
52754
|
+
import { mkdir as mkdir13, readFile as readFile13, writeFile as writeFile11 } from "fs/promises";
|
|
52735
52755
|
import * as os8 from "os";
|
|
52736
52756
|
import * as path39 from "path";
|
|
52737
52757
|
async function migrateKnowledgeToExternal(_directory, _config) {
|
|
@@ -52747,7 +52767,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
52747
52767
|
const sentinelPath = path39.join(directory, ".swarm", ".knowledge-migrated");
|
|
52748
52768
|
const contextPath = path39.join(directory, ".swarm", "context.md");
|
|
52749
52769
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
52750
|
-
if (
|
|
52770
|
+
if (existsSync25(sentinelPath)) {
|
|
52751
52771
|
return {
|
|
52752
52772
|
migrated: false,
|
|
52753
52773
|
entriesMigrated: 0,
|
|
@@ -52756,7 +52776,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
52756
52776
|
skippedReason: "sentinel-exists"
|
|
52757
52777
|
};
|
|
52758
52778
|
}
|
|
52759
|
-
if (!
|
|
52779
|
+
if (!existsSync25(contextPath)) {
|
|
52760
52780
|
return {
|
|
52761
52781
|
migrated: false,
|
|
52762
52782
|
entriesMigrated: 0,
|
|
@@ -52848,7 +52868,7 @@ async function migrateHiveKnowledgeLegacy(config3) {
|
|
|
52848
52868
|
const legacyHivePath = _internals29.resolveLegacyHiveKnowledgePath();
|
|
52849
52869
|
const canonicalHivePath = resolveHiveKnowledgePath();
|
|
52850
52870
|
const sentinelPath = path39.join(path39.dirname(canonicalHivePath), ".hive-knowledge-migrated");
|
|
52851
|
-
if (
|
|
52871
|
+
if (existsSync25(sentinelPath)) {
|
|
52852
52872
|
return {
|
|
52853
52873
|
migrated: false,
|
|
52854
52874
|
entriesMigrated: 0,
|
|
@@ -52857,7 +52877,7 @@ async function migrateHiveKnowledgeLegacy(config3) {
|
|
|
52857
52877
|
skippedReason: "sentinel-exists"
|
|
52858
52878
|
};
|
|
52859
52879
|
}
|
|
52860
|
-
if (!
|
|
52880
|
+
if (!existsSync25(legacyHivePath)) {
|
|
52861
52881
|
return {
|
|
52862
52882
|
migrated: false,
|
|
52863
52883
|
entriesMigrated: 0,
|
|
@@ -53059,7 +53079,7 @@ function truncateLesson2(text) {
|
|
|
53059
53079
|
}
|
|
53060
53080
|
function inferProjectName(directory) {
|
|
53061
53081
|
const packageJsonPath = path39.join(directory, "package.json");
|
|
53062
|
-
if (
|
|
53082
|
+
if (existsSync25(packageJsonPath)) {
|
|
53063
53083
|
try {
|
|
53064
53084
|
const pkg = JSON.parse(readFileSync16(packageJsonPath, "utf-8"));
|
|
53065
53085
|
if (pkg.name && typeof pkg.name === "string") {
|
|
@@ -53079,7 +53099,7 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
53079
53099
|
schema_version: 1,
|
|
53080
53100
|
migration_tool: "knowledge-migrator.ts"
|
|
53081
53101
|
};
|
|
53082
|
-
await
|
|
53102
|
+
await mkdir13(path39.dirname(sentinelPath), { recursive: true });
|
|
53083
53103
|
await writeFile11(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
53084
53104
|
}
|
|
53085
53105
|
function resolveLegacyHiveKnowledgePath() {
|
|
@@ -54267,10 +54287,10 @@ var init_scoring = __esm(() => {
|
|
|
54267
54287
|
|
|
54268
54288
|
// src/memory/local-jsonl-provider.ts
|
|
54269
54289
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
54270
|
-
import { existsSync as
|
|
54290
|
+
import { existsSync as existsSync26 } from "fs";
|
|
54271
54291
|
import {
|
|
54272
54292
|
appendFile as appendFile7,
|
|
54273
|
-
mkdir as
|
|
54293
|
+
mkdir as mkdir14,
|
|
54274
54294
|
readFile as readFile14,
|
|
54275
54295
|
rename as rename7,
|
|
54276
54296
|
writeFile as writeFile12
|
|
@@ -54618,7 +54638,7 @@ function validateLoadedProposals(values, config3) {
|
|
|
54618
54638
|
return { records, invalidCount };
|
|
54619
54639
|
}
|
|
54620
54640
|
async function readJsonl(filePath) {
|
|
54621
|
-
if (!
|
|
54641
|
+
if (!existsSync26(filePath))
|
|
54622
54642
|
return [];
|
|
54623
54643
|
const content = await readFile14(filePath, "utf-8");
|
|
54624
54644
|
const records = [];
|
|
@@ -54674,12 +54694,12 @@ function parseRecallUsageEvent(event) {
|
|
|
54674
54694
|
}
|
|
54675
54695
|
}
|
|
54676
54696
|
async function appendJsonl(filePath, value) {
|
|
54677
|
-
await
|
|
54697
|
+
await mkdir14(path40.dirname(filePath), { recursive: true });
|
|
54678
54698
|
await appendFile7(filePath, `${JSON.stringify(value)}
|
|
54679
54699
|
`, "utf-8");
|
|
54680
54700
|
}
|
|
54681
54701
|
async function writeJsonlAtomic(filePath, values) {
|
|
54682
|
-
await
|
|
54702
|
+
await mkdir14(path40.dirname(filePath), { recursive: true });
|
|
54683
54703
|
const tmp = `${filePath}.tmp.${randomUUID4()}`;
|
|
54684
54704
|
const content = values.map((value) => JSON.stringify(value)).join(`
|
|
54685
54705
|
`) + (values.length > 0 ? `
|
|
@@ -54704,8 +54724,8 @@ var init_prompt_block = __esm(() => {
|
|
|
54704
54724
|
});
|
|
54705
54725
|
|
|
54706
54726
|
// src/memory/jsonl-migration.ts
|
|
54707
|
-
import { existsSync as
|
|
54708
|
-
import { copyFile, mkdir as
|
|
54727
|
+
import { existsSync as existsSync27 } from "fs";
|
|
54728
|
+
import { copyFile as copyFile2, mkdir as mkdir15, readFile as readFile15, stat as stat6, writeFile as writeFile13 } from "fs/promises";
|
|
54709
54729
|
import * as path41 from "path";
|
|
54710
54730
|
function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
|
|
54711
54731
|
const resolved = resolveConfig(config3);
|
|
@@ -54732,25 +54752,25 @@ async function readLegacyJsonl(rootDirectory, config3 = {}) {
|
|
|
54732
54752
|
async function backupLegacyJsonl(rootDirectory, config3 = {}) {
|
|
54733
54753
|
const storageDir = resolveMemoryStorageDir(rootDirectory, config3);
|
|
54734
54754
|
const backupDir = path41.join(storageDir, "backups");
|
|
54735
|
-
await
|
|
54755
|
+
await mkdir15(backupDir, { recursive: true });
|
|
54736
54756
|
const results = [];
|
|
54737
54757
|
for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
|
|
54738
54758
|
const source = path41.join(storageDir, filename);
|
|
54739
|
-
if (!
|
|
54759
|
+
if (!existsSync27(source))
|
|
54740
54760
|
continue;
|
|
54741
54761
|
const backup = path41.join(backupDir, `${filename}.pre-sqlite-migration`);
|
|
54742
|
-
if (
|
|
54762
|
+
if (existsSync27(backup)) {
|
|
54743
54763
|
results.push({ source, backup, created: false });
|
|
54744
54764
|
continue;
|
|
54745
54765
|
}
|
|
54746
|
-
await
|
|
54766
|
+
await copyFile2(source, backup);
|
|
54747
54767
|
results.push({ source, backup, created: true });
|
|
54748
54768
|
}
|
|
54749
54769
|
return results;
|
|
54750
54770
|
}
|
|
54751
54771
|
async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
|
|
54752
54772
|
const exportDir = path41.join(resolveMemoryStorageDir(rootDirectory, config3), "export");
|
|
54753
|
-
await
|
|
54773
|
+
await mkdir15(exportDir, { recursive: true });
|
|
54754
54774
|
const memoriesPath = path41.join(exportDir, "memories.jsonl");
|
|
54755
54775
|
const proposalsPath = path41.join(exportDir, "proposals.jsonl");
|
|
54756
54776
|
await writeFile13(memoriesPath, toJsonl(memories), "utf-8");
|
|
@@ -54759,14 +54779,14 @@ async function writeJsonlExport(rootDirectory, config3, memories, proposals) {
|
|
|
54759
54779
|
}
|
|
54760
54780
|
async function writeMigrationReport(rootDirectory, report, config3 = {}) {
|
|
54761
54781
|
const reportPath = path41.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
|
|
54762
|
-
await
|
|
54782
|
+
await mkdir15(path41.dirname(reportPath), { recursive: true });
|
|
54763
54783
|
await writeFile13(reportPath, `${JSON.stringify(report, null, 2)}
|
|
54764
54784
|
`, "utf-8");
|
|
54765
54785
|
return reportPath;
|
|
54766
54786
|
}
|
|
54767
54787
|
async function readMigrationReport(rootDirectory, config3 = {}) {
|
|
54768
54788
|
const reportPath = path41.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
|
|
54769
|
-
if (!
|
|
54789
|
+
if (!existsSync27(reportPath))
|
|
54770
54790
|
return null;
|
|
54771
54791
|
try {
|
|
54772
54792
|
return JSON.parse(await readFile15(reportPath, "utf-8"));
|
|
@@ -54780,13 +54800,13 @@ async function getLegacyJsonlFileStatus(rootDirectory, config3 = {}) {
|
|
|
54780
54800
|
for (const file3 of ["memories.jsonl", "proposals.jsonl"]) {
|
|
54781
54801
|
const filePath = path41.join(storageDir, file3);
|
|
54782
54802
|
let sizeBytes = 0;
|
|
54783
|
-
if (
|
|
54784
|
-
sizeBytes = (await
|
|
54803
|
+
if (existsSync27(filePath)) {
|
|
54804
|
+
sizeBytes = (await stat6(filePath)).size;
|
|
54785
54805
|
}
|
|
54786
54806
|
statuses.push({
|
|
54787
54807
|
file: file3,
|
|
54788
54808
|
path: filePath,
|
|
54789
|
-
exists:
|
|
54809
|
+
exists: existsSync27(filePath),
|
|
54790
54810
|
sizeBytes
|
|
54791
54811
|
});
|
|
54792
54812
|
}
|
|
@@ -54867,7 +54887,7 @@ async function readProposalJsonl(filePath, config3) {
|
|
|
54867
54887
|
return { records, invalidRows, totalRows: rows.totalRows };
|
|
54868
54888
|
}
|
|
54869
54889
|
async function readJsonlRows(filePath) {
|
|
54870
|
-
if (!
|
|
54890
|
+
if (!existsSync27(filePath)) {
|
|
54871
54891
|
return { rows: [], invalidRows: [], totalRows: 0 };
|
|
54872
54892
|
}
|
|
54873
54893
|
const content = await readFile15(filePath, "utf-8");
|
|
@@ -54905,7 +54925,7 @@ var init_jsonl_migration = __esm(() => {
|
|
|
54905
54925
|
|
|
54906
54926
|
// src/memory/sqlite-provider.ts
|
|
54907
54927
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
54908
|
-
import { mkdirSync as
|
|
54928
|
+
import { mkdirSync as mkdirSync15 } from "fs";
|
|
54909
54929
|
import { createRequire as createRequire2 } from "module";
|
|
54910
54930
|
import * as path42 from "path";
|
|
54911
54931
|
function loadDatabaseCtor2() {
|
|
@@ -54965,7 +54985,7 @@ class SQLiteMemoryProvider {
|
|
|
54965
54985
|
if (this.initialized)
|
|
54966
54986
|
return;
|
|
54967
54987
|
const dbPath = this.databasePath();
|
|
54968
|
-
|
|
54988
|
+
mkdirSync15(path42.dirname(dbPath), { recursive: true });
|
|
54969
54989
|
const Db = loadDatabaseCtor2();
|
|
54970
54990
|
this.db = new Db(dbPath);
|
|
54971
54991
|
this.db.run("PRAGMA journal_mode = WAL;");
|
|
@@ -56244,7 +56264,7 @@ var init_memory = __esm(() => {
|
|
|
56244
56264
|
});
|
|
56245
56265
|
|
|
56246
56266
|
// src/commands/memory.ts
|
|
56247
|
-
import { existsSync as
|
|
56267
|
+
import { existsSync as existsSync28 } from "fs";
|
|
56248
56268
|
import * as path44 from "path";
|
|
56249
56269
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
56250
56270
|
async function handleMemoryCommand(_directory, _args) {
|
|
@@ -56276,7 +56296,7 @@ async function handleMemoryStatusCommand(directory, _args) {
|
|
|
56276
56296
|
`- Provider: \`${config3.provider}\``,
|
|
56277
56297
|
`- Storage: \`${storageDir}\``,
|
|
56278
56298
|
`- SQLite path: \`${sqlitePath}\``,
|
|
56279
|
-
`- SQLite database exists: \`${
|
|
56299
|
+
`- SQLite database exists: \`${existsSync28(sqlitePath)}\``,
|
|
56280
56300
|
`- Automatic destructive cleanup: \`disabled\``,
|
|
56281
56301
|
"",
|
|
56282
56302
|
"### Legacy JSONL"
|
|
@@ -58075,11 +58095,11 @@ function createRedactedContext(line, findings) {
|
|
|
58075
58095
|
function scanFileForSecrets(filePath) {
|
|
58076
58096
|
const findings = [];
|
|
58077
58097
|
try {
|
|
58078
|
-
const
|
|
58079
|
-
if (
|
|
58098
|
+
const lstat2 = fs19.lstatSync(filePath);
|
|
58099
|
+
if (lstat2.isSymbolicLink()) {
|
|
58080
58100
|
return findings;
|
|
58081
58101
|
}
|
|
58082
|
-
if (
|
|
58102
|
+
if (lstat2.size > MAX_FILE_SIZE_BYTES) {
|
|
58083
58103
|
return findings;
|
|
58084
58104
|
}
|
|
58085
58105
|
let buffer;
|
|
@@ -58167,18 +58187,18 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
58167
58187
|
stats.skippedDirs++;
|
|
58168
58188
|
continue;
|
|
58169
58189
|
}
|
|
58170
|
-
let
|
|
58190
|
+
let lstat2;
|
|
58171
58191
|
try {
|
|
58172
|
-
|
|
58192
|
+
lstat2 = fs19.lstatSync(fullPath);
|
|
58173
58193
|
} catch {
|
|
58174
58194
|
stats.fileErrors++;
|
|
58175
58195
|
continue;
|
|
58176
58196
|
}
|
|
58177
|
-
if (
|
|
58197
|
+
if (lstat2.isSymbolicLink()) {
|
|
58178
58198
|
stats.symlinkSkipped++;
|
|
58179
58199
|
continue;
|
|
58180
58200
|
}
|
|
58181
|
-
if (
|
|
58201
|
+
if (lstat2.isDirectory()) {
|
|
58182
58202
|
let realPath;
|
|
58183
58203
|
try {
|
|
58184
58204
|
realPath = fs19.realpathSync(fullPath);
|
|
@@ -58196,7 +58216,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
|
|
|
58196
58216
|
}
|
|
58197
58217
|
const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
|
|
58198
58218
|
files.push(...subFiles);
|
|
58199
|
-
} else if (
|
|
58219
|
+
} else if (lstat2.isFile()) {
|
|
58200
58220
|
const ext = path47.extname(fullPath).toLowerCase();
|
|
58201
58221
|
if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
|
|
58202
58222
|
files.push(fullPath);
|
|
@@ -58527,8 +58547,8 @@ var init_secretscan = __esm(() => {
|
|
|
58527
58547
|
break;
|
|
58528
58548
|
const fileFindings = scanFileForSecrets(filePath);
|
|
58529
58549
|
try {
|
|
58530
|
-
const
|
|
58531
|
-
if (
|
|
58550
|
+
const stat7 = fs19.statSync(filePath);
|
|
58551
|
+
if (stat7.size > MAX_FILE_SIZE_BYTES) {
|
|
58532
58552
|
skippedFiles++;
|
|
58533
58553
|
continue;
|
|
58534
58554
|
}
|
|
@@ -59338,8 +59358,8 @@ function sharedTrailingSegments(a, b) {
|
|
|
59338
59358
|
function isCacheStale(impactMap, generatedAtMs) {
|
|
59339
59359
|
for (const sourcePath of Object.keys(impactMap)) {
|
|
59340
59360
|
try {
|
|
59341
|
-
const
|
|
59342
|
-
if (
|
|
59361
|
+
const stat7 = fs23.statSync(sourcePath);
|
|
59362
|
+
if (stat7.mtimeMs > generatedAtMs) {
|
|
59343
59363
|
return true;
|
|
59344
59364
|
}
|
|
59345
59365
|
} catch {
|
|
@@ -60640,8 +60660,8 @@ function manifestHash(dir) {
|
|
|
60640
60660
|
if (!entries.has(name))
|
|
60641
60661
|
continue;
|
|
60642
60662
|
try {
|
|
60643
|
-
const
|
|
60644
|
-
parts.push(`${name}:${
|
|
60663
|
+
const stat7 = fs28.statSync(path56.join(dir, name));
|
|
60664
|
+
parts.push(`${name}:${stat7.size}:${stat7.mtimeMs}:${stat7.ino}`);
|
|
60645
60665
|
} catch {}
|
|
60646
60666
|
}
|
|
60647
60667
|
return parts.join("|");
|
|
@@ -65122,8 +65142,8 @@ async function countProposals(directory) {
|
|
|
65122
65142
|
const proposalsDir = validateSwarmPath(directory, "skills/proposals");
|
|
65123
65143
|
if (!fsSync3.existsSync(proposalsDir))
|
|
65124
65144
|
return 0;
|
|
65125
|
-
const { readdir:
|
|
65126
|
-
const entries = await
|
|
65145
|
+
const { readdir: readdir5 } = await import("fs/promises");
|
|
65146
|
+
const entries = await readdir5(proposalsDir);
|
|
65127
65147
|
return entries.filter((f) => f.endsWith(".md")).length;
|
|
65128
65148
|
} catch {
|
|
65129
65149
|
return 0;
|
|
@@ -66230,7 +66250,7 @@ Showing full help:
|
|
|
66230
66250
|
}
|
|
66231
66251
|
async function handleModeCommandWithBundledSkills(ctx, handler) {
|
|
66232
66252
|
if (ctx.packageRoot) {
|
|
66233
|
-
|
|
66253
|
+
await syncBundledProjectSkillsIfMissingAsync(ctx.directory, ctx.packageRoot);
|
|
66234
66254
|
}
|
|
66235
66255
|
return Promise.resolve(handler(ctx.directory, ctx.args));
|
|
66236
66256
|
}
|
|
@@ -66430,6 +66450,13 @@ var init_registry = __esm(() => {
|
|
|
66430
66450
|
description: "Run tool registration coherence check",
|
|
66431
66451
|
category: "diagnostics"
|
|
66432
66452
|
},
|
|
66453
|
+
"doctor-tools": {
|
|
66454
|
+
handler: (ctx) => handleDoctorToolsCommand(ctx.directory, ctx.args),
|
|
66455
|
+
description: "Run tool registration coherence check",
|
|
66456
|
+
category: "diagnostics",
|
|
66457
|
+
aliasOf: "doctor tools",
|
|
66458
|
+
deprecated: true
|
|
66459
|
+
},
|
|
66433
66460
|
diagnose: {
|
|
66434
66461
|
handler: (ctx) => handleDiagnoseCommand(ctx.directory, ctx.args),
|
|
66435
66462
|
description: "Run health check on swarm state",
|