@wrongstack/core 0.277.1 → 0.280.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-bridge-BFJ2ODzI.d.ts → agent-bridge-DXC6QDJ4.d.ts} +1 -1
- package/dist/{agent-subagent-runner-BimKihiC.d.ts → agent-subagent-runner-PoqNKiR4.d.ts} +563 -471
- package/dist/{compactor-D3BGw26y.d.ts → compactor-U3agvUIG.d.ts} +1 -1
- package/dist/{config-DAOjriz9.d.ts → config-Cr3312zc.d.ts} +102 -4
- package/dist/coordination/index.d.ts +1087 -998
- package/dist/coordination/index.js +12235 -12052
- package/dist/coordination/index.js.map +1 -1
- package/dist/defaults/index.d.ts +31 -30
- package/dist/defaults/index.js +403 -189
- package/dist/defaults/index.js.map +1 -1
- package/dist/{brain-CCfuEOdp.d.ts → events-Bs2fmldo.d.ts} +117 -112
- package/dist/execution/index.d.ts +27 -19
- package/dist/execution/index.js +216 -63
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +1 -1
- package/dist/execution/prompt-enhancer.js.map +1 -1
- package/dist/extension/index.d.ts +8 -7
- package/dist/{global-mailbox-Dr4cTKqL.d.ts → global-mailbox-Ct7IorLJ.d.ts} +84 -6
- package/dist/{goal-store-C1uH4srH.d.ts → goal-store-C4F6DjC0.d.ts} +1 -1
- package/dist/hq/index.d.ts +504 -7
- package/dist/hq/index.js +1069 -20
- package/dist/hq/index.js.map +1 -1
- package/dist/{index-DJXj-dcr.d.ts → index-kidebiDh.d.ts} +8 -5
- package/dist/{index-cMEmzCVN.d.ts → index-nP09-oP2.d.ts} +2 -2
- package/dist/index.d.ts +153 -76
- package/dist/index.js +5791 -3163
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +7 -6
- package/dist/kernel/index.d.ts +14 -13
- package/dist/kernel/index.js +31 -15
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mailbox-types-DTl7bRH3.d.ts → mailbox-types-BGZWrYTJ.d.ts} +38 -0
- package/dist/{mcp-servers-CFb60-pH.d.ts → mcp-servers-D910X5_r.d.ts} +3 -3
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js.map +1 -1
- package/dist/{models-registry-5Ufn7f2m.d.ts → models-registry-CLkoOcHk.d.ts} +1 -1
- package/dist/{multi-agent-coordinator-CcrcncvG.d.ts → multi-agent-coordinator-CieyUoEL.d.ts} +1 -1
- package/dist/{null-fleet-bus-C9KsYyrI.d.ts → null-fleet-bus-DkdmZJ_W.d.ts} +464 -464
- package/dist/observability/index.d.ts +3 -2
- package/dist/{path-resolver-CEeX9I7O.d.ts → path-resolver-XfZ9eLxG.d.ts} +3 -3
- package/dist/{permission-DbsGOA1C.d.ts → permission-Dx6dIqS2.d.ts} +2 -7
- package/dist/{permission-policy-BpEea3r7.d.ts → permission-policy-C8vJcnX5.d.ts} +2 -2
- package/dist/{pipeline-CEjBjzVA.d.ts → pipeline-BwAP21_4.d.ts} +9 -4
- package/dist/{provider-model-resolve-BpfXp3Jj.d.ts → provider-model-resolve-CwQNZWt_.d.ts} +3 -3
- package/dist/{provider-runner-CnOSr5BN.d.ts → provider-runner-CYHFImzV.d.ts} +3 -3
- package/dist/{retry-policy-Git9WF6d.d.ts → retry-policy-D4feSLk3.d.ts} +1 -1
- package/dist/sdd/index.d.ts +11 -10
- package/dist/sdd/index.js +2 -2
- package/dist/sdd/index.js.map +1 -1
- package/dist/secret-scrubber-3MHDDAtm.d.ts +6 -0
- package/dist/{secret-vault-DDSMHqIm.d.ts → secret-vault-CImt2XrR.d.ts} +1 -1
- package/dist/security/index.d.ts +6 -5
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-Cq72C0Oy.d.ts → selector-Dy-MzKp1.d.ts} +1 -1
- package/dist/{session-event-bridge-DG94B3Bk.d.ts → session-event-bridge-CqdiGnfU.d.ts} +1 -1
- package/dist/{session-reader-BzT-iMQT.d.ts → session-reader-Hk0WbNm9.d.ts} +1 -1
- package/dist/{skill-DGIXCtdv.d.ts → skill-DHniprNl.d.ts} +15 -1
- package/dist/skills/index.d.ts +472 -26
- package/dist/skills/index.js +872 -129
- package/dist/skills/index.js.map +1 -1
- package/dist/storage/index.d.ts +27 -14
- package/dist/storage/index.js +264 -85
- package/dist/storage/index.js.map +1 -1
- package/dist/{strategy-compactor-Bt_ZH6R0.d.ts → strategy-compactor-CQwhbErd.d.ts} +32 -17
- package/dist/{todos-checkpoint-CH1pcua9.d.ts → todos-checkpoint-Bk2uP7Ex.d.ts} +6 -6
- package/dist/{context-DPlA6kid.d.ts → tool-BkOgs_KL.d.ts} +306 -286
- package/dist/{tool-executor-SVFq7IOR.d.ts → tool-executor-SiE1wlZo.d.ts} +9 -9
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/types/index.d.ts +22 -21
- package/dist/types/index.js +7 -9
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +30 -4
- package/dist/utils/index.js +50 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/{worktree-manager-C4YIf1Fa.d.ts → worktree-manager-BjOFF6bt.d.ts} +1 -1
- package/dist/{wstack-paths-_NrRovdr.d.ts → wstack-paths-CMl_cYgq.d.ts} +8 -0
- package/package.json +1 -1
- package/skills/mailbox-bridge/SKILL.md +1 -0
- package/skills/plugin-author/SKILL.md +350 -0
- package/skills/sdd/SKILL.md +134 -134
- package/skills/skill-creator/SKILL.md +45 -7
- package/skills/wrongstack-mailbox/SKILL.md +40 -21
package/dist/defaults/index.js
CHANGED
|
@@ -70,8 +70,8 @@ async function atomicWrite(targetPath, content, opts = {}) {
|
|
|
70
70
|
}
|
|
71
71
|
let mode;
|
|
72
72
|
try {
|
|
73
|
-
const
|
|
74
|
-
mode =
|
|
73
|
+
const stat11 = await fsp7.stat(targetPath);
|
|
74
|
+
mode = stat11.mode & 511;
|
|
75
75
|
} catch {
|
|
76
76
|
mode = opts.mode;
|
|
77
77
|
}
|
|
@@ -117,8 +117,8 @@ async function withFileLock(targetPath, fn, opts = {}) {
|
|
|
117
117
|
}
|
|
118
118
|
if (code !== "EEXIST") throw err;
|
|
119
119
|
try {
|
|
120
|
-
const
|
|
121
|
-
if (Date.now() -
|
|
120
|
+
const stat11 = await fsp7.stat(lockPath);
|
|
121
|
+
if (Date.now() - stat11.mtimeMs > staleMs) {
|
|
122
122
|
await fsp7.unlink(lockPath);
|
|
123
123
|
continue;
|
|
124
124
|
}
|
|
@@ -380,6 +380,7 @@ function createContextEvidenceState() {
|
|
|
380
380
|
toolCalls: [],
|
|
381
381
|
fileGraph: {},
|
|
382
382
|
repeatedReads: [],
|
|
383
|
+
completedWork: [],
|
|
383
384
|
updatedAt: Date.now()
|
|
384
385
|
};
|
|
385
386
|
}
|
|
@@ -442,6 +443,7 @@ function ensureEvidence(ctx) {
|
|
|
442
443
|
if (!ctx.contextEvidence) {
|
|
443
444
|
ctx.contextEvidence = createContextEvidenceState();
|
|
444
445
|
}
|
|
446
|
+
ctx.contextEvidence.completedWork ??= [];
|
|
445
447
|
return ctx.contextEvidence;
|
|
446
448
|
}
|
|
447
449
|
var MAX_DIGEST_CHARS;
|
|
@@ -627,8 +629,8 @@ async function expandGlob(pattern) {
|
|
|
627
629
|
for (const e of entries) {
|
|
628
630
|
const full = `${dir}${SEP}${e}`;
|
|
629
631
|
try {
|
|
630
|
-
const
|
|
631
|
-
if (
|
|
632
|
+
const stat11 = await fsp7.stat(full);
|
|
633
|
+
if (stat11.isDirectory()) await walk3(full, rest);
|
|
632
634
|
} catch {
|
|
633
635
|
}
|
|
634
636
|
}
|
|
@@ -645,8 +647,8 @@ async function expandGlob(pattern) {
|
|
|
645
647
|
if (entries.includes(seg)) {
|
|
646
648
|
const full = `${dir}${SEP}${seg}`;
|
|
647
649
|
try {
|
|
648
|
-
const
|
|
649
|
-
if (
|
|
650
|
+
const stat11 = await fsp7.stat(full);
|
|
651
|
+
if (stat11.isDirectory()) await walk3(full, rest);
|
|
650
652
|
} catch {
|
|
651
653
|
}
|
|
652
654
|
}
|
|
@@ -2277,16 +2279,20 @@ function wstackGlobalRoot() {
|
|
|
2277
2279
|
}
|
|
2278
2280
|
function resolveWstackPaths(opts) {
|
|
2279
2281
|
const globalRoot = opts.globalRoot ?? (opts.userHome ? path4.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
|
|
2282
|
+
const homeDir = opts.userHome ?? os.homedir();
|
|
2280
2283
|
const hash = projectHash(opts.projectRoot);
|
|
2281
2284
|
const slug = projectSlug(opts.projectRoot);
|
|
2282
2285
|
const projectDir = path4.join(globalRoot, "projects", slug);
|
|
2283
2286
|
return {
|
|
2284
2287
|
globalRoot,
|
|
2288
|
+
projectRoot: opts.projectRoot,
|
|
2289
|
+
homeDir,
|
|
2285
2290
|
configDir: globalRoot,
|
|
2286
2291
|
globalConfig: path4.join(globalRoot, "config.json"),
|
|
2287
2292
|
secretsKey: path4.join(globalRoot, ".key"),
|
|
2288
2293
|
globalMemory: path4.join(globalRoot, "memory.md"),
|
|
2289
2294
|
globalSkills: path4.join(globalRoot, "skills"),
|
|
2295
|
+
globalClaudeSkills: path4.join(homeDir, ".claude", "skills"),
|
|
2290
2296
|
globalDesignKits: path4.join(globalRoot, "design-kits"),
|
|
2291
2297
|
globalPrompts: path4.join(globalRoot, "prompts"),
|
|
2292
2298
|
globalInstructions: path4.join(globalRoot, "instructions"),
|
|
@@ -2306,6 +2312,7 @@ function resolveWstackPaths(opts) {
|
|
|
2306
2312
|
inProjectConfig: path4.join(opts.projectRoot, ".wrongstack", "config.json"),
|
|
2307
2313
|
inProjectAgentsFile: path4.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
|
|
2308
2314
|
inProjectSkills: path4.join(opts.projectRoot, ".wrongstack", "skills"),
|
|
2315
|
+
inProjectClaudeSkills: path4.join(opts.projectRoot, ".claude", "skills"),
|
|
2309
2316
|
inProjectPrompts: path4.join(opts.projectRoot, ".wrongstack", "prompts"),
|
|
2310
2317
|
inProjectInstructions: path4.join(opts.projectRoot, ".wrongstack", "instructions"),
|
|
2311
2318
|
inProjectDesignKits: path4.join(opts.projectRoot, ".wrongstack", "design-kits"),
|
|
@@ -5821,7 +5828,7 @@ var CollabSession = class extends EventEmitter {
|
|
|
5821
5828
|
}
|
|
5822
5829
|
for (const filePath of allFiles) {
|
|
5823
5830
|
try {
|
|
5824
|
-
const [content,
|
|
5831
|
+
const [content, stat11] = await Promise.all([
|
|
5825
5832
|
fsp7.readFile(filePath, "utf8"),
|
|
5826
5833
|
fsp7.stat(filePath)
|
|
5827
5834
|
]);
|
|
@@ -5831,8 +5838,8 @@ var CollabSession = class extends EventEmitter {
|
|
|
5831
5838
|
path: filePath,
|
|
5832
5839
|
content,
|
|
5833
5840
|
language,
|
|
5834
|
-
snapshotMtimeMs:
|
|
5835
|
-
snapshotSizeBytes:
|
|
5841
|
+
snapshotMtimeMs: stat11.mtimeMs,
|
|
5842
|
+
snapshotSizeBytes: stat11.size
|
|
5836
5843
|
});
|
|
5837
5844
|
} catch {
|
|
5838
5845
|
this.snapshot.files.push({ path: filePath, content: "", language: void 0 });
|
|
@@ -6245,9 +6252,9 @@ Emit each evaluation immediately. Do not wait until you have read all reports.`;
|
|
|
6245
6252
|
for (const file of this.snapshot.files) {
|
|
6246
6253
|
if (file.snapshotMtimeMs === void 0 && file.snapshotSizeBytes === void 0) continue;
|
|
6247
6254
|
try {
|
|
6248
|
-
const
|
|
6249
|
-
const mtimeChanged = file.snapshotMtimeMs !== void 0 &&
|
|
6250
|
-
const sizeChanged = file.snapshotSizeBytes !== void 0 &&
|
|
6255
|
+
const stat11 = await fsp7.stat(file.path);
|
|
6256
|
+
const mtimeChanged = file.snapshotMtimeMs !== void 0 && stat11.mtimeMs > file.snapshotMtimeMs + 1;
|
|
6257
|
+
const sizeChanged = file.snapshotSizeBytes !== void 0 && stat11.size !== file.snapshotSizeBytes;
|
|
6251
6258
|
if (mtimeChanged || sizeChanged) {
|
|
6252
6259
|
warnings.push(`${file.path} changed after the collab snapshot was captured.`);
|
|
6253
6260
|
}
|
|
@@ -6333,7 +6340,7 @@ function readBundledInstructionText(relativePath) {
|
|
|
6333
6340
|
function renderInstructionTemplate(template, values) {
|
|
6334
6341
|
return template.replace(
|
|
6335
6342
|
/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g,
|
|
6336
|
-
(match, key) => Object.
|
|
6343
|
+
(match, key) => Object.hasOwn(values, key) ? values[key] ?? "" : match
|
|
6337
6344
|
);
|
|
6338
6345
|
}
|
|
6339
6346
|
function instructionRootCandidates() {
|
|
@@ -9026,6 +9033,7 @@ var Director = class _Director {
|
|
|
9026
9033
|
if (entry?.model) {
|
|
9027
9034
|
config.model = entry.model;
|
|
9028
9035
|
if (entry.provider) config.provider = entry.provider;
|
|
9036
|
+
if (entry.modelRuntime) config.modelRuntime = entry.modelRuntime;
|
|
9029
9037
|
}
|
|
9030
9038
|
}
|
|
9031
9039
|
if (this.fleetManager) {
|
|
@@ -10547,9 +10555,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
10547
10555
|
let cacheHit = false;
|
|
10548
10556
|
try {
|
|
10549
10557
|
const s = await fsp7.stat(file);
|
|
10550
|
-
const
|
|
10558
|
+
const stat11 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
10551
10559
|
const cached = this._loadCache.get(id);
|
|
10552
|
-
if (cached && cached.mtimeMs ===
|
|
10560
|
+
if (cached && cached.mtimeMs === stat11.mtimeMs && cached.size === stat11.size) {
|
|
10553
10561
|
cacheHit = true;
|
|
10554
10562
|
this._loadCache.delete(id);
|
|
10555
10563
|
this._loadCache.set(id, cached);
|
|
@@ -10672,7 +10680,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
10672
10680
|
this._loadCache.delete(oldest);
|
|
10673
10681
|
}
|
|
10674
10682
|
}
|
|
10675
|
-
this._loadCache.set(id, { mtimeMs:
|
|
10683
|
+
this._loadCache.set(id, { mtimeMs: stat11.mtimeMs, size: stat11.size, data });
|
|
10676
10684
|
}
|
|
10677
10685
|
return data;
|
|
10678
10686
|
} catch (err) {
|
|
@@ -10714,14 +10722,14 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
10714
10722
|
const limit = opts?.limit;
|
|
10715
10723
|
const signal = opts?.signal;
|
|
10716
10724
|
const out = [];
|
|
10717
|
-
let
|
|
10725
|
+
let stat11;
|
|
10718
10726
|
try {
|
|
10719
|
-
|
|
10727
|
+
stat11 = await fsp7.stat(file);
|
|
10720
10728
|
} catch (err) {
|
|
10721
10729
|
if (err.code === "ENOENT") return [];
|
|
10722
10730
|
throw err;
|
|
10723
10731
|
}
|
|
10724
|
-
if (
|
|
10732
|
+
if (stat11.size === 0) return [];
|
|
10725
10733
|
let fh;
|
|
10726
10734
|
try {
|
|
10727
10735
|
fh = await fsp7.open(file, "r");
|
|
@@ -10904,15 +10912,15 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
10904
10912
|
* Returns empty array when the index doesn't exist or is corrupt.
|
|
10905
10913
|
*/
|
|
10906
10914
|
async readIndex() {
|
|
10907
|
-
let
|
|
10915
|
+
let stat11;
|
|
10908
10916
|
try {
|
|
10909
10917
|
const s = await fsp7.stat(this.indexFile);
|
|
10910
|
-
|
|
10918
|
+
stat11 = { mtimeMs: s.mtimeMs, size: s.size };
|
|
10911
10919
|
} catch {
|
|
10912
10920
|
this._indexCache = null;
|
|
10913
10921
|
return [];
|
|
10914
10922
|
}
|
|
10915
|
-
if (this._indexCache !== null && this._indexCache.mtimeMs ===
|
|
10923
|
+
if (this._indexCache !== null && this._indexCache.mtimeMs === stat11.mtimeMs && this._indexCache.size === stat11.size) {
|
|
10916
10924
|
return [...this._indexCache.summaries];
|
|
10917
10925
|
}
|
|
10918
10926
|
let raw;
|
|
@@ -10945,7 +10953,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
10945
10953
|
if (a.startedAt > b.startedAt) return -1;
|
|
10946
10954
|
return a.id.localeCompare(b.id);
|
|
10947
10955
|
});
|
|
10948
|
-
this._indexCache = { ...
|
|
10956
|
+
this._indexCache = { ...stat11, summaries };
|
|
10949
10957
|
return [...summaries];
|
|
10950
10958
|
}
|
|
10951
10959
|
/**
|
|
@@ -11112,8 +11120,8 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
11112
11120
|
if (fromManifest) return fromManifest;
|
|
11113
11121
|
try {
|
|
11114
11122
|
const full = this.sessionPath(id, ".jsonl");
|
|
11115
|
-
const
|
|
11116
|
-
const summary = await this.summarize(id,
|
|
11123
|
+
const stat11 = await fsp7.stat(full);
|
|
11124
|
+
const summary = await this.summarize(id, stat11.mtime.toISOString());
|
|
11117
11125
|
await atomicWrite(manifest, JSON.stringify(summary), { mode: 384 }).catch((err) => {
|
|
11118
11126
|
const msg = toErrorMessage(err);
|
|
11119
11127
|
this.emitError(id, manifest, "summary_fallback", msg, true);
|
|
@@ -11156,18 +11164,18 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
11156
11164
|
async summaryHeaderFor(ref) {
|
|
11157
11165
|
let mtime = (/* @__PURE__ */ new Date(0)).toISOString();
|
|
11158
11166
|
try {
|
|
11159
|
-
const
|
|
11160
|
-
if (!
|
|
11167
|
+
const stat11 = await fsp7.stat(ref.filePath);
|
|
11168
|
+
if (!stat11.isFile()) {
|
|
11161
11169
|
return {
|
|
11162
11170
|
id: ref.id,
|
|
11163
11171
|
title: "(damaged)",
|
|
11164
|
-
startedAt:
|
|
11172
|
+
startedAt: stat11.mtime.toISOString(),
|
|
11165
11173
|
model: "unknown",
|
|
11166
11174
|
provider: "unknown",
|
|
11167
11175
|
tokenTotal: 0
|
|
11168
11176
|
};
|
|
11169
11177
|
}
|
|
11170
|
-
mtime =
|
|
11178
|
+
mtime = stat11.mtime.toISOString();
|
|
11171
11179
|
} catch {
|
|
11172
11180
|
return null;
|
|
11173
11181
|
}
|
|
@@ -11268,8 +11276,8 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
11268
11276
|
const pruneFile = async (dir, name, prefix) => {
|
|
11269
11277
|
const jsonlPath = path4.join(dir, name);
|
|
11270
11278
|
try {
|
|
11271
|
-
const
|
|
11272
|
-
if (
|
|
11279
|
+
const stat11 = await fsp7.stat(jsonlPath);
|
|
11280
|
+
if (stat11.mtimeMs >= cutoff) return;
|
|
11273
11281
|
} catch {
|
|
11274
11282
|
return;
|
|
11275
11283
|
}
|
|
@@ -13110,7 +13118,7 @@ async function recordOverrides(projectRoot, patch, isoTime) {
|
|
|
13110
13118
|
if (!active) return void 0;
|
|
13111
13119
|
const merged = { ...active.overrides ?? {} };
|
|
13112
13120
|
for (const [k, v] of Object.entries(patch)) {
|
|
13113
|
-
if (v
|
|
13121
|
+
if (v?.trim()) merged[k] = v.trim();
|
|
13114
13122
|
else delete merged[k];
|
|
13115
13123
|
}
|
|
13116
13124
|
try {
|
|
@@ -15925,6 +15933,134 @@ Summarize the following message range:`;
|
|
|
15925
15933
|
return estimateMessages(messages);
|
|
15926
15934
|
}
|
|
15927
15935
|
};
|
|
15936
|
+
|
|
15937
|
+
// src/skills/foreign-sources.ts
|
|
15938
|
+
var FOREIGN_SKILL_TOOLS = [
|
|
15939
|
+
{ id: "agents", subdir: "skills" },
|
|
15940
|
+
// shared store (asm / agentskills.io ecosystem)
|
|
15941
|
+
{ id: "codex", subdir: "skills" },
|
|
15942
|
+
// OpenAI Codex CLI
|
|
15943
|
+
{ id: "gemini", subdir: "skills" },
|
|
15944
|
+
// Gemini CLI
|
|
15945
|
+
{ id: "cursor", subdir: "skills" },
|
|
15946
|
+
// Cursor (standard subdir, aligned with skills.sh ecosystem)
|
|
15947
|
+
{ id: "qwen", subdir: "skills" },
|
|
15948
|
+
// Qwen Code
|
|
15949
|
+
{ id: "trae", subdir: "skills" },
|
|
15950
|
+
// Trae
|
|
15951
|
+
{ id: "windsurf", subdir: "skills" }
|
|
15952
|
+
// Windsurf
|
|
15953
|
+
];
|
|
15954
|
+
var KNOWN_FOREIGN_IDS = new Set(FOREIGN_SKILL_TOOLS.map((t) => t.id));
|
|
15955
|
+
function resolveForeignToolIds(opt) {
|
|
15956
|
+
return resolveForeignToolIdsWithWarnings(opt).ids;
|
|
15957
|
+
}
|
|
15958
|
+
function resolveForeignToolIdsWithWarnings(opt) {
|
|
15959
|
+
if (opt === false) return { ids: [], unknownIds: [] };
|
|
15960
|
+
if (Array.isArray(opt)) {
|
|
15961
|
+
const ids = [];
|
|
15962
|
+
const unknownIds = [];
|
|
15963
|
+
for (const id of opt) {
|
|
15964
|
+
if (KNOWN_FOREIGN_IDS.has(id)) ids.push(id);
|
|
15965
|
+
else unknownIds.push(id);
|
|
15966
|
+
}
|
|
15967
|
+
return { ids, unknownIds };
|
|
15968
|
+
}
|
|
15969
|
+
return { ids: FOREIGN_SKILL_TOOLS.map((t) => t.id), unknownIds: [] };
|
|
15970
|
+
}
|
|
15971
|
+
|
|
15972
|
+
// src/skills/frontmatter.ts
|
|
15973
|
+
var SCALAR_KEYS = /* @__PURE__ */ new Set(["name", "description", "version", "license", "compatibility"]);
|
|
15974
|
+
function parseSkillFrontmatter(raw) {
|
|
15975
|
+
const text = normalizeLineEndings(raw);
|
|
15976
|
+
if (!text.startsWith("---")) return {};
|
|
15977
|
+
const end = text.indexOf("\n---", 4);
|
|
15978
|
+
if (end === -1) return {};
|
|
15979
|
+
return parseFrontmatterBlock(text.slice(4, end));
|
|
15980
|
+
}
|
|
15981
|
+
function normalizeLineEndings(s) {
|
|
15982
|
+
return s.replace(/\r\n?/g, "\n");
|
|
15983
|
+
}
|
|
15984
|
+
function parseFrontmatterBlock(block) {
|
|
15985
|
+
const out = {};
|
|
15986
|
+
const lines = block.split("\n");
|
|
15987
|
+
let i = 0;
|
|
15988
|
+
while (i < lines.length) {
|
|
15989
|
+
const line = lines[i] ?? "";
|
|
15990
|
+
const m = /^([a-zA-Z][a-zA-Z0-9_-]*):\s*(.*)$/.exec(line);
|
|
15991
|
+
if (!m) {
|
|
15992
|
+
i++;
|
|
15993
|
+
continue;
|
|
15994
|
+
}
|
|
15995
|
+
const key = m[1] ?? "";
|
|
15996
|
+
const rest = (m[2] ?? "").trim();
|
|
15997
|
+
if (key === "metadata") {
|
|
15998
|
+
const map = {};
|
|
15999
|
+
i++;
|
|
16000
|
+
while (i < lines.length) {
|
|
16001
|
+
const sub = lines[i] ?? "";
|
|
16002
|
+
const sm = /^\s+([a-zA-Z0-9_.-]+):\s*(.*)$/.exec(sub);
|
|
16003
|
+
if (!sm) break;
|
|
16004
|
+
map[sm[1] ?? ""] = unquote((sm[2] ?? "").trim());
|
|
16005
|
+
i++;
|
|
16006
|
+
}
|
|
16007
|
+
if (Object.keys(map).length > 0) out.metadata = map;
|
|
16008
|
+
continue;
|
|
16009
|
+
}
|
|
16010
|
+
if (rest === "|" || rest === ">") {
|
|
16011
|
+
const collected = [];
|
|
16012
|
+
i++;
|
|
16013
|
+
while (i < lines.length) {
|
|
16014
|
+
const sub = lines[i] ?? "";
|
|
16015
|
+
if (sub === "" || sub.startsWith(" ") || sub.startsWith(" ")) {
|
|
16016
|
+
collected.push(sub.replace(/^\s+/, ""));
|
|
16017
|
+
i++;
|
|
16018
|
+
} else break;
|
|
16019
|
+
}
|
|
16020
|
+
out[normalizeKey(key)] = collected.join("\n").trim();
|
|
16021
|
+
continue;
|
|
16022
|
+
}
|
|
16023
|
+
if (key === "allowed-tools" || key === "allowedTools") {
|
|
16024
|
+
out.allowedTools = rest.split(/[\s,]+/).filter(Boolean);
|
|
16025
|
+
i++;
|
|
16026
|
+
continue;
|
|
16027
|
+
}
|
|
16028
|
+
if (SCALAR_KEYS.has(key)) {
|
|
16029
|
+
out[key] = unquote(rest);
|
|
16030
|
+
i++;
|
|
16031
|
+
continue;
|
|
16032
|
+
}
|
|
16033
|
+
i++;
|
|
16034
|
+
}
|
|
16035
|
+
return out;
|
|
16036
|
+
}
|
|
16037
|
+
function normalizeKey(key) {
|
|
16038
|
+
return key === "allowed-tools" ? "allowedTools" : key;
|
|
16039
|
+
}
|
|
16040
|
+
function unquote(s) {
|
|
16041
|
+
if (s.length >= 2 && (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'"))) {
|
|
16042
|
+
return s.slice(1, -1);
|
|
16043
|
+
}
|
|
16044
|
+
return s;
|
|
16045
|
+
}
|
|
16046
|
+
function isValidSkillNameFormat(name) {
|
|
16047
|
+
return name.length >= 1 && name.length <= 64 && /^[a-z0-9]+(-[a-z0-9]+)*$/.test(name);
|
|
16048
|
+
}
|
|
16049
|
+
|
|
16050
|
+
// src/skills/limits.ts
|
|
16051
|
+
var SKILL_LIMITS = {
|
|
16052
|
+
/**
|
|
16053
|
+
* Auto-compact body limits (the token-saving fallback used when a skill has
|
|
16054
|
+
* no hand-crafted `SKILL.save.md`). The Overview and Rules sections are
|
|
16055
|
+
* extracted and trimmed to these char budgets, then the total is capped.
|
|
16056
|
+
*
|
|
16057
|
+
* Consumer: `DefaultSkillLoader.compactSkillBody`.
|
|
16058
|
+
*/
|
|
16059
|
+
COMPACT_OVERVIEW_MAX: 200,
|
|
16060
|
+
COMPACT_RULES_MAX: 350,
|
|
16061
|
+
COMPACT_TOTAL_MAX: 450};
|
|
16062
|
+
|
|
16063
|
+
// src/execution/skill-loader.ts
|
|
15928
16064
|
function stripFrontmatter2(raw) {
|
|
15929
16065
|
if (!raw.startsWith("---")) return raw;
|
|
15930
16066
|
const end = raw.indexOf("\n---", 4);
|
|
@@ -15938,21 +16074,33 @@ function compactSkillBody(body) {
|
|
|
15938
16074
|
const overviewMatch = body.match(/##\s*Overview\s*\n([\s\S]*?)(?=\n##|\n$|$)/i);
|
|
15939
16075
|
const overview = overviewMatch?.[1];
|
|
15940
16076
|
if (overview?.trim()) {
|
|
15941
|
-
sections.push(overview.trim().slice(0,
|
|
16077
|
+
sections.push(overview.trim().slice(0, SKILL_LIMITS.COMPACT_OVERVIEW_MAX));
|
|
15942
16078
|
}
|
|
15943
16079
|
const rulesMatch = body.match(/##\s*Rules\s*\n([\s\S]*?)(?=\n##|\n$|$)/i);
|
|
15944
16080
|
const rules = rulesMatch?.[1];
|
|
15945
16081
|
if (rules?.trim()) {
|
|
15946
|
-
const trimmed = rules.trim().slice(0,
|
|
16082
|
+
const trimmed = rules.trim().slice(0, SKILL_LIMITS.COMPACT_RULES_MAX);
|
|
15947
16083
|
const ruleLines = trimmed.split("\n").filter((l) => /^\s*[-*]\s/.test(l) || /^\s*\d+[.)]\s/.test(l)).slice(0, 6).join("\n");
|
|
15948
16084
|
if (ruleLines) sections.push(ruleLines);
|
|
15949
16085
|
}
|
|
15950
16086
|
if (sections.length === 0) {
|
|
15951
|
-
const first = body.trim().slice(0,
|
|
16087
|
+
const first = body.trim().slice(0, SKILL_LIMITS.COMPACT_OVERVIEW_MAX);
|
|
15952
16088
|
if (first) sections.push(first);
|
|
15953
16089
|
}
|
|
15954
16090
|
const result = sections.join("\n\n");
|
|
15955
|
-
|
|
16091
|
+
const total = SKILL_LIMITS.COMPACT_TOTAL_MAX;
|
|
16092
|
+
return result.length > total ? result.slice(0, total - 3) + "\u2026" : result;
|
|
16093
|
+
}
|
|
16094
|
+
async function entryIsDirectory(dir, entry) {
|
|
16095
|
+
if (entry.isDirectory()) return true;
|
|
16096
|
+
if (entry.isSymbolicLink()) {
|
|
16097
|
+
try {
|
|
16098
|
+
return (await fsp7.stat(path4.join(dir, entry.name))).isDirectory();
|
|
16099
|
+
} catch {
|
|
16100
|
+
return false;
|
|
16101
|
+
}
|
|
16102
|
+
}
|
|
16103
|
+
return false;
|
|
15956
16104
|
}
|
|
15957
16105
|
var DefaultSkillLoader = class {
|
|
15958
16106
|
dirs;
|
|
@@ -15960,36 +16108,58 @@ var DefaultSkillLoader = class {
|
|
|
15960
16108
|
entriesCache;
|
|
15961
16109
|
bodyCache = /* @__PURE__ */ new Map();
|
|
15962
16110
|
constructor(opts) {
|
|
15963
|
-
|
|
15964
|
-
|
|
15965
|
-
|
|
15966
|
-
|
|
15967
|
-
|
|
15968
|
-
|
|
15969
|
-
|
|
16111
|
+
const readClaude = opts.readClaudeSkills !== false;
|
|
16112
|
+
const foreignIds = resolveForeignToolIds(opts.foreignSources);
|
|
16113
|
+
const dirs = [];
|
|
16114
|
+
const pushForeign = (root) => {
|
|
16115
|
+
if (!root) return;
|
|
16116
|
+
for (const tool of FOREIGN_SKILL_TOOLS) {
|
|
16117
|
+
if (!foreignIds.includes(tool.id)) continue;
|
|
16118
|
+
dirs.push({
|
|
16119
|
+
dir: path4.join(root, "." + tool.id, tool.subdir),
|
|
16120
|
+
source: "foreign",
|
|
16121
|
+
originTool: tool.id
|
|
16122
|
+
});
|
|
16123
|
+
}
|
|
16124
|
+
};
|
|
16125
|
+
dirs.push({ dir: opts.paths.inProjectSkills, source: "project" });
|
|
16126
|
+
if (readClaude) dirs.push({ dir: opts.paths.inProjectClaudeSkills, source: "claude-project" });
|
|
16127
|
+
pushForeign(opts.paths.projectRoot);
|
|
16128
|
+
dirs.push({ dir: opts.paths.globalSkills, source: "user" });
|
|
16129
|
+
if (readClaude) dirs.push({ dir: opts.paths.globalClaudeSkills, source: "claude-user" });
|
|
16130
|
+
pushForeign(opts.paths.homeDir);
|
|
16131
|
+
for (const d of opts.extraDirs ?? []) dirs.push({ dir: d, source: "extra" });
|
|
16132
|
+
if (opts.bundledDir) dirs.push({ dir: opts.bundledDir, source: "bundled" });
|
|
16133
|
+
this.dirs = dirs;
|
|
15970
16134
|
}
|
|
15971
16135
|
async list() {
|
|
15972
16136
|
if (this.cache) return this.cache;
|
|
15973
16137
|
const found = [];
|
|
15974
16138
|
const seen = /* @__PURE__ */ new Set();
|
|
15975
|
-
for (const { dir, source } of this.dirs) {
|
|
16139
|
+
for (const { dir, source, originTool } of this.dirs) {
|
|
15976
16140
|
try {
|
|
15977
16141
|
const entries = await fsp7.readdir(dir, { withFileTypes: true });
|
|
15978
16142
|
for (const e of entries) {
|
|
15979
|
-
if (!e
|
|
16143
|
+
if (!await entryIsDirectory(dir, e)) continue;
|
|
15980
16144
|
const skillFile = path4.join(dir, e.name, "SKILL.md");
|
|
15981
16145
|
try {
|
|
15982
16146
|
const raw = await fsp7.readFile(skillFile, "utf8");
|
|
15983
|
-
const
|
|
15984
|
-
if (!
|
|
15985
|
-
if (
|
|
15986
|
-
seen.
|
|
16147
|
+
const fm = parseSkillFrontmatter(raw);
|
|
16148
|
+
if (!fm.name || !fm.description) continue;
|
|
16149
|
+
if (!isValidSkillNameFormat(fm.name)) continue;
|
|
16150
|
+
if (seen.has(fm.name)) continue;
|
|
16151
|
+
seen.add(fm.name);
|
|
15987
16152
|
found.push({
|
|
15988
|
-
name:
|
|
15989
|
-
description:
|
|
15990
|
-
version:
|
|
16153
|
+
name: fm.name,
|
|
16154
|
+
description: fm.description,
|
|
16155
|
+
version: fm.version,
|
|
16156
|
+
license: fm.license,
|
|
16157
|
+
compatibility: fm.compatibility,
|
|
16158
|
+
metadata: fm.metadata,
|
|
16159
|
+
allowedTools: fm.allowedTools,
|
|
15991
16160
|
path: skillFile,
|
|
15992
|
-
source
|
|
16161
|
+
source,
|
|
16162
|
+
originTool
|
|
15993
16163
|
});
|
|
15994
16164
|
} catch {
|
|
15995
16165
|
}
|
|
@@ -16022,7 +16192,14 @@ var DefaultSkillLoader = class {
|
|
|
16022
16192
|
const entries = [];
|
|
16023
16193
|
for (const s of skills) {
|
|
16024
16194
|
const { trigger, scope } = parseDescriptionFromText(s.description ?? "");
|
|
16025
|
-
entries.push({
|
|
16195
|
+
entries.push({
|
|
16196
|
+
name: s.name,
|
|
16197
|
+
trigger,
|
|
16198
|
+
scope,
|
|
16199
|
+
source: s.source,
|
|
16200
|
+
originTool: s.originTool,
|
|
16201
|
+
path: s.path
|
|
16202
|
+
});
|
|
16026
16203
|
}
|
|
16027
16204
|
this.entriesCache = entries;
|
|
16028
16205
|
return entries;
|
|
@@ -16068,42 +16245,6 @@ ${compact}`;
|
|
|
16068
16245
|
return result;
|
|
16069
16246
|
}
|
|
16070
16247
|
};
|
|
16071
|
-
function parseFrontmatter(raw) {
|
|
16072
|
-
if (!raw.startsWith("---")) return {};
|
|
16073
|
-
const end = raw.indexOf("\n---", 4);
|
|
16074
|
-
if (end === -1) return {};
|
|
16075
|
-
const block = raw.slice(4, end);
|
|
16076
|
-
const out = {};
|
|
16077
|
-
let key = null;
|
|
16078
|
-
let value = [];
|
|
16079
|
-
const flush = () => {
|
|
16080
|
-
if (key) {
|
|
16081
|
-
out[key] = value.join("\n").trim();
|
|
16082
|
-
}
|
|
16083
|
-
key = null;
|
|
16084
|
-
value = [];
|
|
16085
|
-
};
|
|
16086
|
-
for (const line of block.split("\n")) {
|
|
16087
|
-
const m = /^([a-zA-Z_]+):\s*(\|?)\s*(.*)$/.exec(line);
|
|
16088
|
-
if (m) {
|
|
16089
|
-
flush();
|
|
16090
|
-
key = m[1] ?? "";
|
|
16091
|
-
const pipe = m[2];
|
|
16092
|
-
const rest = m[3] ?? "";
|
|
16093
|
-
if (pipe === "|") {
|
|
16094
|
-
value = [];
|
|
16095
|
-
} else if (rest) {
|
|
16096
|
-
value = [rest];
|
|
16097
|
-
} else {
|
|
16098
|
-
value = [];
|
|
16099
|
-
}
|
|
16100
|
-
} else if (key) {
|
|
16101
|
-
value.push(line.replace(/^\s+/, ""));
|
|
16102
|
-
}
|
|
16103
|
-
}
|
|
16104
|
-
flush();
|
|
16105
|
-
return out;
|
|
16106
|
-
}
|
|
16107
16248
|
function parseDescriptionFromText(desc) {
|
|
16108
16249
|
const firstSentenceEnd = desc.indexOf(". ");
|
|
16109
16250
|
const trigger = firstSentenceEnd !== -1 ? desc.slice(0, firstSentenceEnd + 1).trim() : desc.trim().split("\n")[0] ?? "";
|
|
@@ -16812,7 +16953,9 @@ ${errorDetails}`,
|
|
|
16812
16953
|
toolUseId: use.id,
|
|
16813
16954
|
toolName: tool.name,
|
|
16814
16955
|
input: use.input,
|
|
16815
|
-
suggestedPattern
|
|
16956
|
+
suggestedPattern,
|
|
16957
|
+
decisionSource: decision.source,
|
|
16958
|
+
riskTier: decision.riskTier ?? tool.riskTier
|
|
16816
16959
|
};
|
|
16817
16960
|
return { result: pending, tool, durationMs: Date.now() - start };
|
|
16818
16961
|
}
|
|
@@ -18114,8 +18257,8 @@ async function loadProjectModes(modesDir) {
|
|
|
18114
18257
|
for (const entry of entries) {
|
|
18115
18258
|
if (!entry.endsWith(".md") && !entry.endsWith(".txt")) continue;
|
|
18116
18259
|
const filePath = path4.join(modesDir, entry);
|
|
18117
|
-
const
|
|
18118
|
-
if (!
|
|
18260
|
+
const stat11 = await fsp7.stat(filePath);
|
|
18261
|
+
if (!stat11.isFile()) continue;
|
|
18119
18262
|
const content = await fsp7.readFile(filePath, "utf8");
|
|
18120
18263
|
const id = path4.basename(entry, path4.extname(entry));
|
|
18121
18264
|
modes.push({
|
|
@@ -23101,7 +23244,7 @@ var SddParallelRun = class {
|
|
|
23101
23244
|
disabledTools: ["delegate"],
|
|
23102
23245
|
...model ? { model } : {},
|
|
23103
23246
|
...provider ? { provider } : {},
|
|
23104
|
-
...fallbackModels
|
|
23247
|
+
...fallbackModels?.length ? { fallbackModels } : {}
|
|
23105
23248
|
});
|
|
23106
23249
|
if (!spawnResult.subagentId) {
|
|
23107
23250
|
throw new SddError({
|
|
@@ -25525,8 +25668,8 @@ function unwrapDataKey(buf, keyFile) {
|
|
|
25525
25668
|
function checkKeyFilePermissions(keyFile) {
|
|
25526
25669
|
if (process.platform === "win32") return;
|
|
25527
25670
|
try {
|
|
25528
|
-
const
|
|
25529
|
-
const actualMode =
|
|
25671
|
+
const stat11 = fs12.statSync(keyFile);
|
|
25672
|
+
const actualMode = stat11.mode & 511;
|
|
25530
25673
|
if (actualMode !== KEY_FILE_MODE) {
|
|
25531
25674
|
console.warn(JSON.stringify({
|
|
25532
25675
|
level: "warn",
|
|
@@ -26017,8 +26160,9 @@ function mergeAdjacentText(blocks) {
|
|
|
26017
26160
|
}
|
|
26018
26161
|
return out;
|
|
26019
26162
|
}
|
|
26020
|
-
|
|
26021
|
-
|
|
26163
|
+
|
|
26164
|
+
// src/types/config.ts
|
|
26165
|
+
var DEFAULT_TUI_THINKING_WORD = "thinking";
|
|
26022
26166
|
|
|
26023
26167
|
// src/types/context-window.ts
|
|
26024
26168
|
var DEFAULT_CONTEXT_WINDOW_MODE_ID = "balanced";
|
|
@@ -26071,13 +26215,12 @@ function isContextWindowModeId(id) {
|
|
|
26071
26215
|
return CONTEXT_WINDOW_MODES.some((m) => m.id === id);
|
|
26072
26216
|
}
|
|
26073
26217
|
|
|
26074
|
-
// src/types/config.ts
|
|
26075
|
-
var DEFAULT_TUI_THINKING_WORD = "thinking";
|
|
26076
|
-
|
|
26077
26218
|
// src/storage/config-loader.ts
|
|
26078
26219
|
init_errors();
|
|
26079
|
-
|
|
26220
|
+
init_atomic_write();
|
|
26080
26221
|
init_deep_merge();
|
|
26222
|
+
init_error();
|
|
26223
|
+
init_safe_json();
|
|
26081
26224
|
function storageErrorString(err) {
|
|
26082
26225
|
if (err instanceof Error) {
|
|
26083
26226
|
const code = err.code;
|
|
@@ -26119,10 +26262,16 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
26119
26262
|
tokenSavingMode: "off",
|
|
26120
26263
|
allowOutsideProjectRoot: true
|
|
26121
26264
|
},
|
|
26265
|
+
skills: { readClaudeSkills: true },
|
|
26122
26266
|
mcpServers: {},
|
|
26123
26267
|
fallbackAuto: true,
|
|
26124
26268
|
maxConcurrent: 4,
|
|
26125
|
-
|
|
26269
|
+
// YOLO on by default: auto-approve normal project work without a per-call
|
|
26270
|
+
// prompt. Destructive operations still gate through a confirmation. Users
|
|
26271
|
+
// who want the per-call prompts set `yolo: false`. Existing installs whose
|
|
26272
|
+
// config lacks this key pick it up via fillMissingDefaults; an explicit
|
|
26273
|
+
// `false` is preserved by the deep-merge (opt-out respected).
|
|
26274
|
+
yolo: true,
|
|
26126
26275
|
nextPrediction: false,
|
|
26127
26276
|
hints: true,
|
|
26128
26277
|
debugStream: false,
|
|
@@ -26135,12 +26284,19 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
26135
26284
|
},
|
|
26136
26285
|
session: { ...DEFAULT_SESSION_LOGGING_CONFIG },
|
|
26137
26286
|
autonomy: {
|
|
26138
|
-
|
|
26287
|
+
// 'auto' by default: the agent self-drives (picks the top next-step after
|
|
26288
|
+
// each turn). This is a startup default, not a runtime flip — the
|
|
26289
|
+
// autoProceedMaxIterations cap + autoProceedDelayMs cooldown + destructive
|
|
26290
|
+
// gate + Ctrl+C / [GOAL_COMPLETE] stops remain in force. Explicit 'off'
|
|
26291
|
+
// in a config file is preserved (opt-out respected).
|
|
26292
|
+
defaultMode: "auto",
|
|
26139
26293
|
autoProceedDelayMs: DEFAULT_AUTONOMY_CONFIG.autoProceedDelayMs,
|
|
26140
26294
|
autoProceedMaxIterations: 50,
|
|
26141
26295
|
autonomyNextPrompt: "auto {{suggestion}}",
|
|
26142
26296
|
terminalTitleAnimation: true,
|
|
26143
|
-
yolo
|
|
26297
|
+
// Mirrored from the top-level yolo default so the autonomy subsystem
|
|
26298
|
+
// (which reads autonomy.yolo) stays consistent with config.yolo.
|
|
26299
|
+
yolo: true,
|
|
26144
26300
|
streamFleet: true,
|
|
26145
26301
|
chime: false,
|
|
26146
26302
|
confirmExit: true,
|
|
@@ -26176,7 +26332,7 @@ function fillMissingDefaults(target, defaults) {
|
|
|
26176
26332
|
function fillMissingDefaultsInPlace(target, defaults) {
|
|
26177
26333
|
let changed = false;
|
|
26178
26334
|
for (const [key, defaultValue] of Object.entries(defaults)) {
|
|
26179
|
-
if (!Object.
|
|
26335
|
+
if (!Object.hasOwn(target, key)) {
|
|
26180
26336
|
target[key] = cloneJsonValue(defaultValue);
|
|
26181
26337
|
changed = true;
|
|
26182
26338
|
continue;
|
|
@@ -26246,6 +26402,7 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
|
26246
26402
|
"context",
|
|
26247
26403
|
"tools",
|
|
26248
26404
|
"features",
|
|
26405
|
+
"skills",
|
|
26249
26406
|
"autonomy",
|
|
26250
26407
|
"indexing",
|
|
26251
26408
|
"session",
|
|
@@ -26256,6 +26413,7 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
|
26256
26413
|
"debugStream",
|
|
26257
26414
|
"configScope",
|
|
26258
26415
|
"maxConcurrent",
|
|
26416
|
+
"uiLocale",
|
|
26259
26417
|
"fallbackModels",
|
|
26260
26418
|
"fallbackProfiles",
|
|
26261
26419
|
"favoriteModels",
|
|
@@ -26288,6 +26446,7 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
26288
26446
|
"apiKey",
|
|
26289
26447
|
"baseUrl",
|
|
26290
26448
|
"maxConcurrent",
|
|
26449
|
+
"uiLocale",
|
|
26291
26450
|
"providers",
|
|
26292
26451
|
"models",
|
|
26293
26452
|
"modelMatrix",
|
|
@@ -26303,6 +26462,7 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
26303
26462
|
"plugins",
|
|
26304
26463
|
"log",
|
|
26305
26464
|
"features",
|
|
26465
|
+
"skills",
|
|
26306
26466
|
"yolo",
|
|
26307
26467
|
"nextPrediction",
|
|
26308
26468
|
"cwd",
|
|
@@ -26328,8 +26488,12 @@ function assertInProjectAllowListComplete() {
|
|
|
26328
26488
|
const denied = KNOWN_DENIED_IN_PROJECT.find((d) => d.key === key);
|
|
26329
26489
|
if (!denied) missingFromBoth.push(key);
|
|
26330
26490
|
}
|
|
26331
|
-
const staleDenials = KNOWN_DENIED_IN_PROJECT.filter(
|
|
26332
|
-
|
|
26491
|
+
const staleDenials = KNOWN_DENIED_IN_PROJECT.filter(
|
|
26492
|
+
(d) => !KNOWN_CONFIG_TOP_LEVEL_KEYS.has(d.key)
|
|
26493
|
+
).map((d) => d.key);
|
|
26494
|
+
const duplicate = KNOWN_DENIED_IN_PROJECT.filter((d) => IN_PROJECT_ALLOWED_KEYS.has(d.key)).map(
|
|
26495
|
+
(d) => d.key
|
|
26496
|
+
);
|
|
26333
26497
|
const problems = [];
|
|
26334
26498
|
if (missingFromBoth.length > 0) {
|
|
26335
26499
|
problems.push(
|
|
@@ -26371,14 +26535,41 @@ function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => conso
|
|
|
26371
26535
|
const outTools = out["tools"];
|
|
26372
26536
|
if (outTools && typeof outTools === "object") {
|
|
26373
26537
|
const execCfg = outTools["exec"];
|
|
26374
|
-
if (execCfg && typeof execCfg === "object"
|
|
26375
|
-
const
|
|
26376
|
-
|
|
26377
|
-
|
|
26378
|
-
...
|
|
26379
|
-
|
|
26380
|
-
|
|
26381
|
-
|
|
26538
|
+
if (execCfg && typeof execCfg === "object") {
|
|
26539
|
+
const hasAllow = "allow" in execCfg;
|
|
26540
|
+
const hasDanger = "danger" in execCfg;
|
|
26541
|
+
if (hasAllow || hasDanger) {
|
|
26542
|
+
const clonedExec = { ...execCfg };
|
|
26543
|
+
if (hasAllow) {
|
|
26544
|
+
delete clonedExec["allow"];
|
|
26545
|
+
stripped.push("tools.exec.allow");
|
|
26546
|
+
}
|
|
26547
|
+
if (hasDanger) {
|
|
26548
|
+
delete clonedExec["danger"];
|
|
26549
|
+
stripped.push("tools.exec.danger");
|
|
26550
|
+
}
|
|
26551
|
+
out["tools"] = {
|
|
26552
|
+
...outTools,
|
|
26553
|
+
exec: clonedExec
|
|
26554
|
+
};
|
|
26555
|
+
}
|
|
26556
|
+
}
|
|
26557
|
+
}
|
|
26558
|
+
const outSkills = out["skills"];
|
|
26559
|
+
if (outSkills && typeof outSkills === "object") {
|
|
26560
|
+
const skillsRec = outSkills;
|
|
26561
|
+
const needsClone = "extraDirs" in skillsRec || "registryUrl" in skillsRec;
|
|
26562
|
+
if (needsClone) {
|
|
26563
|
+
const clonedSkills = { ...skillsRec };
|
|
26564
|
+
if ("extraDirs" in clonedSkills) {
|
|
26565
|
+
delete clonedSkills["extraDirs"];
|
|
26566
|
+
stripped.push("skills.extraDirs");
|
|
26567
|
+
}
|
|
26568
|
+
if ("registryUrl" in clonedSkills) {
|
|
26569
|
+
delete clonedSkills["registryUrl"];
|
|
26570
|
+
stripped.push("skills.registryUrl");
|
|
26571
|
+
}
|
|
26572
|
+
out["skills"] = clonedSkills;
|
|
26382
26573
|
}
|
|
26383
26574
|
}
|
|
26384
26575
|
if (stripped.length > 0) {
|
|
@@ -26413,7 +26604,11 @@ function deepMerge2(base, patch) {
|
|
|
26413
26604
|
);
|
|
26414
26605
|
};
|
|
26415
26606
|
}
|
|
26416
|
-
return deepMerge(
|
|
26607
|
+
return deepMerge(
|
|
26608
|
+
base,
|
|
26609
|
+
patch,
|
|
26610
|
+
opts
|
|
26611
|
+
);
|
|
26417
26612
|
}
|
|
26418
26613
|
var DefaultConfigLoader = class {
|
|
26419
26614
|
paths;
|
|
@@ -26459,13 +26654,15 @@ var DefaultConfigLoader = class {
|
|
|
26459
26654
|
cfg = deepMerge2(cfg, patch);
|
|
26460
26655
|
}
|
|
26461
26656
|
} catch (err) {
|
|
26462
|
-
console.warn(
|
|
26463
|
-
|
|
26464
|
-
|
|
26465
|
-
|
|
26466
|
-
|
|
26467
|
-
|
|
26468
|
-
|
|
26657
|
+
console.warn(
|
|
26658
|
+
JSON.stringify({
|
|
26659
|
+
level: "warn",
|
|
26660
|
+
event: "config.source_load_failed",
|
|
26661
|
+
source: src.name,
|
|
26662
|
+
message: toErrorMessage(err),
|
|
26663
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
26664
|
+
})
|
|
26665
|
+
);
|
|
26469
26666
|
}
|
|
26470
26667
|
}
|
|
26471
26668
|
if (opts.cliFlags) {
|
|
@@ -26524,13 +26721,15 @@ var DefaultConfigLoader = class {
|
|
|
26524
26721
|
durationMs: Date.now() - t0,
|
|
26525
26722
|
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
26526
26723
|
});
|
|
26527
|
-
console.warn(
|
|
26528
|
-
|
|
26529
|
-
|
|
26530
|
-
|
|
26531
|
-
|
|
26532
|
-
|
|
26533
|
-
|
|
26724
|
+
console.warn(
|
|
26725
|
+
JSON.stringify({
|
|
26726
|
+
level: "warn",
|
|
26727
|
+
event: "config.defaults_read_failed",
|
|
26728
|
+
path: fp,
|
|
26729
|
+
message: toErrorMessage(err),
|
|
26730
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
26731
|
+
})
|
|
26732
|
+
);
|
|
26534
26733
|
return;
|
|
26535
26734
|
}
|
|
26536
26735
|
parsed = {};
|
|
@@ -26563,13 +26762,15 @@ var DefaultConfigLoader = class {
|
|
|
26563
26762
|
durationMs: Date.now() - t0,
|
|
26564
26763
|
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
26565
26764
|
});
|
|
26566
|
-
console.warn(
|
|
26567
|
-
|
|
26568
|
-
|
|
26569
|
-
|
|
26570
|
-
|
|
26571
|
-
|
|
26572
|
-
|
|
26765
|
+
console.warn(
|
|
26766
|
+
JSON.stringify({
|
|
26767
|
+
level: "warn",
|
|
26768
|
+
event: "config.defaults_write_failed",
|
|
26769
|
+
path: fp,
|
|
26770
|
+
message: toErrorMessage(err),
|
|
26771
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
26772
|
+
})
|
|
26773
|
+
);
|
|
26573
26774
|
}
|
|
26574
26775
|
}
|
|
26575
26776
|
/**
|
|
@@ -26671,12 +26872,14 @@ var DefaultConfigLoader = class {
|
|
|
26671
26872
|
error: storageErrorString(err),
|
|
26672
26873
|
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
26673
26874
|
});
|
|
26674
|
-
console.warn(
|
|
26675
|
-
|
|
26676
|
-
|
|
26677
|
-
|
|
26678
|
-
|
|
26679
|
-
|
|
26875
|
+
console.warn(
|
|
26876
|
+
JSON.stringify({
|
|
26877
|
+
level: "warn",
|
|
26878
|
+
event: "config.sync_load_failed",
|
|
26879
|
+
message: toErrorMessage(err),
|
|
26880
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
26881
|
+
})
|
|
26882
|
+
);
|
|
26680
26883
|
return null;
|
|
26681
26884
|
}
|
|
26682
26885
|
}
|
|
@@ -26684,8 +26887,8 @@ var DefaultConfigLoader = class {
|
|
|
26684
26887
|
const t0 = Date.now();
|
|
26685
26888
|
let mtimeMs = null;
|
|
26686
26889
|
try {
|
|
26687
|
-
const
|
|
26688
|
-
mtimeMs =
|
|
26890
|
+
const stat11 = await fsp7.stat(file);
|
|
26891
|
+
mtimeMs = stat11.mtimeMs;
|
|
26689
26892
|
const cached = this.jsonCache.get(file);
|
|
26690
26893
|
if (cached && cached.mtimeMs === mtimeMs) {
|
|
26691
26894
|
return structuredClone(cached.value);
|
|
@@ -26705,13 +26908,15 @@ var DefaultConfigLoader = class {
|
|
|
26705
26908
|
error: storageErrorString(err),
|
|
26706
26909
|
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
26707
26910
|
});
|
|
26708
|
-
console.warn(
|
|
26709
|
-
|
|
26710
|
-
|
|
26711
|
-
|
|
26712
|
-
|
|
26713
|
-
|
|
26714
|
-
|
|
26911
|
+
console.warn(
|
|
26912
|
+
JSON.stringify({
|
|
26913
|
+
level: "warn",
|
|
26914
|
+
event: "config.read_failed",
|
|
26915
|
+
path: file,
|
|
26916
|
+
message: toErrorMessage(err),
|
|
26917
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
26918
|
+
})
|
|
26919
|
+
);
|
|
26715
26920
|
return {};
|
|
26716
26921
|
}
|
|
26717
26922
|
let raw;
|
|
@@ -26729,13 +26934,15 @@ var DefaultConfigLoader = class {
|
|
|
26729
26934
|
error: storageErrorString(err),
|
|
26730
26935
|
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
26731
26936
|
});
|
|
26732
|
-
console.warn(
|
|
26733
|
-
|
|
26734
|
-
|
|
26735
|
-
|
|
26736
|
-
|
|
26737
|
-
|
|
26738
|
-
|
|
26937
|
+
console.warn(
|
|
26938
|
+
JSON.stringify({
|
|
26939
|
+
level: "warn",
|
|
26940
|
+
event: "config.read_failed",
|
|
26941
|
+
path: file,
|
|
26942
|
+
message: toErrorMessage(err),
|
|
26943
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
26944
|
+
})
|
|
26945
|
+
);
|
|
26739
26946
|
}
|
|
26740
26947
|
this.jsonCache.set(file, { mtimeMs: null, value: {} });
|
|
26741
26948
|
return {};
|
|
@@ -26752,35 +26959,40 @@ var DefaultConfigLoader = class {
|
|
|
26752
26959
|
error: "parse error or empty file",
|
|
26753
26960
|
...this.traceId !== void 0 ? { traceId: this.traceId } : {}
|
|
26754
26961
|
});
|
|
26755
|
-
console.warn(
|
|
26756
|
-
|
|
26757
|
-
|
|
26758
|
-
|
|
26759
|
-
|
|
26760
|
-
|
|
26761
|
-
|
|
26962
|
+
console.warn(
|
|
26963
|
+
JSON.stringify({
|
|
26964
|
+
level: "warn",
|
|
26965
|
+
event: "config.parse_failed",
|
|
26966
|
+
path: file,
|
|
26967
|
+
message: "invalid JSON \u2014 falling back to defaults for this layer",
|
|
26968
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
26969
|
+
})
|
|
26970
|
+
);
|
|
26762
26971
|
return {};
|
|
26763
26972
|
}
|
|
26764
26973
|
this.jsonCache.set(file, { mtimeMs, value: structuredClone(parsed.value) });
|
|
26765
26974
|
return parsed.value;
|
|
26766
26975
|
}
|
|
26767
26976
|
validateBehavior(cfg) {
|
|
26768
|
-
if (cfg.version === void 0)
|
|
26769
|
-
|
|
26770
|
-
|
|
26771
|
-
|
|
26772
|
-
|
|
26773
|
-
|
|
26774
|
-
|
|
26775
|
-
|
|
26776
|
-
|
|
26777
|
-
|
|
26977
|
+
if (cfg.version === void 0)
|
|
26978
|
+
throw new ConfigError({
|
|
26979
|
+
message: "Config: missing version field",
|
|
26980
|
+
code: ERROR_CODES.CONFIG_INVALID,
|
|
26981
|
+
context: { field: "version" }
|
|
26982
|
+
});
|
|
26983
|
+
if (cfg.version !== 1)
|
|
26984
|
+
throw new ConfigError({
|
|
26985
|
+
message: `Config: unsupported version ${cfg.version}`,
|
|
26986
|
+
code: ERROR_CODES.CONFIG_INVALID,
|
|
26987
|
+
context: { field: "version", actual: cfg.version }
|
|
26988
|
+
});
|
|
26778
26989
|
const c = cfg.context;
|
|
26779
|
-
if (!c)
|
|
26780
|
-
|
|
26781
|
-
|
|
26782
|
-
|
|
26783
|
-
|
|
26990
|
+
if (!c)
|
|
26991
|
+
throw new ConfigError({
|
|
26992
|
+
message: "Config: missing context section",
|
|
26993
|
+
code: ERROR_CODES.CONFIG_INVALID,
|
|
26994
|
+
context: { field: "context" }
|
|
26995
|
+
});
|
|
26784
26996
|
const fields = ["warnThreshold", "softThreshold", "hardThreshold"];
|
|
26785
26997
|
for (const f of fields) {
|
|
26786
26998
|
const v = c[f];
|
|
@@ -27119,8 +27331,8 @@ var FileMemoryBackend = class {
|
|
|
27119
27331
|
}
|
|
27120
27332
|
async getMtime(file) {
|
|
27121
27333
|
try {
|
|
27122
|
-
const
|
|
27123
|
-
return
|
|
27334
|
+
const stat11 = await fsp7.stat(file);
|
|
27335
|
+
return stat11.mtimeMs;
|
|
27124
27336
|
} catch {
|
|
27125
27337
|
return 0;
|
|
27126
27338
|
}
|
|
@@ -28608,7 +28820,9 @@ var STANDARD_AUDIT_EVENTS = /* @__PURE__ */ new Set([
|
|
|
28608
28820
|
"error",
|
|
28609
28821
|
"message_truncated",
|
|
28610
28822
|
"provider_retry",
|
|
28611
|
-
"provider_error"
|
|
28823
|
+
"provider_error",
|
|
28824
|
+
"skill_activated",
|
|
28825
|
+
"skill_deactivated"
|
|
28612
28826
|
]);
|
|
28613
28827
|
var FULL_ONLY_EVENTS = /* @__PURE__ */ new Set([
|
|
28614
28828
|
"tool_progress"
|
|
@@ -28720,8 +28934,8 @@ var DefaultSessionReader = class _DefaultSessionReader {
|
|
|
28720
28934
|
const sessionPath = sessionScopedPath(rootDir, sessionId, ".jsonl");
|
|
28721
28935
|
let mtimeMs = null;
|
|
28722
28936
|
try {
|
|
28723
|
-
const
|
|
28724
|
-
mtimeMs =
|
|
28937
|
+
const stat11 = await fsp7.stat(sessionPath);
|
|
28938
|
+
mtimeMs = stat11.mtimeMs;
|
|
28725
28939
|
} catch {
|
|
28726
28940
|
this.eventCache.delete(sessionId);
|
|
28727
28941
|
this.eventCacheMtimes.delete(sessionId);
|