@wrongstack/core 0.107.2 → 0.119.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-bridge-mOxbpFcg.d.ts → agent-bridge-PRAbEX-9.d.ts} +1 -1
- package/dist/{agent-subagent-runner-DukQLUcS.d.ts → agent-subagent-runner-DXWImnNV.d.ts} +7 -8
- package/dist/{brain-Dfv4Y82E.d.ts → brain-NZZqL8sn.d.ts} +1 -1
- package/dist/{compactor-DXLxLcmU.d.ts → compactor-C3stu664.d.ts} +1 -1
- package/dist/{config-BSU-6vah.d.ts → config-DZV9VK9n.d.ts} +104 -3
- package/dist/{context-CNRYfhUv.d.ts → context-hvXINa6a.d.ts} +31 -1
- package/dist/coordination/index.d.ts +12 -13
- package/dist/coordination/index.js +198 -0
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +27 -28
- package/dist/defaults/index.js +346 -86
- package/dist/defaults/index.js.map +1 -1
- package/dist/execution/index.d.ts +16 -17
- package/dist/execution/index.js +266 -12
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +6 -7
- package/dist/{goal-preamble-CI8lxeY1.d.ts → goal-preamble-COpt55W8.d.ts} +10 -10
- package/dist/{goal-store-ht0VmR1A.d.ts → goal-store-CV9Yz2X_.d.ts} +11 -0
- package/dist/{index-DIKEcfgC.d.ts → index-4VVHuTZF.d.ts} +7 -6
- package/dist/{index-BWRN6wOb.d.ts → index-Cj3le7TI.d.ts} +9 -10
- package/dist/index.d.ts +41 -42
- package/dist/index.js +372 -118
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -7
- package/dist/kernel/index.d.ts +10 -11
- package/dist/llm-selector-Bmx4PsVM.d.ts +58 -0
- package/dist/{mcp-servers-CXCsANdY.d.ts → mcp-servers-CofNHOqn.d.ts} +3 -3
- package/dist/{mode-ARA3HrkY.d.ts → mode-CZlO9iU1.d.ts} +1 -1
- package/dist/models/index.d.ts +157 -53
- package/dist/models/index.js +423 -1
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-DU64QxQa.d.ts → models-registry-BzlsjKcy.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-51LvnXkD.d.ts → multi-agent-coordinator-CmDmUgq2.d.ts} +1 -1
- package/dist/{null-fleet-bus-D09hMzFQ.d.ts → null-fleet-bus-CyH2YqP4.d.ts} +6 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{parallel-eternal-engine-CUtmM_0V.d.ts → parallel-eternal-engine-uxVm4y4V.d.ts} +11 -10
- package/dist/{path-resolver-DDJiMAtX.d.ts → path-resolver-gfoGxpdd.d.ts} +3 -3
- package/dist/{permission-BDv7z0mk.d.ts → permission-DhLrgA30.d.ts} +1 -1
- package/dist/{permission-policy-dF74EpDp.d.ts → permission-policy-DGOvne7i.d.ts} +2 -2
- package/dist/{pipeline-BqiA_UMr.d.ts → pipeline-CqF7uju2.d.ts} +2 -2
- package/dist/{plan-templates-BdDxl9cI.d.ts → plan-templates-DoKhzenv.d.ts} +6 -6
- package/dist/{provider-runner-BUunikwY.d.ts → provider-runner-BPlI5sPZ.d.ts} +3 -3
- package/dist/{retry-policy-BcmuT_V0.d.ts → retry-policy-B4Q-FZgE.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -9
- package/dist/sdd/index.js +198 -0
- package/dist/sdd/index.js.map +1 -1
- package/dist/{secret-vault-DrOhc2i5.d.ts → secret-vault-B7GnL6o9.d.ts} +1 -1
- package/dist/security/index.d.ts +4 -4
- package/dist/{selector-C7wcdqMA.d.ts → selector-BakeMnWR.d.ts} +1 -1
- package/dist/{session-event-bridge-BpJ5trO9.d.ts → session-event-bridge-DE5Oekwx.d.ts} +1 -1
- package/dist/{session-reader-DDz1Ek4V.d.ts → session-reader-DFC81-4p.d.ts} +1 -1
- package/dist/storage/index.d.ts +12 -13
- package/dist/storage/index.js +147 -88
- package/dist/storage/index.js.map +1 -1
- package/dist/types/index.d.ts +20 -21
- package/dist/types/index.js +35 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +3 -4
- package/dist/utils/index.js +2 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/{wstack-paths-_lqjzErq.d.ts → wstack-paths-DD50Omgn.d.ts} +3 -0
- package/package.json +1 -1
- package/dist/models-registry-B6_KfS65.d.ts +0 -95
package/dist/defaults/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as crypto2 from 'crypto';
|
|
2
2
|
import { randomBytes, randomUUID, createCipheriv, createDecipheriv, createHash } from 'crypto';
|
|
3
3
|
import * as fsp from 'fs/promises';
|
|
4
|
-
import * as
|
|
4
|
+
import * as path11 from 'path';
|
|
5
5
|
import { isAbsolute, resolve } from 'path';
|
|
6
6
|
import * as fs5 from 'fs';
|
|
7
7
|
import * as os from 'os';
|
|
@@ -28,9 +28,9 @@ __export(atomic_write_exports, {
|
|
|
28
28
|
withFileLock: () => withFileLock
|
|
29
29
|
});
|
|
30
30
|
async function atomicWrite(targetPath, content, opts = {}) {
|
|
31
|
-
const dir =
|
|
31
|
+
const dir = path11.dirname(targetPath);
|
|
32
32
|
await fsp.mkdir(dir, { recursive: true });
|
|
33
|
-
const tmp =
|
|
33
|
+
const tmp = path11.join(dir, `.${path11.basename(targetPath)}.${randomBytes(6).toString("hex")}.tmp`);
|
|
34
34
|
try {
|
|
35
35
|
if (typeof content === "string") {
|
|
36
36
|
await fsp.writeFile(tmp, content, { flag: "wx", encoding: opts.encoding ?? "utf8" });
|
|
@@ -69,9 +69,9 @@ async function ensureDir(dir) {
|
|
|
69
69
|
await fsp.mkdir(dir, { recursive: true });
|
|
70
70
|
}
|
|
71
71
|
async function withFileLock(targetPath, fn, opts = {}) {
|
|
72
|
-
const dir =
|
|
72
|
+
const dir = path11.dirname(targetPath);
|
|
73
73
|
await fsp.mkdir(dir, { recursive: true });
|
|
74
|
-
const lockPath =
|
|
74
|
+
const lockPath = path11.join(dir, `.${path11.basename(targetPath)}.lock`);
|
|
75
75
|
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
76
76
|
const staleMs = opts.staleMs ?? 3e4;
|
|
77
77
|
const started = Date.now();
|
|
@@ -218,7 +218,7 @@ var DefaultLogger = class _DefaultLogger {
|
|
|
218
218
|
this.stderr = opts.stderr !== false;
|
|
219
219
|
if (this.file) {
|
|
220
220
|
try {
|
|
221
|
-
fs5.mkdirSync(
|
|
221
|
+
fs5.mkdirSync(path11.dirname(this.file), { recursive: true });
|
|
222
222
|
} catch {
|
|
223
223
|
}
|
|
224
224
|
}
|
|
@@ -414,11 +414,11 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
414
414
|
}
|
|
415
415
|
/** Absolute path to the session index file. */
|
|
416
416
|
get indexFile() {
|
|
417
|
-
return
|
|
417
|
+
return path11.join(this.dir, "_index.jsonl");
|
|
418
418
|
}
|
|
419
419
|
/** Join session ID to its absolute path within the store directory. */
|
|
420
420
|
sessionPath(id, ext) {
|
|
421
|
-
return
|
|
421
|
+
return path11.join(this.dir, `${id}${ext}`);
|
|
422
422
|
}
|
|
423
423
|
/**
|
|
424
424
|
* Ensure the directory implied by the session ID exists. When the ID
|
|
@@ -426,7 +426,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
426
426
|
* subdirectory so sessions group naturally by day.
|
|
427
427
|
*/
|
|
428
428
|
async ensureShardDir(id) {
|
|
429
|
-
const dirPath =
|
|
429
|
+
const dirPath = path11.dirname(path11.join(this.dir, id));
|
|
430
430
|
await ensureDir(dirPath);
|
|
431
431
|
return dirPath;
|
|
432
432
|
}
|
|
@@ -434,7 +434,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
434
434
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
435
435
|
const id = meta.id && meta.id.length > 0 ? meta.id : generateSessionId(startedAt, meta.model ?? meta.provider);
|
|
436
436
|
const shardDir = await this.ensureShardDir(id);
|
|
437
|
-
const file =
|
|
437
|
+
const file = path11.join(shardDir, `${path11.basename(id)}.jsonl`);
|
|
438
438
|
let handle;
|
|
439
439
|
try {
|
|
440
440
|
handle = await fsp.open(file, "a", 384);
|
|
@@ -642,7 +642,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
642
642
|
continue;
|
|
643
643
|
if (entry.isDirectory()) {
|
|
644
644
|
const childPrefix = depth === 0 ? entry.name : `${prefix}/${entry.name}`;
|
|
645
|
-
ids.push(...await this.collectSessionIds(
|
|
645
|
+
ids.push(...await this.collectSessionIds(path11.join(dir, entry.name), childPrefix, depth + 1));
|
|
646
646
|
} else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
647
647
|
if (entry.name === "_index.jsonl") continue;
|
|
648
648
|
const base = entry.name.replace(/\.jsonl$/, "");
|
|
@@ -676,12 +676,12 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
676
676
|
async deleteSession(id) {
|
|
677
677
|
await fsp.unlink(this.sessionPath(id, ".jsonl")).catch(() => void 0);
|
|
678
678
|
await fsp.unlink(this.sessionPath(id, ".summary.json")).catch(() => void 0);
|
|
679
|
-
const shardDir =
|
|
680
|
-
const base =
|
|
679
|
+
const shardDir = path11.dirname(path11.join(this.dir, id));
|
|
680
|
+
const base = path11.basename(id);
|
|
681
681
|
for (const ext of [".plan.json", ".todos.json"]) {
|
|
682
|
-
await fsp.unlink(
|
|
682
|
+
await fsp.unlink(path11.join(shardDir, `${base}${ext}`)).catch(() => void 0);
|
|
683
683
|
}
|
|
684
|
-
const sessDir =
|
|
684
|
+
const sessDir = path11.join(shardDir, base);
|
|
685
685
|
await fsp.rm(sessDir, { recursive: true, force: true }).catch(() => void 0);
|
|
686
686
|
await this.writeTombstone(id);
|
|
687
687
|
}
|
|
@@ -693,7 +693,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
693
693
|
let deleted = 0;
|
|
694
694
|
let activeSessionId = null;
|
|
695
695
|
try {
|
|
696
|
-
const raw = await fsp.readFile(
|
|
696
|
+
const raw = await fsp.readFile(path11.join(this.dir, "active.json"), "utf8");
|
|
697
697
|
const active = JSON.parse(raw);
|
|
698
698
|
activeSessionId = active.sessionId ?? null;
|
|
699
699
|
} catch {
|
|
@@ -701,11 +701,11 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
701
701
|
const entries = await fsp.readdir(this.dir, { withFileTypes: true }).catch(() => []);
|
|
702
702
|
for (const entry of entries) {
|
|
703
703
|
if (!entry.isDirectory()) continue;
|
|
704
|
-
const dateDir =
|
|
704
|
+
const dateDir = path11.join(this.dir, entry.name);
|
|
705
705
|
const files = await fsp.readdir(dateDir, { withFileTypes: true }).catch(() => []);
|
|
706
706
|
for (const file of files) {
|
|
707
707
|
if (!file.isFile() || !file.name.endsWith(".jsonl")) continue;
|
|
708
|
-
const jsonlPath =
|
|
708
|
+
const jsonlPath = path11.join(dateDir, file.name);
|
|
709
709
|
try {
|
|
710
710
|
const stat6 = await fsp.stat(jsonlPath);
|
|
711
711
|
if (stat6.mtimeMs >= cutoff) continue;
|
|
@@ -723,7 +723,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
723
723
|
}
|
|
724
724
|
for (const entry of entries) {
|
|
725
725
|
if (!entry.isDirectory()) continue;
|
|
726
|
-
const dateDir =
|
|
726
|
+
const dateDir = path11.join(this.dir, entry.name);
|
|
727
727
|
try {
|
|
728
728
|
const remaining = await fsp.readdir(dateDir);
|
|
729
729
|
if (remaining.length === 0) {
|
|
@@ -888,7 +888,7 @@ var FileSessionWriter = class {
|
|
|
888
888
|
this.meta = meta;
|
|
889
889
|
this.events = events;
|
|
890
890
|
this.resumed = opts.resumed ?? false;
|
|
891
|
-
this.manifestFile = opts.dir ?
|
|
891
|
+
this.manifestFile = opts.dir ? path11.join(opts.dir, `${path11.basename(id)}.summary.json`) : "";
|
|
892
892
|
this.filePath = opts.filePath ?? "";
|
|
893
893
|
this.secretScrubber = opts.secretScrubber;
|
|
894
894
|
this.onCloseCb = opts.onClose;
|
|
@@ -1211,7 +1211,7 @@ init_atomic_write();
|
|
|
1211
1211
|
var QueueStore = class {
|
|
1212
1212
|
file;
|
|
1213
1213
|
constructor(opts) {
|
|
1214
|
-
this.file =
|
|
1214
|
+
this.file = path11.join(opts.dir, "queue.json");
|
|
1215
1215
|
}
|
|
1216
1216
|
async write(items) {
|
|
1217
1217
|
if (items.length === 0) {
|
|
@@ -1281,7 +1281,7 @@ var DefaultAttachmentStore = class {
|
|
|
1281
1281
|
let data = input.data;
|
|
1282
1282
|
if (this.spoolDir && bytes >= this.spoolThreshold) {
|
|
1283
1283
|
await fsp.mkdir(this.spoolDir, { recursive: true });
|
|
1284
|
-
spooledPath =
|
|
1284
|
+
spooledPath = path11.join(this.spoolDir, `${id}.bin`);
|
|
1285
1285
|
await atomicWrite(spooledPath, input.data, {
|
|
1286
1286
|
encoding: input.kind === "image" ? "base64" : "utf8"
|
|
1287
1287
|
});
|
|
@@ -1493,7 +1493,7 @@ var FileMemoryBackend = class {
|
|
|
1493
1493
|
}
|
|
1494
1494
|
async remember(scope, entry, filePath) {
|
|
1495
1495
|
const file = this.resolveFile(filePath, scope);
|
|
1496
|
-
await ensureDir(
|
|
1496
|
+
await ensureDir(path11.dirname(file));
|
|
1497
1497
|
let existing = "";
|
|
1498
1498
|
try {
|
|
1499
1499
|
existing = await fsp.readFile(file, "utf8");
|
|
@@ -1510,39 +1510,41 @@ ${line}`;
|
|
|
1510
1510
|
}
|
|
1511
1511
|
async forget(scope, query, filePath) {
|
|
1512
1512
|
const file = this.resolveFile(filePath, scope);
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
const
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1513
|
+
return withFileLock(file, async () => {
|
|
1514
|
+
let existing;
|
|
1515
|
+
try {
|
|
1516
|
+
existing = await fsp.readFile(file, "utf8");
|
|
1517
|
+
} catch {
|
|
1518
|
+
return 0;
|
|
1519
|
+
}
|
|
1520
|
+
const needle = query.toLowerCase();
|
|
1521
|
+
const idMatcher = /mem_\d+_\w+/;
|
|
1522
|
+
let removed = 0;
|
|
1523
|
+
const lines = existing.split("\n").filter((line) => {
|
|
1524
|
+
const trimmed = line.trim();
|
|
1525
|
+
if (!trimmed.startsWith("- ")) return true;
|
|
1526
|
+
if (idMatcher.test(query)) {
|
|
1527
|
+
const entryIdMatch = /mem_\d+_\w+/.exec(trimmed);
|
|
1528
|
+
if (entryIdMatch && entryIdMatch[0] === query) {
|
|
1529
|
+
removed++;
|
|
1530
|
+
return false;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
if (trimmed.toLowerCase().includes(needle)) {
|
|
1528
1534
|
removed++;
|
|
1529
1535
|
return false;
|
|
1530
1536
|
}
|
|
1537
|
+
return true;
|
|
1538
|
+
});
|
|
1539
|
+
if (removed > 0) {
|
|
1540
|
+
if (lines.length === 0 || lines.length === 1 && !lines[0]?.trim()) {
|
|
1541
|
+
await atomicWrite(file, "");
|
|
1542
|
+
} else {
|
|
1543
|
+
await atomicWrite(file, lines.join("\n"));
|
|
1544
|
+
}
|
|
1531
1545
|
}
|
|
1532
|
-
|
|
1533
|
-
removed++;
|
|
1534
|
-
return false;
|
|
1535
|
-
}
|
|
1536
|
-
return true;
|
|
1546
|
+
return removed;
|
|
1537
1547
|
});
|
|
1538
|
-
if (removed > 0) {
|
|
1539
|
-
if (lines.length === 0 || lines.length === 1 && !lines[0]?.trim()) {
|
|
1540
|
-
await atomicWrite(file, "");
|
|
1541
|
-
} else {
|
|
1542
|
-
await atomicWrite(file, lines.join("\n"));
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
return removed;
|
|
1546
1548
|
}
|
|
1547
1549
|
async readAll(scope, filePath) {
|
|
1548
1550
|
const file = this.resolveFile(filePath, scope);
|
|
@@ -2255,12 +2257,14 @@ var DefaultConfigLoader = class {
|
|
|
2255
2257
|
}
|
|
2256
2258
|
async load(opts = {}) {
|
|
2257
2259
|
let cfg = { ...BEHAVIOR_DEFAULTS };
|
|
2258
|
-
const [global, local] = await Promise.all([
|
|
2260
|
+
const [global, local, inProject] = await Promise.all([
|
|
2259
2261
|
this.readJson(this.paths.globalConfig),
|
|
2260
|
-
this.readJson(this.paths.projectLocalConfig)
|
|
2262
|
+
this.readJson(this.paths.projectLocalConfig),
|
|
2263
|
+
this.readJson(this.paths.inProjectConfig)
|
|
2261
2264
|
]);
|
|
2262
2265
|
cfg = deepMerge(cfg, global);
|
|
2263
2266
|
cfg = deepMerge(cfg, local);
|
|
2267
|
+
cfg = deepMerge(cfg, inProject);
|
|
2264
2268
|
for (const [key, fn] of Object.entries(ENV_MAP)) {
|
|
2265
2269
|
const v = process.env[key];
|
|
2266
2270
|
if (v) fn(cfg, v);
|
|
@@ -2462,7 +2466,7 @@ var RecoveryLock = class {
|
|
|
2462
2466
|
sessionStore;
|
|
2463
2467
|
probe;
|
|
2464
2468
|
constructor(opts) {
|
|
2465
|
-
this.file =
|
|
2469
|
+
this.file = path11.join(opts.dir, LOCK_FILE);
|
|
2466
2470
|
this.pid = opts.pid ?? process.pid;
|
|
2467
2471
|
this.hostname = opts.hostname ?? os.hostname();
|
|
2468
2472
|
this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
|
|
@@ -2520,7 +2524,7 @@ var RecoveryLock = class {
|
|
|
2520
2524
|
* null return before calling this.
|
|
2521
2525
|
*/
|
|
2522
2526
|
async write(sessionId) {
|
|
2523
|
-
await ensureDir(
|
|
2527
|
+
await ensureDir(path11.dirname(this.file));
|
|
2524
2528
|
const lock = {
|
|
2525
2529
|
v: 1,
|
|
2526
2530
|
sessionId,
|
|
@@ -3753,7 +3757,7 @@ var DefaultSecretVault = class {
|
|
|
3753
3757
|
} catch (err) {
|
|
3754
3758
|
if (err.code !== "ENOENT") throw err;
|
|
3755
3759
|
}
|
|
3756
|
-
fs5.mkdirSync(
|
|
3760
|
+
fs5.mkdirSync(path11.dirname(this.keyFile), { recursive: true });
|
|
3757
3761
|
const key = randomBytes(KEY_BYTES);
|
|
3758
3762
|
try {
|
|
3759
3763
|
fs5.writeFileSync(this.keyFile, key, { mode: 384, flag: "wx" });
|
|
@@ -3822,7 +3826,7 @@ async function rewriteConfigEncrypted(configPath, vault, patch) {
|
|
|
3822
3826
|
}
|
|
3823
3827
|
const merged = deepMerge2(current, patch ?? {});
|
|
3824
3828
|
const encrypted = encryptConfigSecrets(merged, vault);
|
|
3825
|
-
await fsp.mkdir(
|
|
3829
|
+
await fsp.mkdir(path11.dirname(configPath), { recursive: true });
|
|
3826
3830
|
await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
3827
3831
|
await restrictFilePermissions(configPath);
|
|
3828
3832
|
}
|
|
@@ -4063,9 +4067,9 @@ function getInputString(input, key) {
|
|
|
4063
4067
|
function pathLooksInsideProject(rawPath, projectRoot) {
|
|
4064
4068
|
if (!projectRoot) return false;
|
|
4065
4069
|
if (rawPath === "~" || rawPath.startsWith("~/") || rawPath.startsWith("~\\")) return false;
|
|
4066
|
-
const resolved =
|
|
4067
|
-
const relative2 =
|
|
4068
|
-
return !!relative2 && !relative2.startsWith("..") && !
|
|
4070
|
+
const resolved = path11.resolve(projectRoot, rawPath);
|
|
4071
|
+
const relative2 = path11.relative(projectRoot, resolved);
|
|
4072
|
+
return !!relative2 && !relative2.startsWith("..") && !path11.isAbsolute(relative2);
|
|
4069
4073
|
}
|
|
4070
4074
|
function tokenizeShell(command) {
|
|
4071
4075
|
return command.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token) => token.replace(/^['"]|['"]$/g, "")) ?? [];
|
|
@@ -4075,7 +4079,7 @@ function pathTokenIsOutsideProject(token, projectRoot) {
|
|
|
4075
4079
|
if (token === "/" || token === "~" || token === "." || token === "..") return token !== ".";
|
|
4076
4080
|
if (token.includes("*")) return true;
|
|
4077
4081
|
if (token.startsWith("..") || token.includes("../") || token.includes("..\\")) return true;
|
|
4078
|
-
if (
|
|
4082
|
+
if (path11.isAbsolute(token) || token.startsWith("~/")) return !pathLooksInsideProject(token, projectRoot);
|
|
4079
4083
|
return false;
|
|
4080
4084
|
}
|
|
4081
4085
|
function hasDangerousDeleteTarget(tokens, start, projectRoot) {
|
|
@@ -4612,6 +4616,7 @@ var DefaultRetryPolicy = class {
|
|
|
4612
4616
|
if (err instanceof ProviderError) {
|
|
4613
4617
|
if (err.status === 429) return 5;
|
|
4614
4618
|
if (err.status === 529) return 3;
|
|
4619
|
+
if (err.status === 599) return 5;
|
|
4615
4620
|
if (err.status >= 500) return 3;
|
|
4616
4621
|
return 0;
|
|
4617
4622
|
}
|
|
@@ -4731,7 +4736,7 @@ var DefaultSkillLoader = class {
|
|
|
4731
4736
|
const entries = await fsp.readdir(dir, { withFileTypes: true });
|
|
4732
4737
|
for (const e of entries) {
|
|
4733
4738
|
if (!e.isDirectory()) continue;
|
|
4734
|
-
const skillFile =
|
|
4739
|
+
const skillFile = path11.join(dir, e.name, "SKILL.md");
|
|
4735
4740
|
try {
|
|
4736
4741
|
const raw = await fsp.readFile(skillFile, "utf8");
|
|
4737
4742
|
const meta = parseFrontmatter(raw);
|
|
@@ -7037,25 +7042,82 @@ var AutonomousRunner = class {
|
|
|
7037
7042
|
|
|
7038
7043
|
// src/storage/goal-store.ts
|
|
7039
7044
|
init_atomic_write();
|
|
7045
|
+
function projectHash(absRoot) {
|
|
7046
|
+
return createHash("sha256").update(path11.resolve(absRoot)).digest("hex").slice(0, 12);
|
|
7047
|
+
}
|
|
7048
|
+
function projectSlug(absRoot) {
|
|
7049
|
+
const base = slugify(path11.basename(absRoot));
|
|
7050
|
+
const hash = createHash("sha256").update(path11.resolve(absRoot)).digest("hex").slice(0, 6);
|
|
7051
|
+
return `${base}-${hash}`;
|
|
7052
|
+
}
|
|
7053
|
+
function slugify(name) {
|
|
7054
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40) || "project";
|
|
7055
|
+
}
|
|
7056
|
+
function resolveWstackPaths(opts) {
|
|
7057
|
+
const home = opts.userHome ?? os.homedir();
|
|
7058
|
+
const globalRoot = opts.globalRoot ?? path11.join(home, ".wrongstack");
|
|
7059
|
+
const hash = projectHash(opts.projectRoot);
|
|
7060
|
+
const slug = projectSlug(opts.projectRoot);
|
|
7061
|
+
const projectDir = path11.join(globalRoot, "projects", slug);
|
|
7062
|
+
return {
|
|
7063
|
+
globalRoot,
|
|
7064
|
+
configDir: globalRoot,
|
|
7065
|
+
globalConfig: path11.join(globalRoot, "config.json"),
|
|
7066
|
+
secretsKey: path11.join(globalRoot, ".key"),
|
|
7067
|
+
globalMemory: path11.join(globalRoot, "memory.md"),
|
|
7068
|
+
globalSkills: path11.join(globalRoot, "skills"),
|
|
7069
|
+
globalPrompts: path11.join(globalRoot, "prompts"),
|
|
7070
|
+
cacheDir: path11.join(globalRoot, "cache"),
|
|
7071
|
+
modelsCache: path11.join(globalRoot, "cache", "models.dev.json"),
|
|
7072
|
+
modelsOverlayCache: path11.join(globalRoot, "cache", "models-overlay.json"),
|
|
7073
|
+
historyFile: path11.join(globalRoot, "history"),
|
|
7074
|
+
logFile: path11.join(globalRoot, "logs", "wrongstack.log"),
|
|
7075
|
+
projectDir,
|
|
7076
|
+
projectCodebaseIndex: path11.join(projectDir, "codebase-index"),
|
|
7077
|
+
projectMemory: path11.join(projectDir, "memory.md"),
|
|
7078
|
+
projectSessions: path11.join(projectDir, "sessions"),
|
|
7079
|
+
projectTrust: path11.join(projectDir, "trust.json"),
|
|
7080
|
+
projectMeta: path11.join(projectDir, "meta.json"),
|
|
7081
|
+
projectLocalConfig: path11.join(projectDir, "config.local.json"),
|
|
7082
|
+
inProjectConfig: path11.join(opts.projectRoot, ".wrongstack", "config.json"),
|
|
7083
|
+
inProjectAgentsFile: path11.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
|
|
7084
|
+
inProjectSkills: path11.join(opts.projectRoot, ".wrongstack", "skills"),
|
|
7085
|
+
inProjectWorktrees: path11.join(opts.projectRoot, ".wrongstack", "worktrees"),
|
|
7086
|
+
projectHash: hash,
|
|
7087
|
+
projectSlug: slug,
|
|
7088
|
+
projectGoal: path11.join(projectDir, "goal.json"),
|
|
7089
|
+
projectSpecs: path11.join(projectDir, "specs"),
|
|
7090
|
+
projectTaskGraphs: path11.join(projectDir, "task-graphs"),
|
|
7091
|
+
projectSddSession: path11.join(projectDir, "sdd-session.json"),
|
|
7092
|
+
projectPlan: path11.join(projectDir, "plan.json"),
|
|
7093
|
+
projectAutophase: path11.join(projectDir, "autophase"),
|
|
7094
|
+
syncConfig: path11.join(globalRoot, "sync.json")
|
|
7095
|
+
};
|
|
7096
|
+
}
|
|
7097
|
+
|
|
7098
|
+
// src/storage/goal-store.ts
|
|
7040
7099
|
var MAX_JOURNAL_ENTRIES = 500;
|
|
7041
7100
|
function goalFilePath(projectRoot) {
|
|
7042
|
-
|
|
7043
|
-
return path3.join(os.homedir(), ".wrongstack", "projects", hash, "goal.json");
|
|
7101
|
+
return resolveWstackPaths({ projectRoot }).projectGoal;
|
|
7044
7102
|
}
|
|
7045
7103
|
async function loadGoal(filePath) {
|
|
7046
7104
|
let raw;
|
|
7047
7105
|
try {
|
|
7048
7106
|
raw = await fsp.readFile(filePath, "utf8");
|
|
7049
|
-
} catch {
|
|
7050
|
-
|
|
7107
|
+
} catch (err) {
|
|
7108
|
+
const code = err.code;
|
|
7109
|
+
if (code === "ENOENT") return null;
|
|
7110
|
+
throw err;
|
|
7051
7111
|
}
|
|
7052
7112
|
try {
|
|
7053
7113
|
const parsed = JSON.parse(raw);
|
|
7054
7114
|
if (parsed?.version !== 1 || typeof parsed.goal !== "string" || !Array.isArray(parsed.journal)) {
|
|
7115
|
+
console.warn(`[goal-store] Corrupt goal.json at ${filePath} \u2014 invalid schema. Consider deleting it and re-creating.`);
|
|
7055
7116
|
return null;
|
|
7056
7117
|
}
|
|
7057
7118
|
return parsed;
|
|
7058
7119
|
} catch {
|
|
7120
|
+
console.warn(`[goal-store] Corrupt goal.json at ${filePath} \u2014 JSON parse failed. Consider deleting it and re-creating.`);
|
|
7059
7121
|
return null;
|
|
7060
7122
|
}
|
|
7061
7123
|
}
|
|
@@ -7109,7 +7171,7 @@ function computeTrend(history) {
|
|
|
7109
7171
|
const recent = history.slice(-5);
|
|
7110
7172
|
const deltas = [];
|
|
7111
7173
|
for (let i = 1; i < recent.length; i++) {
|
|
7112
|
-
deltas.push(recent[i]
|
|
7174
|
+
deltas.push((recent[i]?.progress ?? 0) - (recent[i - 1]?.progress ?? 0));
|
|
7113
7175
|
}
|
|
7114
7176
|
if (deltas.length < 2) return void 0;
|
|
7115
7177
|
const avgDelta = deltas.reduce((a, b) => a + b, 0) / deltas.length;
|
|
@@ -7701,8 +7763,8 @@ ${recentJournal}` : "No prior iterations.",
|
|
|
7701
7763
|
await saveGoal(this.goalPath, abandoned);
|
|
7702
7764
|
}
|
|
7703
7765
|
try {
|
|
7704
|
-
const { unlink:
|
|
7705
|
-
await
|
|
7766
|
+
const { unlink: unlink10 } = await import('fs/promises');
|
|
7767
|
+
await unlink10(this.goalPath);
|
|
7706
7768
|
} catch {
|
|
7707
7769
|
}
|
|
7708
7770
|
this.opts.onEternalStop?.();
|
|
@@ -8703,6 +8765,53 @@ Working rules:
|
|
|
8703
8765
|
"flaws"
|
|
8704
8766
|
]
|
|
8705
8767
|
}
|
|
8768
|
+
},
|
|
8769
|
+
{
|
|
8770
|
+
config: {
|
|
8771
|
+
id: "refactor-planner",
|
|
8772
|
+
name: "Refactor Planner",
|
|
8773
|
+
role: "refactor-planner",
|
|
8774
|
+
tools: [...PLAN_TOOLS, "diff"],
|
|
8775
|
+
prompt: `You are the Refactor Planner agent. Your job is to analyze code
|
|
8776
|
+
structure and produce a concrete, phased refactoring plan with risk
|
|
8777
|
+
assessment, dependency ordering, and rollback strategy.
|
|
8778
|
+
|
|
8779
|
+
Scope:
|
|
8780
|
+
- Map module-level dependencies (import graph)
|
|
8781
|
+
- Identify coupling hotspots (high fan-in/out modules)
|
|
8782
|
+
- Assess refactoring risk by complexity and test coverage
|
|
8783
|
+
- Generate phased plans with checkpoint milestones
|
|
8784
|
+
- Produce diff-friendly task lists (one task = one concern)
|
|
8785
|
+
|
|
8786
|
+
Input format you accept:
|
|
8787
|
+
{ "task": "plan | assess | roadmap", "target": "src/core", "constraint": "no-breaking-changes | minimal-downtime | full-rewrite", "focus": "architecture | performance | maintainability" }
|
|
8788
|
+
|
|
8789
|
+
Output: Markdown refactor plan with phases (Low Risk / Medium Risk / High Risk),
|
|
8790
|
+
dependency graph, rollback strategy, and exit criteria.
|
|
8791
|
+
|
|
8792
|
+
Working rules:
|
|
8793
|
+
- Always include rollback strategy \u2014 every refactor can fail
|
|
8794
|
+
- Merge tasks that take <1h into a single phase
|
|
8795
|
+
- Respect team constraints (reviewer availability, parallelization)
|
|
8796
|
+
- Never plan without analyzing the actual code first`
|
|
8797
|
+
},
|
|
8798
|
+
budget: HEAVY_BUDGET,
|
|
8799
|
+
capability: {
|
|
8800
|
+
phase: "planning",
|
|
8801
|
+
summary: "Refactoring planner: analyzes code structure, maps dependencies, produces risk-scored phased plans with rollback strategy.",
|
|
8802
|
+
keywords: [
|
|
8803
|
+
"refactor",
|
|
8804
|
+
"refactoring",
|
|
8805
|
+
"restructure",
|
|
8806
|
+
"debt",
|
|
8807
|
+
"technical debt",
|
|
8808
|
+
"clean up",
|
|
8809
|
+
"modularize",
|
|
8810
|
+
"decouple",
|
|
8811
|
+
"dependency graph",
|
|
8812
|
+
"code structure"
|
|
8813
|
+
]
|
|
8814
|
+
}
|
|
8706
8815
|
}
|
|
8707
8816
|
];
|
|
8708
8817
|
|
|
@@ -9242,6 +9351,157 @@ Working rules:
|
|
|
9242
9351
|
"robustness"
|
|
9243
9352
|
]
|
|
9244
9353
|
}
|
|
9354
|
+
},
|
|
9355
|
+
{
|
|
9356
|
+
config: {
|
|
9357
|
+
id: "security-scanner",
|
|
9358
|
+
name: "Security Scanner",
|
|
9359
|
+
role: "security-scanner",
|
|
9360
|
+
tools: [...TOOLS.inspect],
|
|
9361
|
+
prompt: `You are the Security Scanner agent. Your job is to scan code,
|
|
9362
|
+
configs, and dependencies for security issues from hardcoded secrets to
|
|
9363
|
+
supply chain risks.
|
|
9364
|
+
|
|
9365
|
+
Scope:
|
|
9366
|
+
- Detect hardcoded secrets: API keys, tokens, passwords, private keys
|
|
9367
|
+
- Find injection vectors: eval, innerHTML, SQL concat, shell injection
|
|
9368
|
+
- Identify insecure patterns: weak crypto, hardcoded IVs, disabled TLS
|
|
9369
|
+
- Scan dependencies for known CVEs (via npm/pnpm audit)
|
|
9370
|
+
- Flag supply chain risks: postinstall hooks, unverified scripts
|
|
9371
|
+
|
|
9372
|
+
Input format you accept:
|
|
9373
|
+
{ "task": "scan | audit | secrets | dependencies", "paths": ["src", "config"], "depth": "quick | normal | deep" }
|
|
9374
|
+
|
|
9375
|
+
Output: Markdown security report with severity-ranked findings, injection
|
|
9376
|
+
vectors, dependency issues, and a remediation checklist.
|
|
9377
|
+
|
|
9378
|
+
Working rules:
|
|
9379
|
+
- Never scan node_modules \u2014 use npm audit instead
|
|
9380
|
+
- Always provide remediation steps, not just findings
|
|
9381
|
+
- Verify regex-based secrets before flagging (false positive risk)
|
|
9382
|
+
- When in doubt, flag as medium rather than ignoring potential issues`
|
|
9383
|
+
},
|
|
9384
|
+
budget: HEAVY_BUDGET,
|
|
9385
|
+
capability: {
|
|
9386
|
+
phase: "verify",
|
|
9387
|
+
summary: "Security scanner: detects hardcoded secrets, injection vectors, insecure patterns, and supply-chain risks with remediation.",
|
|
9388
|
+
keywords: [
|
|
9389
|
+
"security",
|
|
9390
|
+
"scan",
|
|
9391
|
+
"vulnerability",
|
|
9392
|
+
"secret",
|
|
9393
|
+
"api key",
|
|
9394
|
+
"hardcoded",
|
|
9395
|
+
"injection",
|
|
9396
|
+
"cve",
|
|
9397
|
+
"audit dependencies",
|
|
9398
|
+
"supply chain",
|
|
9399
|
+
"xss",
|
|
9400
|
+
"sqli",
|
|
9401
|
+
"shell injection",
|
|
9402
|
+
"sensitive data",
|
|
9403
|
+
"credential"
|
|
9404
|
+
]
|
|
9405
|
+
}
|
|
9406
|
+
},
|
|
9407
|
+
{
|
|
9408
|
+
config: {
|
|
9409
|
+
id: "bug-hunter",
|
|
9410
|
+
name: "Bug Hunter",
|
|
9411
|
+
role: "bug-hunter",
|
|
9412
|
+
tools: [...TOOLS.inspect],
|
|
9413
|
+
prompt: `You are the Bug Hunter agent. Your job is to systematically scan
|
|
9414
|
+
source code for bugs, anti-patterns, and code smells using pattern matching
|
|
9415
|
+
and heuristics. Output a prioritized hit list with file:line references.
|
|
9416
|
+
|
|
9417
|
+
Scope:
|
|
9418
|
+
- Detect common bug patterns (uncaught errors, resource leaks, race conditions)
|
|
9419
|
+
- Identify anti-patterns (callback hell, God objects, circular deps)
|
|
9420
|
+
- Find TypeScript-specific issues (unsafe any, missing null checks, branded types)
|
|
9421
|
+
- Flag security-sensitive constructs (eval, innerHTML, hardcoded secrets)
|
|
9422
|
+
- Rank findings: critical > high > medium > low
|
|
9423
|
+
|
|
9424
|
+
Input format you accept:
|
|
9425
|
+
{ "task": "scan | hunt | check", "paths": ["src/**/*.ts"], "focus": "bugs | patterns | security | all", "severityThreshold": "medium" }
|
|
9426
|
+
|
|
9427
|
+
Output: Markdown bug hunt report with critically/high/medium/low sections.
|
|
9428
|
+
Each entry: **[TYPE]** \`file:line\` \u2014 description + suggested fix
|
|
9429
|
+
|
|
9430
|
+
Working rules:
|
|
9431
|
+
- Never scan node_modules \u2014 it's noise
|
|
9432
|
+
- Always include file:line for every finding
|
|
9433
|
+
- If >30% of findings are false positives, note the confidence level
|
|
9434
|
+
- Ask director for clarification if paths are ambiguous`
|
|
9435
|
+
},
|
|
9436
|
+
budget: HEAVY_BUDGET,
|
|
9437
|
+
capability: {
|
|
9438
|
+
phase: "verify",
|
|
9439
|
+
summary: "Bug hunter: scans source code for bugs, anti-patterns, and code smells, producing a file:line-ranked hit list with fixes.",
|
|
9440
|
+
keywords: [
|
|
9441
|
+
"bug",
|
|
9442
|
+
"hunt",
|
|
9443
|
+
"scan",
|
|
9444
|
+
"code smell",
|
|
9445
|
+
"anti-pattern",
|
|
9446
|
+
"race condition",
|
|
9447
|
+
"memory leak",
|
|
9448
|
+
"null deref",
|
|
9449
|
+
"type safety",
|
|
9450
|
+
"unhandled error",
|
|
9451
|
+
"find bugs",
|
|
9452
|
+
"audit code",
|
|
9453
|
+
"code quality"
|
|
9454
|
+
]
|
|
9455
|
+
}
|
|
9456
|
+
},
|
|
9457
|
+
{
|
|
9458
|
+
config: {
|
|
9459
|
+
id: "audit-log",
|
|
9460
|
+
name: "Audit Log",
|
|
9461
|
+
role: "audit-log",
|
|
9462
|
+
tools: [...TOOLS.inspect],
|
|
9463
|
+
prompt: `You are the Audit Log agent. Your job is to analyze structured JSONL
|
|
9464
|
+
session logs and produce actionable markdown reports.
|
|
9465
|
+
|
|
9466
|
+
Scope:
|
|
9467
|
+
- Parse session logs (iteration counts, tool calls, errors, usage)
|
|
9468
|
+
- Detect repeated failure patterns across multiple runs
|
|
9469
|
+
- Identify tool usage anomalies (over-use, failures, unexpected chains)
|
|
9470
|
+
- Track token consumption trends
|
|
9471
|
+
- Generate structured audit reports with severity ratings
|
|
9472
|
+
|
|
9473
|
+
Input format you accept:
|
|
9474
|
+
{ "task": "analyze | report | trends", "sessionPath": "<path>", "focus": "errors | tools | usage | all" }
|
|
9475
|
+
|
|
9476
|
+
Output: Markdown audit report with Summary, Top Errors, Tool Usage table,
|
|
9477
|
+
Anomalies, and Cost Trend sections.
|
|
9478
|
+
|
|
9479
|
+
Working rules:
|
|
9480
|
+
- Never fabricate numbers \u2014 read the actual logs first
|
|
9481
|
+
- Always include file:line references for errors
|
|
9482
|
+
- If sessionPath is missing, ask the director to provide it
|
|
9483
|
+
- Report confidence level: high (>90% accuracy), medium, low`
|
|
9484
|
+
},
|
|
9485
|
+
budget: MEDIUM_BUDGET,
|
|
9486
|
+
capability: {
|
|
9487
|
+
phase: "verify",
|
|
9488
|
+
summary: "Audit log analyzer: parses session JSONL, detects failure patterns, tool anomalies, and cost trends with structured reports.",
|
|
9489
|
+
keywords: [
|
|
9490
|
+
"audit",
|
|
9491
|
+
"log",
|
|
9492
|
+
"logs",
|
|
9493
|
+
"session",
|
|
9494
|
+
"trace",
|
|
9495
|
+
"analyze logs",
|
|
9496
|
+
"error patterns",
|
|
9497
|
+
"cost analysis",
|
|
9498
|
+
"tool usage",
|
|
9499
|
+
"token usage",
|
|
9500
|
+
"post-mortem",
|
|
9501
|
+
"trend",
|
|
9502
|
+
"anomaly"
|
|
9503
|
+
]
|
|
9504
|
+
}
|
|
9245
9505
|
}
|
|
9246
9506
|
];
|
|
9247
9507
|
|
|
@@ -14900,7 +15160,7 @@ var Director = class _Director {
|
|
|
14900
15160
|
})),
|
|
14901
15161
|
usage: this.usage.snapshot()
|
|
14902
15162
|
};
|
|
14903
|
-
await fsp.mkdir(
|
|
15163
|
+
await fsp.mkdir(path11.dirname(this.manifestPath), { recursive: true });
|
|
14904
15164
|
await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
|
|
14905
15165
|
return this.manifestPath;
|
|
14906
15166
|
}
|
|
@@ -15106,7 +15366,7 @@ var Director = class _Director {
|
|
|
15106
15366
|
*/
|
|
15107
15367
|
async readSession(subagentId, tail) {
|
|
15108
15368
|
if (!this.sessionsRoot) return null;
|
|
15109
|
-
const filePath =
|
|
15369
|
+
const filePath = path11.join(this.sessionsRoot, this.directorRunId, `${subagentId}.jsonl`);
|
|
15110
15370
|
let raw;
|
|
15111
15371
|
try {
|
|
15112
15372
|
raw = await fsp.readFile(filePath, "utf8");
|
|
@@ -15630,13 +15890,13 @@ async function readSubagentPartial(opts, subagentId) {
|
|
|
15630
15890
|
if (!opts.sessionsRoot) return void 0;
|
|
15631
15891
|
const candidates = [];
|
|
15632
15892
|
if (opts.directorRunId) {
|
|
15633
|
-
candidates.push(
|
|
15893
|
+
candidates.push(path11.join(opts.sessionsRoot, opts.directorRunId, `${subagentId}.jsonl`));
|
|
15634
15894
|
} else {
|
|
15635
15895
|
try {
|
|
15636
15896
|
const entries = await fsp.readdir(opts.sessionsRoot, { withFileTypes: true });
|
|
15637
15897
|
for (const entry of entries) {
|
|
15638
15898
|
if (entry.isDirectory()) {
|
|
15639
|
-
candidates.push(
|
|
15899
|
+
candidates.push(path11.join(opts.sessionsRoot, entry.name, `${subagentId}.jsonl`));
|
|
15640
15900
|
}
|
|
15641
15901
|
}
|
|
15642
15902
|
} catch {
|
|
@@ -15685,9 +15945,9 @@ function makeDirectorSessionFactory(opts) {
|
|
|
15685
15945
|
let dir;
|
|
15686
15946
|
if (opts.store) {
|
|
15687
15947
|
store = opts.store;
|
|
15688
|
-
dir = opts.sessionsRoot ?
|
|
15948
|
+
dir = opts.sessionsRoot ? path11.join(opts.sessionsRoot, runId) : "(caller-managed)";
|
|
15689
15949
|
} else if (opts.sessionsRoot) {
|
|
15690
|
-
dir =
|
|
15950
|
+
dir = path11.join(opts.sessionsRoot, runId);
|
|
15691
15951
|
store = new DefaultSessionStore({ dir });
|
|
15692
15952
|
} else {
|
|
15693
15953
|
throw new Error("makeDirectorSessionFactory requires either `store` or `sessionsRoot`");
|
|
@@ -15894,7 +16154,7 @@ var DefaultModelsRegistry = class {
|
|
|
15894
16154
|
this.overlay = opts.overlay;
|
|
15895
16155
|
this.overlayUrl = opts.overlayUrl;
|
|
15896
16156
|
this.overlayFile = opts.overlayFile;
|
|
15897
|
-
this.overlayCacheFile = opts.overlayCacheFile ?? (opts.overlayUrl ?
|
|
16157
|
+
this.overlayCacheFile = opts.overlayCacheFile ?? (opts.overlayUrl ? path11.join(path11.dirname(opts.cacheFile), "models-overlay-cache.json") : void 0);
|
|
15898
16158
|
}
|
|
15899
16159
|
async load(opts = {}) {
|
|
15900
16160
|
if (this.payload && !opts.force) return this.payload;
|
|
@@ -16107,7 +16367,7 @@ var DefaultModelsRegistry = class {
|
|
|
16107
16367
|
}
|
|
16108
16368
|
/** Used by `wstack models refresh` to expose where the cache lives. */
|
|
16109
16369
|
cacheLocation() {
|
|
16110
|
-
return
|
|
16370
|
+
return path11.resolve(this.cacheFile);
|
|
16111
16371
|
}
|
|
16112
16372
|
};
|
|
16113
16373
|
function hasEntries(payload) {
|
|
@@ -16403,7 +16663,7 @@ var DefaultModeStore = class {
|
|
|
16403
16663
|
}
|
|
16404
16664
|
async loadActiveMode() {
|
|
16405
16665
|
try {
|
|
16406
|
-
const configPath =
|
|
16666
|
+
const configPath = path11.join(this.configDir, "mode.json");
|
|
16407
16667
|
const content = await fsp.readFile(configPath, "utf8");
|
|
16408
16668
|
const data = JSON.parse(content);
|
|
16409
16669
|
this.activeModeId = data.activeMode ?? null;
|
|
@@ -16414,7 +16674,7 @@ var DefaultModeStore = class {
|
|
|
16414
16674
|
async saveActiveMode() {
|
|
16415
16675
|
try {
|
|
16416
16676
|
await fsp.mkdir(this.configDir, { recursive: true });
|
|
16417
|
-
const configPath =
|
|
16677
|
+
const configPath = path11.join(this.configDir, "mode.json");
|
|
16418
16678
|
await atomicWrite(
|
|
16419
16679
|
configPath,
|
|
16420
16680
|
JSON.stringify({ activeMode: this.activeModeId }, null, 2)
|
|
@@ -16429,11 +16689,11 @@ async function loadProjectModes(modesDir) {
|
|
|
16429
16689
|
const entries = await fsp.readdir(modesDir);
|
|
16430
16690
|
for (const entry of entries) {
|
|
16431
16691
|
if (!entry.endsWith(".md") && !entry.endsWith(".txt")) continue;
|
|
16432
|
-
const filePath =
|
|
16692
|
+
const filePath = path11.join(modesDir, entry);
|
|
16433
16693
|
const stat6 = await fsp.stat(filePath);
|
|
16434
16694
|
if (!stat6.isFile()) continue;
|
|
16435
16695
|
const content = await fsp.readFile(filePath, "utf8");
|
|
16436
|
-
const id =
|
|
16696
|
+
const id = path11.basename(entry, path11.extname(entry));
|
|
16437
16697
|
modes.push({
|
|
16438
16698
|
id,
|
|
16439
16699
|
name: id.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
|
|
@@ -16449,7 +16709,7 @@ async function loadProjectModes(modesDir) {
|
|
|
16449
16709
|
async function loadUserModes(modesDir) {
|
|
16450
16710
|
const modes = [];
|
|
16451
16711
|
try {
|
|
16452
|
-
const manifestPath =
|
|
16712
|
+
const manifestPath = path11.join(modesDir, "modes.json");
|
|
16453
16713
|
const content = await fsp.readFile(manifestPath, "utf8");
|
|
16454
16714
|
const manifest = JSON.parse(content);
|
|
16455
16715
|
for (const mode of manifest.modes) {
|
|
@@ -17366,7 +17626,7 @@ var SpecStore = class {
|
|
|
17366
17626
|
indexPath;
|
|
17367
17627
|
constructor(opts) {
|
|
17368
17628
|
this.baseDir = opts.baseDir;
|
|
17369
|
-
this.indexPath =
|
|
17629
|
+
this.indexPath = path11.join(this.baseDir, "_index.json");
|
|
17370
17630
|
}
|
|
17371
17631
|
async save(spec) {
|
|
17372
17632
|
await ensureDir(this.baseDir);
|
|
@@ -17435,7 +17695,7 @@ var SpecStore = class {
|
|
|
17435
17695
|
return updated;
|
|
17436
17696
|
}
|
|
17437
17697
|
filePath(id) {
|
|
17438
|
-
return
|
|
17698
|
+
return path11.join(this.baseDir, `${id}.json`);
|
|
17439
17699
|
}
|
|
17440
17700
|
async readIndex() {
|
|
17441
17701
|
try {
|
|
@@ -17492,7 +17752,7 @@ var TaskGraphStore = class {
|
|
|
17492
17752
|
indexPath;
|
|
17493
17753
|
constructor(opts) {
|
|
17494
17754
|
this.baseDir = opts.baseDir;
|
|
17495
|
-
this.indexPath =
|
|
17755
|
+
this.indexPath = path11.join(this.baseDir, "_index.json");
|
|
17496
17756
|
}
|
|
17497
17757
|
async save(graph) {
|
|
17498
17758
|
await ensureDir(this.baseDir);
|
|
@@ -17530,7 +17790,7 @@ var TaskGraphStore = class {
|
|
|
17530
17790
|
}
|
|
17531
17791
|
}
|
|
17532
17792
|
filePath(id) {
|
|
17533
|
-
return
|
|
17793
|
+
return path11.join(this.baseDir, `${id}.json`);
|
|
17534
17794
|
}
|
|
17535
17795
|
async readIndex() {
|
|
17536
17796
|
try {
|