eminiar 0.13.4 → 0.13.5
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/.claude-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/dist/cli.js +424 -257
- package/dist/{hook-chunk-6EFFDI3S.js → hook-chunk-RE4WT5D3.js} +179 -36
- package/dist/{hook-hooks-YGXLOZ6H.js → hook-hooks-5H6LFYD5.js} +2 -2
- package/dist/hook.js +6 -6
- package/dist/server.js +359 -216
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -16309,8 +16309,8 @@ var init_to_json_schema = __esm({
|
|
|
16309
16309
|
function aggregateChecks(schema) {
|
|
16310
16310
|
const agg = {};
|
|
16311
16311
|
const def = schema._zod.def;
|
|
16312
|
-
const
|
|
16313
|
-
for (const ch of
|
|
16312
|
+
const list3 = schema._zod.traits.has("$ZodCheck") ? [schema, ...def.checks ?? []] : def.checks ?? [];
|
|
16313
|
+
for (const ch of list3)
|
|
16314
16314
|
contributors[ch._zod.def.check]?.(agg, ch._zod.def);
|
|
16315
16315
|
const bag = schema._zod.bag;
|
|
16316
16316
|
if (bag.minimum !== void 0)
|
|
@@ -24758,6 +24758,57 @@ var init_storage = __esm({
|
|
|
24758
24758
|
}
|
|
24759
24759
|
});
|
|
24760
24760
|
|
|
24761
|
+
// src/search/typo.ts
|
|
24762
|
+
function editDistance(a, b, max = 3) {
|
|
24763
|
+
if (Math.abs(a.length - b.length) > max) return max + 1;
|
|
24764
|
+
const prev2 = [];
|
|
24765
|
+
let prev = Array.from({ length: b.length + 1 }, (_, j) => j);
|
|
24766
|
+
let cur = new Array(b.length + 1).fill(0);
|
|
24767
|
+
for (let i = 1; i <= a.length; i++) {
|
|
24768
|
+
cur[0] = i;
|
|
24769
|
+
let rowMin = cur[0];
|
|
24770
|
+
for (let j = 1; j <= b.length; j++) {
|
|
24771
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
24772
|
+
let v = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + cost);
|
|
24773
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
24774
|
+
v = Math.min(v, prev2[j - 2] + 1);
|
|
24775
|
+
}
|
|
24776
|
+
cur[j] = v;
|
|
24777
|
+
if (v < rowMin) rowMin = v;
|
|
24778
|
+
}
|
|
24779
|
+
if (rowMin > max) return max + 1;
|
|
24780
|
+
prev2.splice(0, prev2.length, ...prev);
|
|
24781
|
+
[prev, cur] = [cur, prev];
|
|
24782
|
+
}
|
|
24783
|
+
return prev[b.length];
|
|
24784
|
+
}
|
|
24785
|
+
function correctTerms(db, terms) {
|
|
24786
|
+
const corrections = [];
|
|
24787
|
+
const out = terms.map((term) => {
|
|
24788
|
+
if (term.length < 4 || /[^a-z0-9]/.test(term) || db.termExists(term)) return term;
|
|
24789
|
+
const max = term.length >= 7 ? 2 : 1;
|
|
24790
|
+
const candidates2 = db.vocabCandidates(term[0], 3e3);
|
|
24791
|
+
let best;
|
|
24792
|
+
for (const c of candidates2) {
|
|
24793
|
+
if (c.term.length < 3) continue;
|
|
24794
|
+
const d = editDistance(term, c.term, max);
|
|
24795
|
+
if (d > max) continue;
|
|
24796
|
+
if (!best || d < best.d || d === best.d && c.df > best.df)
|
|
24797
|
+
best = { term: c.term, d, df: c.df };
|
|
24798
|
+
}
|
|
24799
|
+
if (!best) return term;
|
|
24800
|
+
corrections.push({ from: term, to: best.term });
|
|
24801
|
+
return `${best.term}*`;
|
|
24802
|
+
});
|
|
24803
|
+
return { terms: out, corrections };
|
|
24804
|
+
}
|
|
24805
|
+
var init_typo = __esm({
|
|
24806
|
+
"src/search/typo.ts"() {
|
|
24807
|
+
"use strict";
|
|
24808
|
+
init_esm_shims();
|
|
24809
|
+
}
|
|
24810
|
+
});
|
|
24811
|
+
|
|
24761
24812
|
// src/swarm/glob.ts
|
|
24762
24813
|
function normalize(g) {
|
|
24763
24814
|
let s = g.trim().replace(/\\/g, "/");
|
|
@@ -24893,6 +24944,52 @@ function mergeContext(...layers) {
|
|
|
24893
24944
|
}
|
|
24894
24945
|
return out;
|
|
24895
24946
|
}
|
|
24947
|
+
function unknownKeys(v, s = RawFile, at = []) {
|
|
24948
|
+
if (s instanceof external_exports.ZodOptional) s = s.unwrap();
|
|
24949
|
+
if (Array.isArray(v))
|
|
24950
|
+
return s instanceof external_exports.ZodArray ? v.flatMap((x, i) => unknownKeys(x, s.element, [...at, String(i)])) : [];
|
|
24951
|
+
if (!v || typeof v !== "object") return [];
|
|
24952
|
+
const entries = Object.entries(v);
|
|
24953
|
+
if (s instanceof external_exports.ZodRecord)
|
|
24954
|
+
return entries.flatMap(([k, x]) => unknownKeys(x, s.valueType, [...at, k]));
|
|
24955
|
+
if (!(s instanceof external_exports.ZodObject)) return [];
|
|
24956
|
+
const known = Object.keys(s.shape);
|
|
24957
|
+
return entries.flatMap(
|
|
24958
|
+
([k, x]) => Object.hasOwn(s.shape, k) ? unknownKeys(x, s.shape[k], [...at, k]) : at.length === 0 && (k.startsWith("x-") || k === "<<") ? [] : [{ at, key: k, known }]
|
|
24959
|
+
);
|
|
24960
|
+
}
|
|
24961
|
+
function schemaKeys(s = RawFile, out = /* @__PURE__ */ new Set()) {
|
|
24962
|
+
if (s instanceof external_exports.ZodOptional) s = s.unwrap();
|
|
24963
|
+
if (s instanceof external_exports.ZodArray) schemaKeys(s.element, out);
|
|
24964
|
+
else if (s instanceof external_exports.ZodRecord) schemaKeys(s.valueType, out);
|
|
24965
|
+
else if (s instanceof external_exports.ZodObject) {
|
|
24966
|
+
for (const [k, v] of Object.entries(s.shape))
|
|
24967
|
+
if (!out.has(k)) {
|
|
24968
|
+
out.add(k);
|
|
24969
|
+
schemaKeys(v, out);
|
|
24970
|
+
}
|
|
24971
|
+
}
|
|
24972
|
+
return out;
|
|
24973
|
+
}
|
|
24974
|
+
function restrictionLike(key, known) {
|
|
24975
|
+
let best;
|
|
24976
|
+
for (const k of known) {
|
|
24977
|
+
if (!RESTRICTION_KEY.test(k)) continue;
|
|
24978
|
+
const d = editDistance(key.toLowerCase(), k.toLowerCase(), 2);
|
|
24979
|
+
if (d <= 2 && key.length >= 3 && (!best || d < best.d)) best = { k, d };
|
|
24980
|
+
}
|
|
24981
|
+
if (best) return best.k;
|
|
24982
|
+
return RESTRICTION_KEY.test(key) ? "" : void 0;
|
|
24983
|
+
}
|
|
24984
|
+
function typoOf(key, known) {
|
|
24985
|
+
const max = key.length >= 7 ? 2 : 1;
|
|
24986
|
+
let best;
|
|
24987
|
+
for (const k of known) {
|
|
24988
|
+
const d = editDistance(key.toLowerCase(), k.toLowerCase(), max);
|
|
24989
|
+
if (d <= max && (!best || d < best.d)) best = { k, d };
|
|
24990
|
+
}
|
|
24991
|
+
return best?.k;
|
|
24992
|
+
}
|
|
24896
24993
|
function roleRange(defaults, a, at, issue2) {
|
|
24897
24994
|
const spec = a.model_range ?? defaults?.model_range;
|
|
24898
24995
|
if (!spec || !spec.floor && !spec.ceiling) return void 0;
|
|
@@ -25028,6 +25125,27 @@ function parseSwarmYaml(text3, file3, rel) {
|
|
|
25028
25125
|
for (const role of Object.keys(agents))
|
|
25029
25126
|
checkName(["swarms", name, "agents", role], role, "agent");
|
|
25030
25127
|
}
|
|
25128
|
+
const ignoredKeys = [];
|
|
25129
|
+
const allKeys = schemaKeys();
|
|
25130
|
+
for (const u of unknownKeys(js)) {
|
|
25131
|
+
const near = typoOf(u.key, u.known);
|
|
25132
|
+
const found = { path: u.at.join("."), line: lineOf([...u.at, u.key]) };
|
|
25133
|
+
if (allKeys.has(u.key))
|
|
25134
|
+
issues.push({ ...found, message: `unknown key "${u.key}": not allowed here` });
|
|
25135
|
+
else if (near)
|
|
25136
|
+
issues.push({ ...found, message: `unknown key "${u.key}" (did you mean "${near}"?)` });
|
|
25137
|
+
else if (u.at.length === 4 && u.at[0] === "swarms" && u.at[2] === "agents" && restrictionLike(u.key, u.known) !== void 0) {
|
|
25138
|
+
const like = restrictionLike(u.key, u.known);
|
|
25139
|
+
issues.push({
|
|
25140
|
+
...found,
|
|
25141
|
+
message: `unknown key "${u.key}" looks like a restriction${like ? ` (did you mean "${like}"?)` : ""}: ignoring it would silently drop a limit`
|
|
25142
|
+
});
|
|
25143
|
+
} else
|
|
25144
|
+
ignoredKeys.push({
|
|
25145
|
+
...found,
|
|
25146
|
+
message: `unknown key "${u.key}" ignored: not a setting in this eminiar version`
|
|
25147
|
+
});
|
|
25148
|
+
}
|
|
25031
25149
|
const parsed = RawFile.safeParse(js);
|
|
25032
25150
|
if (!parsed.success) {
|
|
25033
25151
|
return {
|
|
@@ -25045,15 +25163,9 @@ function parseSwarmYaml(text3, file3, rel) {
|
|
|
25045
25163
|
]
|
|
25046
25164
|
};
|
|
25047
25165
|
}
|
|
25048
|
-
for (const k of Object.keys(js))
|
|
25049
|
-
if (!TOP_KEYS.has(k) && !k.startsWith("x-") && k !== "<<")
|
|
25050
|
-
issue2(
|
|
25051
|
-
[k],
|
|
25052
|
-
`unknown key "${k}" (top-level keys: ${[...TOP_KEYS].join(", ")}; x-* keys may hold YAML anchors)`
|
|
25053
|
-
);
|
|
25054
25166
|
const config2 = resolve3(parsed.data, file3, rel, issue2);
|
|
25055
25167
|
if (issues.length) return { state: "invalid", file: file3, rel, enforce, issues };
|
|
25056
|
-
return { state: "ok", config: config2 };
|
|
25168
|
+
return { state: "ok", config: { ...config2, ignoredKeys } };
|
|
25057
25169
|
}
|
|
25058
25170
|
function resolve3(raw, file3, rel, issue2) {
|
|
25059
25171
|
const swarms = [];
|
|
@@ -25174,13 +25286,14 @@ function findRole(config2, agentType) {
|
|
|
25174
25286
|
for (const role of swarm.roles) if (role.agentType === agentType) return { swarm, role };
|
|
25175
25287
|
return void 0;
|
|
25176
25288
|
}
|
|
25177
|
-
var yamlLib, SWARM_FILES, AGENT_NAME_MAX, NAME_RE, NAME_MAX, NAME_MSG, noFence, FENCE_MSG, MODEL_RE,
|
|
25289
|
+
var yamlLib, SWARM_FILES, AGENT_NAME_MAX, NAME_RE, NAME_MAX, NAME_MSG, noFence, FENCE_MSG, MODEL_RE, DEFAULT_CONTEXT, AGENT_COLORS, ToolName, SkillName, Model, rank, RawModelRange, Glob, AgentName, RawContext, RawHookCommand, RawHookMatcher, RawHooks, RawAgent, RawSwarm, RawFile, uniq, RESTRICTION_KEY, MAX_FILE_CHARS, cache3, STARTER_YAML;
|
|
25178
25290
|
var init_config2 = __esm({
|
|
25179
25291
|
"src/swarm/config.ts"() {
|
|
25180
25292
|
"use strict";
|
|
25181
25293
|
init_esm_shims();
|
|
25182
25294
|
init_zod();
|
|
25183
25295
|
init_types();
|
|
25296
|
+
init_typo();
|
|
25184
25297
|
init_dispatch();
|
|
25185
25298
|
init_glob();
|
|
25186
25299
|
init_types2();
|
|
@@ -25192,15 +25305,6 @@ var init_config2 = __esm({
|
|
|
25192
25305
|
noFence = (s) => !s.includes("---");
|
|
25193
25306
|
FENCE_MSG = 'must not contain "---" (Claude Code would end the agent frontmatter there)';
|
|
25194
25307
|
MODEL_RE = /^(?:inherit|opusplan|(?:sonnet|opus|haiku|fable)(?:\[1m\])?|(?:[a-z0-9-]+\.)*claude-[a-z0-9.:@-]+(?:\[1m\])?)$/;
|
|
25195
|
-
TOP_KEYS = /* @__PURE__ */ new Set([
|
|
25196
|
-
"version",
|
|
25197
|
-
"enabled",
|
|
25198
|
-
"sync",
|
|
25199
|
-
"enforce",
|
|
25200
|
-
"allowed_agents",
|
|
25201
|
-
"defaults",
|
|
25202
|
-
"swarms"
|
|
25203
|
-
]);
|
|
25204
25308
|
DEFAULT_CONTEXT = {
|
|
25205
25309
|
memories: 4,
|
|
25206
25310
|
docs: 2,
|
|
@@ -25229,7 +25333,7 @@ var init_config2 = __esm({
|
|
|
25229
25333
|
).refine(noFence, FENCE_MSG);
|
|
25230
25334
|
Model = external_exports.string().max(100).regex(MODEL_RE, "a model alias (inherit, sonnet, opus, haiku, fable) or a Claude model id").refine(noFence, FENCE_MSG);
|
|
25231
25335
|
rank = (t) => TIERS.indexOf(t);
|
|
25232
|
-
RawModelRange = external_exports.
|
|
25336
|
+
RawModelRange = external_exports.object({ floor: external_exports.enum(TIERS).optional(), ceiling: external_exports.enum(TIERS).optional() }).refine(
|
|
25233
25337
|
(r) => !r.floor || !r.ceiling || rank(r.floor) <= rank(r.ceiling),
|
|
25234
25338
|
`floor must not be above ceiling (${TIERS.join(" < ")})`
|
|
25235
25339
|
);
|
|
@@ -25253,7 +25357,7 @@ var init_config2 = __esm({
|
|
|
25253
25357
|
(n) => !n.startsWith("swarm-"),
|
|
25254
25358
|
"swarm workers need no entry: they are allowed during a run of their swarm"
|
|
25255
25359
|
);
|
|
25256
|
-
RawContext = external_exports.
|
|
25360
|
+
RawContext = external_exports.object({
|
|
25257
25361
|
memories: external_exports.number().int().min(0).max(10).optional(),
|
|
25258
25362
|
docs: external_exports.number().int().min(0).max(10).optional(),
|
|
25259
25363
|
history: external_exports.boolean().optional(),
|
|
@@ -25262,12 +25366,12 @@ var init_config2 = __esm({
|
|
|
25262
25366
|
// SubagentStart context over 10,000 characters is moved to a file Claude may never read.
|
|
25263
25367
|
max_chars: external_exports.number().int().min(500).max(9e3).optional()
|
|
25264
25368
|
});
|
|
25265
|
-
RawHookCommand = external_exports.
|
|
25369
|
+
RawHookCommand = external_exports.object({
|
|
25266
25370
|
type: external_exports.literal("command"),
|
|
25267
25371
|
command: external_exports.string().trim().min(1).max(2e3).refine(noFence, FENCE_MSG),
|
|
25268
25372
|
timeout: external_exports.number().int().positive().max(600).optional()
|
|
25269
25373
|
});
|
|
25270
|
-
RawHookMatcher = external_exports.
|
|
25374
|
+
RawHookMatcher = external_exports.object({
|
|
25271
25375
|
matcher: external_exports.string().max(200).refine(noFence, FENCE_MSG).refine((m) => {
|
|
25272
25376
|
try {
|
|
25273
25377
|
new RegExp(m);
|
|
@@ -25278,12 +25382,12 @@ var init_config2 = __esm({
|
|
|
25278
25382
|
}, "not a valid regular expression (Claude Code matches tool names with it)").optional(),
|
|
25279
25383
|
hooks: external_exports.array(RawHookCommand).min(1).max(10)
|
|
25280
25384
|
});
|
|
25281
|
-
RawHooks = external_exports.
|
|
25385
|
+
RawHooks = external_exports.object({
|
|
25282
25386
|
PreToolUse: external_exports.array(RawHookMatcher).max(10).optional(),
|
|
25283
25387
|
PostToolUse: external_exports.array(RawHookMatcher).max(10).optional(),
|
|
25284
25388
|
Stop: external_exports.array(RawHookMatcher).max(10).optional()
|
|
25285
25389
|
});
|
|
25286
|
-
RawAgent = external_exports.
|
|
25390
|
+
RawAgent = external_exports.object({
|
|
25287
25391
|
description: external_exports.string().trim().min(1).max(500).refine(noFence, FENCE_MSG),
|
|
25288
25392
|
prompt: external_exports.string().max(2e4).optional(),
|
|
25289
25393
|
model: Model.optional(),
|
|
@@ -25301,7 +25405,7 @@ var init_config2 = __esm({
|
|
|
25301
25405
|
color: external_exports.enum(AGENT_COLORS).optional(),
|
|
25302
25406
|
context: RawContext.optional()
|
|
25303
25407
|
});
|
|
25304
|
-
RawSwarm = external_exports.
|
|
25408
|
+
RawSwarm = external_exports.object({
|
|
25305
25409
|
description: external_exports.string().trim().min(1).max(500),
|
|
25306
25410
|
topology: external_exports.enum(TOPOLOGIES).optional(),
|
|
25307
25411
|
max_agents: external_exports.number().int().min(1).max(16).optional(),
|
|
@@ -25317,7 +25421,7 @@ var init_config2 = __esm({
|
|
|
25317
25421
|
sync: external_exports.enum(["auto", "manual"]).optional(),
|
|
25318
25422
|
enforce: external_exports.boolean().optional(),
|
|
25319
25423
|
allowed_agents: external_exports.array(AgentName).max(50).optional(),
|
|
25320
|
-
defaults: external_exports.
|
|
25424
|
+
defaults: external_exports.object({
|
|
25321
25425
|
model: Model.optional(),
|
|
25322
25426
|
model_range: RawModelRange.optional(),
|
|
25323
25427
|
skills: external_exports.array(SkillName).max(20).optional(),
|
|
@@ -25326,6 +25430,7 @@ var init_config2 = __esm({
|
|
|
25326
25430
|
swarms: external_exports.record(external_exports.string(), RawSwarm)
|
|
25327
25431
|
});
|
|
25328
25432
|
uniq = (xs) => [...new Set(xs)];
|
|
25433
|
+
RESTRICTION_KEY = /tool|scope|hook|allow|deny|permission|model|effort|count/i;
|
|
25329
25434
|
MAX_FILE_CHARS = 256e3;
|
|
25330
25435
|
cache3 = /* @__PURE__ */ new Map();
|
|
25331
25436
|
STARTER_YAML = `# eminiar agent swarms (opt-in). Docs: https://github.com/rydn/eminiar/blob/main/docs/swarms.md
|
|
@@ -25838,9 +25943,9 @@ function consentedOrigins(a) {
|
|
|
25838
25943
|
return out;
|
|
25839
25944
|
}
|
|
25840
25945
|
function withConsentedOrigin(a, origin) {
|
|
25841
|
-
const
|
|
25842
|
-
if (!
|
|
25843
|
-
return
|
|
25946
|
+
const list3 = consentedOrigins(a);
|
|
25947
|
+
if (!list3.includes(origin)) list3.push(origin);
|
|
25948
|
+
return list3;
|
|
25844
25949
|
}
|
|
25845
25950
|
function isLoopback(url2) {
|
|
25846
25951
|
if (!url2) return false;
|
|
@@ -28012,11 +28117,11 @@ function createOpenAIProvider(r, cfg, deps = {}) {
|
|
|
28012
28117
|
};
|
|
28013
28118
|
}
|
|
28014
28119
|
function mapAnswers(reqs, items2, raw, cat, askTool) {
|
|
28015
|
-
const
|
|
28016
|
-
if (!
|
|
28120
|
+
const list3 = raw && typeof raw === "object" && Array.isArray(raw.items) ? raw.items : void 0;
|
|
28121
|
+
if (!list3) throw new ProviderError("invalid", "the answer has no items array");
|
|
28017
28122
|
const Item = itemSchema(cat, askTool);
|
|
28018
28123
|
const byId = /* @__PURE__ */ new Map();
|
|
28019
|
-
for (const x of
|
|
28124
|
+
for (const x of list3) {
|
|
28020
28125
|
const p2 = Item.safeParse(x);
|
|
28021
28126
|
if (p2.success && !byId.has(p2.data.id)) byId.set(p2.data.id, p2.data);
|
|
28022
28127
|
}
|
|
@@ -29437,8 +29542,8 @@ function pricedSavings(stats, calls, overrides, opts = {}) {
|
|
|
29437
29542
|
};
|
|
29438
29543
|
const bySession2 = /* @__PURE__ */ new Map();
|
|
29439
29544
|
for (const c of calls) {
|
|
29440
|
-
const
|
|
29441
|
-
if (
|
|
29545
|
+
const list3 = bySession2.get(c.session_id);
|
|
29546
|
+
if (list3) list3.push(c);
|
|
29442
29547
|
else bySession2.set(c.session_id, [c]);
|
|
29443
29548
|
}
|
|
29444
29549
|
const sessionModel = /* @__PURE__ */ new Map();
|
|
@@ -29597,29 +29702,29 @@ function promptWindows(prompts, calls) {
|
|
|
29597
29702
|
const bySession2 = /* @__PURE__ */ new Map();
|
|
29598
29703
|
for (const p2 of prompts) {
|
|
29599
29704
|
if (!p2.sessionId) continue;
|
|
29600
|
-
const
|
|
29601
|
-
if (
|
|
29705
|
+
const list3 = bySession2.get(p2.sessionId);
|
|
29706
|
+
if (list3) list3.push(p2);
|
|
29602
29707
|
else bySession2.set(p2.sessionId, [p2]);
|
|
29603
29708
|
}
|
|
29604
|
-
for (const
|
|
29709
|
+
for (const list3 of bySession2.values()) list3.sort((a, b) => a.ts - b.ts || a.id - b.id);
|
|
29605
29710
|
const out = /* @__PURE__ */ new Map();
|
|
29606
29711
|
for (const p2 of prompts) out.set(p2.id, []);
|
|
29607
29712
|
for (const c of calls) {
|
|
29608
29713
|
if (c.sidechain) continue;
|
|
29609
|
-
const
|
|
29610
|
-
if (!
|
|
29714
|
+
const list3 = bySession2.get(c.session_id);
|
|
29715
|
+
if (!list3) continue;
|
|
29611
29716
|
let lo = 0;
|
|
29612
|
-
let hi =
|
|
29717
|
+
let hi = list3.length - 1;
|
|
29613
29718
|
let at = -1;
|
|
29614
29719
|
while (lo <= hi) {
|
|
29615
29720
|
const mid = lo + hi >> 1;
|
|
29616
|
-
if (
|
|
29721
|
+
if (list3[mid].ts <= c.ts) {
|
|
29617
29722
|
at = mid;
|
|
29618
29723
|
lo = mid + 1;
|
|
29619
29724
|
} else hi = mid - 1;
|
|
29620
29725
|
}
|
|
29621
29726
|
if (at < 0) continue;
|
|
29622
|
-
out.get(
|
|
29727
|
+
out.get(list3[at].id)?.push(c);
|
|
29623
29728
|
}
|
|
29624
29729
|
return out;
|
|
29625
29730
|
}
|
|
@@ -30223,8 +30328,8 @@ var init_learn = __esm({
|
|
|
30223
30328
|
const m = /* @__PURE__ */ new Map();
|
|
30224
30329
|
for (const p2 of allRows(this.db, { surface: "prompt", since })) {
|
|
30225
30330
|
if (!p2.sessionId) continue;
|
|
30226
|
-
const
|
|
30227
|
-
if (
|
|
30331
|
+
const list3 = m.get(p2.sessionId);
|
|
30332
|
+
if (list3) list3.push(p2);
|
|
30228
30333
|
else m.set(p2.sessionId, [p2]);
|
|
30229
30334
|
}
|
|
30230
30335
|
this.promptsBySession = m;
|
|
@@ -30250,8 +30355,8 @@ var init_learn = __esm({
|
|
|
30250
30355
|
const bySession2 = /* @__PURE__ */ new Map();
|
|
30251
30356
|
for (const r of targets) {
|
|
30252
30357
|
if (r.agentId || !r.sessionId) continue;
|
|
30253
|
-
const
|
|
30254
|
-
if (
|
|
30358
|
+
const list3 = bySession2.get(r.sessionId);
|
|
30359
|
+
if (list3) list3.push(r);
|
|
30255
30360
|
else bySession2.set(r.sessionId, [r]);
|
|
30256
30361
|
}
|
|
30257
30362
|
if (!bySession2.size) return;
|
|
@@ -30269,8 +30374,8 @@ var init_learn = __esm({
|
|
|
30269
30374
|
const callsBy = /* @__PURE__ */ new Map();
|
|
30270
30375
|
for (const c of this.calls(sessionId)) {
|
|
30271
30376
|
if (!c.sidechain || !c.agent_id || this.taken.has(c.agent_id)) continue;
|
|
30272
|
-
const
|
|
30273
|
-
if (
|
|
30377
|
+
const list3 = callsBy.get(c.agent_id);
|
|
30378
|
+
if (list3) list3.push(c);
|
|
30274
30379
|
else callsBy.set(c.agent_id, [c]);
|
|
30275
30380
|
}
|
|
30276
30381
|
const agents = [...callsBy].map(([id, cs]) => ({
|
|
@@ -31235,6 +31340,68 @@ function existingGenerated(dir) {
|
|
|
31235
31340
|
}
|
|
31236
31341
|
return out;
|
|
31237
31342
|
}
|
|
31343
|
+
function ignoredWhere(ignored, config2, agentType) {
|
|
31344
|
+
const hit = config2.swarms.flatMap(
|
|
31345
|
+
(swarm) => swarm.roles.filter((r) => r.agentType === agentType).map((r) => ({ swarm, role: r }))
|
|
31346
|
+
)[0];
|
|
31347
|
+
if (!hit) return [];
|
|
31348
|
+
const out = [];
|
|
31349
|
+
for (const i of ignored) {
|
|
31350
|
+
const seg = i.path === "" ? [] : i.path.split(".");
|
|
31351
|
+
const name = /"(.+?)"/.exec(i.message)?.[1] ?? "?";
|
|
31352
|
+
const mine = seg[0] !== "swarms" || seg.length < 2 || seg[1] === hit.swarm.name && (seg.length < 4 || seg[2] !== "agents" || seg[3] === hit.role.role);
|
|
31353
|
+
if (mine) out.push(name);
|
|
31354
|
+
}
|
|
31355
|
+
return out;
|
|
31356
|
+
}
|
|
31357
|
+
function frontmatterOf(raw) {
|
|
31358
|
+
const content = raw.replace(/\r\n/g, "\n");
|
|
31359
|
+
const end = content.indexOf("\n---\n", 3);
|
|
31360
|
+
if (!content.startsWith("---\n") || end === -1) return void 0;
|
|
31361
|
+
try {
|
|
31362
|
+
const v = yaml2().parse(content.slice(4, end));
|
|
31363
|
+
return v && typeof v === "object" ? v : void 0;
|
|
31364
|
+
} catch {
|
|
31365
|
+
return void 0;
|
|
31366
|
+
}
|
|
31367
|
+
}
|
|
31368
|
+
function tightens(oldRaw, newRaw) {
|
|
31369
|
+
const o = frontmatterOf(oldRaw);
|
|
31370
|
+
const n = frontmatterOf(newRaw);
|
|
31371
|
+
if (!o || !n) return false;
|
|
31372
|
+
let tighter = false;
|
|
31373
|
+
for (const k of Object.keys(o)) {
|
|
31374
|
+
if (NEUTRAL_KEYS.has(k)) continue;
|
|
31375
|
+
if (!(k in n)) return false;
|
|
31376
|
+
const a = o[k];
|
|
31377
|
+
const b = n[k];
|
|
31378
|
+
if (JSON.stringify(a) === JSON.stringify(b)) continue;
|
|
31379
|
+
if (k === "tools") {
|
|
31380
|
+
const ob = new Set(list(a));
|
|
31381
|
+
const nb = list(b);
|
|
31382
|
+
if (!nb.every((t) => ob.has(t))) return false;
|
|
31383
|
+
tighter = true;
|
|
31384
|
+
} else if (k === "disallowedTools") {
|
|
31385
|
+
const nb = new Set(list(b));
|
|
31386
|
+
if (!list(a).every((t) => nb.has(t))) return false;
|
|
31387
|
+
tighter = true;
|
|
31388
|
+
} else if (k === "hooks") {
|
|
31389
|
+
const oh = a ?? {};
|
|
31390
|
+
const nh = b ?? {};
|
|
31391
|
+
for (const [ev3, entries] of Object.entries(oh)) {
|
|
31392
|
+
const have = new Set((nh[ev3] ?? []).map((e) => JSON.stringify(e)));
|
|
31393
|
+
if (!Array.isArray(entries) || !entries.every((e) => have.has(JSON.stringify(e))))
|
|
31394
|
+
return false;
|
|
31395
|
+
}
|
|
31396
|
+
tighter = true;
|
|
31397
|
+
} else if (k === "maxTurns") {
|
|
31398
|
+
if (typeof a !== "number" || typeof b !== "number" || b > a) return false;
|
|
31399
|
+
tighter = true;
|
|
31400
|
+
} else return false;
|
|
31401
|
+
}
|
|
31402
|
+
for (const k of Object.keys(n)) if (!(k in o) && !NEUTRAL_KEYS.has(k)) tighter = true;
|
|
31403
|
+
return tighter;
|
|
31404
|
+
}
|
|
31238
31405
|
function planAgentSync(root, config2, opts = {}) {
|
|
31239
31406
|
const dir = agentsDir(root);
|
|
31240
31407
|
const wantedRoles = config2?.enabled ? config2.swarms.flatMap((swarm) => swarm.roles.map((role) => ({ swarm, role }))) : [];
|
|
@@ -31302,6 +31469,24 @@ function planAgentSync(root, config2, opts = {}) {
|
|
|
31302
31469
|
reason: config2?.enabled ? "no longer in the swarm file" : "swarms are disabled"
|
|
31303
31470
|
}
|
|
31304
31471
|
);
|
|
31472
|
+
const ignored = config2?.ignoredKeys ?? [];
|
|
31473
|
+
if (ignored.length && !opts.force) {
|
|
31474
|
+
const holds = (agentType) => ignoredWhere(ignored, config2, agentType);
|
|
31475
|
+
return actions.map((a) => {
|
|
31476
|
+
if (a.action !== "update") return a;
|
|
31477
|
+
const where = holds(a.agentType);
|
|
31478
|
+
if (!where.length) return a;
|
|
31479
|
+
const old = generated.get(a.agentType);
|
|
31480
|
+
if (old && tightens(old.content, a.content ?? "")) return a;
|
|
31481
|
+
return {
|
|
31482
|
+
agentType: a.agentType,
|
|
31483
|
+
path: a.path,
|
|
31484
|
+
action: "conflict",
|
|
31485
|
+
held: true,
|
|
31486
|
+
reason: `kept: ${config2.rel} has keys this eminiar version does not know (${where.slice(0, 3).join(", ")}${where.length > 3 ? ", ..." : ""}), and a newer one may have generated this file with them; update eminiar, or sync with --force`
|
|
31487
|
+
};
|
|
31488
|
+
});
|
|
31489
|
+
}
|
|
31305
31490
|
return actions;
|
|
31306
31491
|
}
|
|
31307
31492
|
function syncAgents(root, config2, opts = {}) {
|
|
@@ -31343,7 +31528,7 @@ function syncAgents(root, config2, opts = {}) {
|
|
|
31343
31528
|
}
|
|
31344
31529
|
return { actions, changed, conflicts: actions.filter((a) => a.action === "conflict").length };
|
|
31345
31530
|
}
|
|
31346
|
-
var MARKER_PREFIX, HASH_RE, RANGE_RE, WORKER_EM_TOOLS, yamlLib2, EXEC_TOOLS, EM_MCP_PREFIXES, AGENTS_REL, TOPOLOGY_RULE, execToolNames, hashOf, SHARED_TREE_RULE;
|
|
31531
|
+
var MARKER_PREFIX, HASH_RE, RANGE_RE, WORKER_EM_TOOLS, yamlLib2, EXEC_TOOLS, EM_MCP_PREFIXES, AGENTS_REL, TOPOLOGY_RULE, execToolNames, hashOf, SHARED_TREE_RULE, list, NEUTRAL_KEYS;
|
|
31347
31532
|
var init_agents = __esm({
|
|
31348
31533
|
"src/swarm/agents.ts"() {
|
|
31349
31534
|
"use strict";
|
|
@@ -31387,6 +31572,8 @@ ${fm}
|
|
|
31387
31572
|
${rest2}` : `${fm}
|
|
31388
31573
|
${rest2}`).digest("hex").slice(0, 12);
|
|
31389
31574
|
SHARED_TREE_RULE = "Other workers may be editing this working tree at the same time, and their changes are not committed. Never run `git stash`, `git checkout`, `git switch`, `git reset`, `git restore` or `git clean`, not even on one path: they hide or wipe another worker's work. If you commit, add only the files you changed: `git add -A` or `git commit -a` takes their unfinished work with yours. To test without your change (a mutation check), copy the files into a scratch directory outside the tree and run the tests there.";
|
|
31575
|
+
list = (v) => typeof v === "string" ? v.split(",").map((x) => x.trim()).filter(Boolean) : [];
|
|
31576
|
+
NEUTRAL_KEYS = /* @__PURE__ */ new Set(["name", "description", "skills", "color", "model", "effort"]);
|
|
31390
31577
|
}
|
|
31391
31578
|
});
|
|
31392
31579
|
|
|
@@ -31579,8 +31766,8 @@ function manifest(dir) {
|
|
|
31579
31766
|
}
|
|
31580
31767
|
function agentPaths(dir) {
|
|
31581
31768
|
const a = manifest(dir)?.agents;
|
|
31582
|
-
const
|
|
31583
|
-
return (
|
|
31769
|
+
const list3 = typeof a === "string" ? [a] : Array.isArray(a) ? a.filter((x) => typeof x === "string") : [];
|
|
31770
|
+
return (list3.length ? list3 : ["./agents"]).map((p2) => resolve4(dir, p2));
|
|
31584
31771
|
}
|
|
31585
31772
|
function pluginDefs(segments, env, home) {
|
|
31586
31773
|
const [plugin, ...rest2] = segments;
|
|
@@ -34881,9 +35068,9 @@ var require_micromatch = __commonJS({
|
|
|
34881
35068
|
const index = v.indexOf("{");
|
|
34882
35069
|
return index > -1 && v.indexOf("}", index) > -1;
|
|
34883
35070
|
};
|
|
34884
|
-
var micromatch2 = (
|
|
35071
|
+
var micromatch2 = (list3, patterns, options) => {
|
|
34885
35072
|
patterns = [].concat(patterns);
|
|
34886
|
-
|
|
35073
|
+
list3 = [].concat(list3);
|
|
34887
35074
|
let omit2 = /* @__PURE__ */ new Set();
|
|
34888
35075
|
let keep = /* @__PURE__ */ new Set();
|
|
34889
35076
|
let items2 = /* @__PURE__ */ new Set();
|
|
@@ -34898,7 +35085,7 @@ var require_micromatch = __commonJS({
|
|
|
34898
35085
|
let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true);
|
|
34899
35086
|
let negated = isMatch.state.negated || isMatch.state.negatedExtglob;
|
|
34900
35087
|
if (negated) negatives++;
|
|
34901
|
-
for (let item of
|
|
35088
|
+
for (let item of list3) {
|
|
34902
35089
|
let matched = isMatch(item, true);
|
|
34903
35090
|
let match = negated ? !matched.isMatch : matched.isMatch;
|
|
34904
35091
|
if (!match) continue;
|
|
@@ -34926,7 +35113,7 @@ var require_micromatch = __commonJS({
|
|
|
34926
35113
|
micromatch2.matcher = (pattern2, options) => picomatch(pattern2, options);
|
|
34927
35114
|
micromatch2.isMatch = (str3, patterns, options) => picomatch(patterns, options)(str3);
|
|
34928
35115
|
micromatch2.any = micromatch2.isMatch;
|
|
34929
|
-
micromatch2.not = (
|
|
35116
|
+
micromatch2.not = (list3, patterns, options = {}) => {
|
|
34930
35117
|
patterns = [].concat(patterns).map(String);
|
|
34931
35118
|
let result = /* @__PURE__ */ new Set();
|
|
34932
35119
|
let items2 = [];
|
|
@@ -34934,7 +35121,7 @@ var require_micromatch = __commonJS({
|
|
|
34934
35121
|
if (options.onResult) options.onResult(state);
|
|
34935
35122
|
items2.push(state.output);
|
|
34936
35123
|
};
|
|
34937
|
-
let matches2 = new Set(micromatch2(
|
|
35124
|
+
let matches2 = new Set(micromatch2(list3, patterns, { ...options, onResult }));
|
|
34938
35125
|
for (let item of items2) {
|
|
34939
35126
|
if (!matches2.has(item)) {
|
|
34940
35127
|
result.add(item);
|
|
@@ -34968,8 +35155,8 @@ var require_micromatch = __commonJS({
|
|
|
34968
35155
|
for (let key of keys) res[key] = obj[key];
|
|
34969
35156
|
return res;
|
|
34970
35157
|
};
|
|
34971
|
-
micromatch2.some = (
|
|
34972
|
-
let items2 = [].concat(
|
|
35158
|
+
micromatch2.some = (list3, patterns, options) => {
|
|
35159
|
+
let items2 = [].concat(list3);
|
|
34973
35160
|
for (let pattern2 of [].concat(patterns)) {
|
|
34974
35161
|
let isMatch = picomatch(String(pattern2), options);
|
|
34975
35162
|
if (items2.some((item) => isMatch(item))) {
|
|
@@ -34978,8 +35165,8 @@ var require_micromatch = __commonJS({
|
|
|
34978
35165
|
}
|
|
34979
35166
|
return false;
|
|
34980
35167
|
};
|
|
34981
|
-
micromatch2.every = (
|
|
34982
|
-
let items2 = [].concat(
|
|
35168
|
+
micromatch2.every = (list3, patterns, options) => {
|
|
35169
|
+
let items2 = [].concat(list3);
|
|
34983
35170
|
for (let pattern2 of [].concat(patterns)) {
|
|
34984
35171
|
let isMatch = picomatch(String(pattern2), options);
|
|
34985
35172
|
if (!items2.every((item) => isMatch(item))) {
|
|
@@ -38860,7 +39047,7 @@ function read(ctx, db, name) {
|
|
|
38860
39047
|
row: synced.row
|
|
38861
39048
|
};
|
|
38862
39049
|
}
|
|
38863
|
-
function
|
|
39050
|
+
function list2(ctx, db, opts = {}) {
|
|
38864
39051
|
void ctx;
|
|
38865
39052
|
const rows = db.memoryList({ ...opts, limit: opts.limit ?? 100 }).filter((r) => r.name);
|
|
38866
39053
|
return rows.sort((a, b) => Number(b.kind === "onboarding") - Number(a.kind === "onboarding"));
|
|
@@ -39286,6 +39473,7 @@ function formatSwarmList(config2, plan, active, opts = {}) {
|
|
|
39286
39473
|
const lines = [
|
|
39287
39474
|
`eminiar swarms \xB7 ${config2.rel} \xB7 sync ${config2.sync}${enforceNote(config2)} \xB7 agent files: ${fileSummary || "none"}`
|
|
39288
39475
|
];
|
|
39476
|
+
if (config2.ignoredKeys.length) lines.push(formatIssues(config2.rel, config2.ignoredKeys));
|
|
39289
39477
|
if (opts.swarm && !swarms.length)
|
|
39290
39478
|
lines.push(
|
|
39291
39479
|
`No swarm "${opts.swarm}"; ${config2.rel} defines: ${config2.swarms.map((s) => s.name).join(", ")}`
|
|
@@ -39344,6 +39532,11 @@ function formatSync(result, opts = {}) {
|
|
|
39344
39532
|
` ${SYNC_VERB[a.action].mark} ${word(a.action)} ${a.path}${a.reason ? `: ${a.reason}` : ""}`
|
|
39345
39533
|
);
|
|
39346
39534
|
}
|
|
39535
|
+
const held = result.actions.filter((a) => a.held).length;
|
|
39536
|
+
if (held)
|
|
39537
|
+
lines.push(
|
|
39538
|
+
`${held} update(s) held: the swarm file has keys this eminiar version does not know, so those agent files were not rewritten (an update that only tightens a file still applies). Update eminiar, or run \`eminiar swarm sync --force\`.`
|
|
39539
|
+
);
|
|
39347
39540
|
if (!opts.dryRun && result.actions.some((a) => a.action === "create"))
|
|
39348
39541
|
lines.push(
|
|
39349
39542
|
"Claude Code reads agent files when a session starts: if a new worker type is not available yet, open /agents or restart the session."
|
|
@@ -39871,8 +40064,8 @@ function groupBy(calls, keyFn) {
|
|
|
39871
40064
|
if (!isRealCall(c)) continue;
|
|
39872
40065
|
const k = keyFn(c);
|
|
39873
40066
|
if (k == null) continue;
|
|
39874
|
-
const
|
|
39875
|
-
if (
|
|
40067
|
+
const list3 = buckets.get(k);
|
|
40068
|
+
if (list3) list3.push(c);
|
|
39876
40069
|
else buckets.set(k, [c]);
|
|
39877
40070
|
}
|
|
39878
40071
|
return [...buckets.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, rows]) => ({ key, totals: totals(rows) }));
|
|
@@ -40573,18 +40766,18 @@ function threads(calls) {
|
|
|
40573
40766
|
const out = /* @__PURE__ */ new Map();
|
|
40574
40767
|
for (const c of calls) {
|
|
40575
40768
|
const key = `${c.session_id}\0${c.sidechain ? c.agent_id ?? "sidechain" : ""}`;
|
|
40576
|
-
const
|
|
40577
|
-
if (
|
|
40769
|
+
const list3 = out.get(key);
|
|
40770
|
+
if (list3) list3.push(c);
|
|
40578
40771
|
else out.set(key, [c]);
|
|
40579
40772
|
}
|
|
40580
|
-
for (const
|
|
40773
|
+
for (const list3 of out.values()) list3.sort((a, b) => a.ts - b.ts);
|
|
40581
40774
|
return out;
|
|
40582
40775
|
}
|
|
40583
40776
|
function groupBySession(rows) {
|
|
40584
40777
|
const out = /* @__PURE__ */ new Map();
|
|
40585
40778
|
for (const r of rows) {
|
|
40586
|
-
const
|
|
40587
|
-
if (
|
|
40779
|
+
const list3 = out.get(r.session_id);
|
|
40780
|
+
if (list3) list3.push(r);
|
|
40588
40781
|
else out.set(r.session_id, [r]);
|
|
40589
40782
|
}
|
|
40590
40783
|
return out;
|
|
@@ -40615,9 +40808,9 @@ function withScope(base, sessionIds) {
|
|
|
40615
40808
|
return out;
|
|
40616
40809
|
}
|
|
40617
40810
|
function hasCompactionBetween(ctx, sessionId, from, to) {
|
|
40618
|
-
const
|
|
40619
|
-
if (!
|
|
40620
|
-
return
|
|
40811
|
+
const list3 = ctx.compactionsBySession.get(sessionId);
|
|
40812
|
+
if (!list3) return false;
|
|
40813
|
+
return list3.some((t) => t > from && t <= to);
|
|
40621
40814
|
}
|
|
40622
40815
|
function detectCacheThrash(ctx) {
|
|
40623
40816
|
let runs = 0;
|
|
@@ -40625,7 +40818,7 @@ function detectCacheThrash(ctx) {
|
|
|
40625
40818
|
let rewritten = 0;
|
|
40626
40819
|
let savings = 0;
|
|
40627
40820
|
const sessions = /* @__PURE__ */ new Set();
|
|
40628
|
-
for (const
|
|
40821
|
+
for (const list3 of ctx.threads.values()) {
|
|
40629
40822
|
let run3 = [];
|
|
40630
40823
|
const flush = () => {
|
|
40631
40824
|
if (run3.length >= THRASH_RUN) {
|
|
@@ -40641,12 +40834,12 @@ function detectCacheThrash(ctx) {
|
|
|
40641
40834
|
}
|
|
40642
40835
|
run3 = [];
|
|
40643
40836
|
};
|
|
40644
|
-
for (let i = 1; i <
|
|
40645
|
-
const c =
|
|
40646
|
-
const prev =
|
|
40837
|
+
for (let i = 1; i < list3.length; i++) {
|
|
40838
|
+
const c = list3[i];
|
|
40839
|
+
const prev = list3[i - 1];
|
|
40647
40840
|
const ctxTokens = contextOf(c);
|
|
40648
40841
|
const heavy = ctxTokens > 0 && writesOf(c) / ctxTokens >= THRASH_WRITE_SHARE;
|
|
40649
|
-
const broken = hasCompactionBetween(ctx, c.session_id, prev.ts, c.ts) || c.ts - prev.ts > ttlFor(
|
|
40842
|
+
const broken = hasCompactionBetween(ctx, c.session_id, prev.ts, c.ts) || c.ts - prev.ts > ttlFor(list3);
|
|
40650
40843
|
if (!heavy || broken) {
|
|
40651
40844
|
flush();
|
|
40652
40845
|
continue;
|
|
@@ -40669,10 +40862,10 @@ function detectCacheThrash(ctx) {
|
|
|
40669
40862
|
sessions
|
|
40670
40863
|
);
|
|
40671
40864
|
}
|
|
40672
|
-
function ttlFor(
|
|
40865
|
+
function ttlFor(list3) {
|
|
40673
40866
|
let w5 = 0;
|
|
40674
40867
|
let w1 = 0;
|
|
40675
|
-
for (const c of
|
|
40868
|
+
for (const c of list3) {
|
|
40676
40869
|
w5 += num3(c.cache_create_5m);
|
|
40677
40870
|
w1 += num3(c.cache_create_1h);
|
|
40678
40871
|
}
|
|
@@ -40684,11 +40877,11 @@ function detectCacheCold(ctx) {
|
|
|
40684
40877
|
let savings = 0;
|
|
40685
40878
|
let longestGap = 0;
|
|
40686
40879
|
const sessions = /* @__PURE__ */ new Set();
|
|
40687
|
-
for (const
|
|
40688
|
-
const ttl = ttlFor(
|
|
40689
|
-
for (let i = 1; i <
|
|
40690
|
-
const c =
|
|
40691
|
-
const prev =
|
|
40880
|
+
for (const list3 of ctx.threads.values()) {
|
|
40881
|
+
const ttl = ttlFor(list3);
|
|
40882
|
+
for (let i = 1; i < list3.length; i++) {
|
|
40883
|
+
const c = list3[i];
|
|
40884
|
+
const prev = list3[i - 1];
|
|
40692
40885
|
const gap = c.ts - prev.ts;
|
|
40693
40886
|
if (gap <= ttl) continue;
|
|
40694
40887
|
if (hasCompactionBetween(ctx, c.session_id, prev.ts, c.ts)) continue;
|
|
@@ -40950,15 +41143,15 @@ function detectErrorLoop(ctx) {
|
|
|
40950
41143
|
const byThread = /* @__PURE__ */ new Map();
|
|
40951
41144
|
for (const u of ctx.toolUses) {
|
|
40952
41145
|
const key = `${u.session_id}\0${u.agent_id ?? ""}`;
|
|
40953
|
-
const
|
|
40954
|
-
if (
|
|
41146
|
+
const list3 = byThread.get(key);
|
|
41147
|
+
if (list3) list3.push(u);
|
|
40955
41148
|
else byThread.set(key, [u]);
|
|
40956
41149
|
}
|
|
40957
|
-
for (const
|
|
40958
|
-
|
|
41150
|
+
for (const list3 of byThread.values()) {
|
|
41151
|
+
list3.sort((a, b) => a.ts - b.ts);
|
|
40959
41152
|
let run3 = 0;
|
|
40960
41153
|
let tool = "";
|
|
40961
|
-
for (const u of
|
|
41154
|
+
for (const u of list3) {
|
|
40962
41155
|
if (u.is_error && u.tool === tool) run3 += 1;
|
|
40963
41156
|
else {
|
|
40964
41157
|
run3 = u.is_error ? 1 : 0;
|
|
@@ -41192,11 +41385,11 @@ function detectInsights(input2) {
|
|
|
41192
41385
|
const calls = input2.calls.filter(isRealCall);
|
|
41193
41386
|
const compactionsBySession = /* @__PURE__ */ new Map();
|
|
41194
41387
|
for (const e of input2.contextEvents) {
|
|
41195
|
-
const
|
|
41196
|
-
if (
|
|
41388
|
+
const list3 = compactionsBySession.get(e.session_id);
|
|
41389
|
+
if (list3) list3.push(e.ts);
|
|
41197
41390
|
else compactionsBySession.set(e.session_id, [e.ts]);
|
|
41198
41391
|
}
|
|
41199
|
-
for (const
|
|
41392
|
+
for (const list3 of compactionsBySession.values()) list3.sort((a, b) => a - b);
|
|
41200
41393
|
const callTs = /* @__PURE__ */ new Map();
|
|
41201
41394
|
for (const [sid, rows] of groupBySession(calls))
|
|
41202
41395
|
callTs.set(
|
|
@@ -41450,8 +41643,8 @@ function periods(calls, keyFn) {
|
|
|
41450
41643
|
const buckets = /* @__PURE__ */ new Map();
|
|
41451
41644
|
for (const c of calls) {
|
|
41452
41645
|
const k = keyFn(c.ts);
|
|
41453
|
-
const
|
|
41454
|
-
if (
|
|
41646
|
+
const list3 = buckets.get(k);
|
|
41647
|
+
if (list3) list3.push(c);
|
|
41455
41648
|
else buckets.set(k, [c]);
|
|
41456
41649
|
}
|
|
41457
41650
|
return [...buckets.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, rows]) => ({ key, totals: totals(rows), models: modelSlices(rows) }));
|
|
@@ -41481,8 +41674,8 @@ function insightsFor(ctx, data) {
|
|
|
41481
41674
|
const r = detectInsights(input2);
|
|
41482
41675
|
return { insights: r.insights, scores: r.scores };
|
|
41483
41676
|
}
|
|
41484
|
-
function sortInsights(
|
|
41485
|
-
return
|
|
41677
|
+
function sortInsights(list3) {
|
|
41678
|
+
return list3.slice().sort(
|
|
41486
41679
|
(a, b) => SEVERITY_RANK2[a.severity] - SEVERITY_RANK2[b.severity] || (b.estimatedSavingsUsd ?? 0) - (a.estimatedSavingsUsd ?? 0)
|
|
41487
41680
|
);
|
|
41488
41681
|
}
|
|
@@ -42576,11 +42769,11 @@ import { readFile } from "fs/promises";
|
|
|
42576
42769
|
import { basename as basename5, extname as extname2, resolve as resolvePath } from "path";
|
|
42577
42770
|
import { pathToFileURL } from "url";
|
|
42578
42771
|
function parseFixture(raw, source = "fixture") {
|
|
42579
|
-
const
|
|
42580
|
-
if (!Array.isArray(
|
|
42772
|
+
const list3 = Array.isArray(raw) || !raw || typeof raw !== "object" ? raw : raw.items;
|
|
42773
|
+
if (!Array.isArray(list3))
|
|
42581
42774
|
throw new EvalFixtureError(`${source}: expected an array of items or {"items": [...]}`);
|
|
42582
|
-
if (!
|
|
42583
|
-
return
|
|
42775
|
+
if (!list3.length) throw new EvalFixtureError(`${source}: the fixture has no items`);
|
|
42776
|
+
return list3.map((it, i) => {
|
|
42584
42777
|
const r = ItemSchema.safeParse(it);
|
|
42585
42778
|
if (!r.success) {
|
|
42586
42779
|
const issue2 = r.error.issues[0];
|
|
@@ -43473,10 +43666,10 @@ function personalConsent() {
|
|
|
43473
43666
|
try {
|
|
43474
43667
|
const a = readRaw(paths().configFile).adjudicator;
|
|
43475
43668
|
if (!isObj2(a)) return { remoteConsent: false };
|
|
43476
|
-
const
|
|
43669
|
+
const list3 = a.remoteConsentOrigins;
|
|
43477
43670
|
return {
|
|
43478
43671
|
remoteConsent: a.remoteConsent === true,
|
|
43479
|
-
...Array.isArray(
|
|
43672
|
+
...Array.isArray(list3) ? { remoteConsentOrigins: list3.filter((s) => typeof s === "string") } : {}
|
|
43480
43673
|
};
|
|
43481
43674
|
} catch {
|
|
43482
43675
|
return { remoteConsent: false };
|
|
@@ -43490,8 +43683,8 @@ function mustAsk(r, previous) {
|
|
|
43490
43683
|
function consentPatch(r, asked) {
|
|
43491
43684
|
if (!r.configuredRemote || !r.origin) return {};
|
|
43492
43685
|
if (!asked && r.consentVia !== "legacy") return {};
|
|
43493
|
-
const
|
|
43494
|
-
return { remoteConsent: true, remoteConsentOrigins:
|
|
43686
|
+
const list3 = withConsentedOrigin(personalConsent(), r.origin);
|
|
43687
|
+
return { remoteConsent: true, remoteConsentOrigins: list3 };
|
|
43495
43688
|
}
|
|
43496
43689
|
function personalOrigin(root) {
|
|
43497
43690
|
try {
|
|
@@ -45439,8 +45632,8 @@ function registerSettings(stable) {
|
|
|
45439
45632
|
const hooks = settings.hooks ?? {};
|
|
45440
45633
|
const hookCmd = `"${join21(stable, "bin", "em-hook")}"`;
|
|
45441
45634
|
for (const ev3 of HOOK_EVENTS) {
|
|
45442
|
-
const
|
|
45443
|
-
const filtered =
|
|
45635
|
+
const list3 = hooks[ev3] ?? [];
|
|
45636
|
+
const filtered = list3.filter(
|
|
45444
45637
|
(entry2) => !(entry2.hooks ?? []).some((h) => isOurs(h.command, stable))
|
|
45445
45638
|
);
|
|
45446
45639
|
const entry = {
|
|
@@ -45480,9 +45673,9 @@ function unregisterSettings(stable, wrote) {
|
|
|
45480
45673
|
const settings = readJson2(settingsPath());
|
|
45481
45674
|
const hooks = settings.hooks ?? {};
|
|
45482
45675
|
for (const ev3 of wrote.hookEvents) {
|
|
45483
|
-
const
|
|
45484
|
-
if (!
|
|
45485
|
-
const kept =
|
|
45676
|
+
const list3 = hooks[ev3];
|
|
45677
|
+
if (!list3) continue;
|
|
45678
|
+
const kept = list3.filter(
|
|
45486
45679
|
(entry) => !(entry.hooks ?? []).some((h) => isOurs(h.command, stable))
|
|
45487
45680
|
);
|
|
45488
45681
|
if (kept.length) hooks[ev3] = kept;
|
|
@@ -45574,13 +45767,13 @@ function registerCursor(stable) {
|
|
|
45574
45767
|
const hooks = cfg.hooks ?? {};
|
|
45575
45768
|
const command = cursorHookCommand(stable);
|
|
45576
45769
|
for (const ev3 of CURSOR_HOOK_EVENTS) {
|
|
45577
|
-
const
|
|
45770
|
+
const list3 = (Array.isArray(hooks[ev3]) ? hooks[ev3] : []).filter(
|
|
45578
45771
|
(h) => !isOurs(h.command, stable)
|
|
45579
45772
|
);
|
|
45580
45773
|
const entry = { command, timeout: TIMEOUTS[ev3] ?? 5 };
|
|
45581
45774
|
if (ev3 === "preToolUse") entry.matcher = CURSOR_PRE_TOOL_MATCHER;
|
|
45582
|
-
|
|
45583
|
-
hooks[ev3] =
|
|
45775
|
+
list3.push(entry);
|
|
45776
|
+
hooks[ev3] = list3;
|
|
45584
45777
|
}
|
|
45585
45778
|
cfg.hooks = hooks;
|
|
45586
45779
|
writeJsonWithBackup(cursorHooksPath(), cfg);
|
|
@@ -46439,8 +46632,8 @@ function findContextMode() {
|
|
|
46439
46632
|
const settings = readJson2(settingsPath());
|
|
46440
46633
|
const hooks = settings.hooks ?? {};
|
|
46441
46634
|
const hookEntries = [];
|
|
46442
|
-
for (const [event,
|
|
46443
|
-
for (const entry of
|
|
46635
|
+
for (const [event, list3] of Object.entries(hooks)) {
|
|
46636
|
+
for (const entry of list3) {
|
|
46444
46637
|
for (const h of entry.hooks ?? []) {
|
|
46445
46638
|
if (typeof h.command === "string" && CM_HOOK.test(h.command))
|
|
46446
46639
|
hookEntries.push({ event, command: h.command });
|
|
@@ -46485,8 +46678,8 @@ async function replaceContextMode(opts) {
|
|
|
46485
46678
|
if (f.hookEntries.length) {
|
|
46486
46679
|
const settings = readJson2(settingsPath());
|
|
46487
46680
|
const hooks = settings.hooks ?? {};
|
|
46488
|
-
for (const [event,
|
|
46489
|
-
const kept =
|
|
46681
|
+
for (const [event, list3] of Object.entries(hooks)) {
|
|
46682
|
+
const kept = list3.map((entry) => ({
|
|
46490
46683
|
...entry,
|
|
46491
46684
|
hooks: (entry.hooks ?? []).filter(
|
|
46492
46685
|
(h) => !(typeof h.command === "string" && CM_HOOK.test(h.command))
|
|
@@ -46752,10 +46945,10 @@ function loadPermissionRules(root, extraDeny = []) {
|
|
|
46752
46945
|
const hit = cache4.get(key);
|
|
46753
46946
|
if (hit?.stamps.every((s, i) => s === stamps[i])) return hit.rules;
|
|
46754
46947
|
const out = { allow: [], deny: [], ask: [], root };
|
|
46755
|
-
const push = (
|
|
46948
|
+
const push = (list3, raws) => {
|
|
46756
46949
|
for (const raw of raws ?? []) {
|
|
46757
46950
|
const r = parseRule(raw);
|
|
46758
|
-
if (r)
|
|
46951
|
+
if (r) list3.push(r);
|
|
46759
46952
|
}
|
|
46760
46953
|
};
|
|
46761
46954
|
for (const f of files) {
|
|
@@ -47080,57 +47273,6 @@ var init_snippets = __esm({
|
|
|
47080
47273
|
}
|
|
47081
47274
|
});
|
|
47082
47275
|
|
|
47083
|
-
// src/search/typo.ts
|
|
47084
|
-
function editDistance(a, b, max = 3) {
|
|
47085
|
-
if (Math.abs(a.length - b.length) > max) return max + 1;
|
|
47086
|
-
const prev2 = [];
|
|
47087
|
-
let prev = Array.from({ length: b.length + 1 }, (_, j) => j);
|
|
47088
|
-
let cur = new Array(b.length + 1).fill(0);
|
|
47089
|
-
for (let i = 1; i <= a.length; i++) {
|
|
47090
|
-
cur[0] = i;
|
|
47091
|
-
let rowMin = cur[0];
|
|
47092
|
-
for (let j = 1; j <= b.length; j++) {
|
|
47093
|
-
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
47094
|
-
let v = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + cost);
|
|
47095
|
-
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
47096
|
-
v = Math.min(v, prev2[j - 2] + 1);
|
|
47097
|
-
}
|
|
47098
|
-
cur[j] = v;
|
|
47099
|
-
if (v < rowMin) rowMin = v;
|
|
47100
|
-
}
|
|
47101
|
-
if (rowMin > max) return max + 1;
|
|
47102
|
-
prev2.splice(0, prev2.length, ...prev);
|
|
47103
|
-
[prev, cur] = [cur, prev];
|
|
47104
|
-
}
|
|
47105
|
-
return prev[b.length];
|
|
47106
|
-
}
|
|
47107
|
-
function correctTerms(db, terms) {
|
|
47108
|
-
const corrections = [];
|
|
47109
|
-
const out = terms.map((term) => {
|
|
47110
|
-
if (term.length < 4 || /[^a-z0-9]/.test(term) || db.termExists(term)) return term;
|
|
47111
|
-
const max = term.length >= 7 ? 2 : 1;
|
|
47112
|
-
const candidates2 = db.vocabCandidates(term[0], 3e3);
|
|
47113
|
-
let best;
|
|
47114
|
-
for (const c of candidates2) {
|
|
47115
|
-
if (c.term.length < 3) continue;
|
|
47116
|
-
const d = editDistance(term, c.term, max);
|
|
47117
|
-
if (d > max) continue;
|
|
47118
|
-
if (!best || d < best.d || d === best.d && c.df > best.df)
|
|
47119
|
-
best = { term: c.term, d, df: c.df };
|
|
47120
|
-
}
|
|
47121
|
-
if (!best) return term;
|
|
47122
|
-
corrections.push({ from: term, to: best.term });
|
|
47123
|
-
return `${best.term}*`;
|
|
47124
|
-
});
|
|
47125
|
-
return { terms: out, corrections };
|
|
47126
|
-
}
|
|
47127
|
-
var init_typo = __esm({
|
|
47128
|
-
"src/search/typo.ts"() {
|
|
47129
|
-
"use strict";
|
|
47130
|
-
init_esm_shims();
|
|
47131
|
-
}
|
|
47132
|
-
});
|
|
47133
|
-
|
|
47134
47276
|
// src/search/pipeline.ts
|
|
47135
47277
|
var pipeline_exports = {};
|
|
47136
47278
|
__export(pipeline_exports, {
|
|
@@ -47405,19 +47547,19 @@ function mergedCatalog(extra) {
|
|
|
47405
47547
|
function catalogLookup(kind, key, catalog = CATALOG) {
|
|
47406
47548
|
const k = key.trim();
|
|
47407
47549
|
for (const e of catalog) {
|
|
47408
|
-
const
|
|
47409
|
-
if (!
|
|
47550
|
+
const list3 = kind === "api" ? e.hosts : e[kind];
|
|
47551
|
+
if (!list3) continue;
|
|
47410
47552
|
if (kind === "env") {
|
|
47411
|
-
if (
|
|
47553
|
+
if (list3.some((p2) => envMatches(p2, k))) return e;
|
|
47412
47554
|
} else if (kind === "api") {
|
|
47413
47555
|
const host = k.toLowerCase();
|
|
47414
|
-
if (
|
|
47556
|
+
if (list3.some((h) => host === h || host.endsWith(`.${h}`))) return e;
|
|
47415
47557
|
} else if (kind === "image") {
|
|
47416
47558
|
const bare = k.split(":")[0].replace(/^docker\.io\/(library\/)?/, "");
|
|
47417
|
-
if (
|
|
47559
|
+
if (list3.some((p2) => matches(p2, bare))) return e;
|
|
47418
47560
|
} else if (kind === "go") {
|
|
47419
|
-
if (
|
|
47420
|
-
} else if (
|
|
47561
|
+
if (list3.some((p2) => k === p2 || k.startsWith(p2))) return e;
|
|
47562
|
+
} else if (list3.some((p2) => matches(p2, k))) return e;
|
|
47421
47563
|
}
|
|
47422
47564
|
return void 0;
|
|
47423
47565
|
}
|
|
@@ -48827,9 +48969,9 @@ function schemaSummary(doc, schema, depth = 0) {
|
|
|
48827
48969
|
if (Array.isArray(s.enum))
|
|
48828
48970
|
return `enum(${s.enum.slice(0, 8).map(String).join(", ")}${s.enum.length > 8 ? ", \u2026" : ""})`;
|
|
48829
48971
|
for (const k of ["oneOf", "anyOf", "allOf"]) {
|
|
48830
|
-
const
|
|
48831
|
-
if (Array.isArray(
|
|
48832
|
-
return `${k}<${
|
|
48972
|
+
const list3 = s[k];
|
|
48973
|
+
if (Array.isArray(list3))
|
|
48974
|
+
return `${k}<${list3.slice(0, 4).map((x) => schemaSummary(doc, x, depth + 1)).join(" | ")}>`;
|
|
48833
48975
|
}
|
|
48834
48976
|
if (type === "array" || s.items) return `${schemaSummary(doc, s.items, depth + 1) || "any"}[]`;
|
|
48835
48977
|
if (type === "object" || isObj3(s.properties)) {
|
|
@@ -48991,9 +49133,9 @@ function postmanBody(body) {
|
|
|
48991
49133
|
const lang = isObj3(body.options) && isObj3(body.options.raw) ? String(body.options.raw.language ?? "json") : "json";
|
|
48992
49134
|
return raw.length > 2e3 ? [`Body (${lang}): ${raw.slice(0, 2e3)}\u2026`] : ["Body:", "", `\`\`\`${lang}`, raw, "```"];
|
|
48993
49135
|
}
|
|
48994
|
-
const
|
|
48995
|
-
if (Array.isArray(
|
|
48996
|
-
const keys =
|
|
49136
|
+
const list3 = body[mode];
|
|
49137
|
+
if (Array.isArray(list3)) {
|
|
49138
|
+
const keys = list3.filter(isObj3).map(
|
|
48997
49139
|
(e) => `${String(e.key)}${e.type && e.type !== "text" ? ` (${String(e.type)})` : ""}${e.description ? ` \u2014 ${clip5(e.description, 100)}` : ""}`
|
|
48998
49140
|
);
|
|
48999
49141
|
return keys.length ? [`Body (${mode}): ${keys.join(", ")}`] : [];
|
|
@@ -49584,9 +49726,9 @@ function computeMetrics(db) {
|
|
|
49584
49726
|
for (const s of symbols) {
|
|
49585
49727
|
const f = s.path ? `file:${s.path}` : void 0;
|
|
49586
49728
|
if (!f) continue;
|
|
49587
|
-
const
|
|
49588
|
-
|
|
49589
|
-
symbolsByFile.set(f,
|
|
49729
|
+
const list3 = symbolsByFile.get(f) ?? [];
|
|
49730
|
+
list3.push(s);
|
|
49731
|
+
symbolsByFile.set(f, list3);
|
|
49590
49732
|
}
|
|
49591
49733
|
for (const f of files) {
|
|
49592
49734
|
const m = meta3(f);
|
|
@@ -49639,9 +49781,9 @@ function computeMetrics(db) {
|
|
|
49639
49781
|
const members2 = /* @__PURE__ */ new Map();
|
|
49640
49782
|
for (const r of fileRows) {
|
|
49641
49783
|
if (r.cluster === null) continue;
|
|
49642
|
-
const
|
|
49643
|
-
|
|
49644
|
-
members2.set(r.cluster,
|
|
49784
|
+
const list3 = members2.get(r.cluster) ?? [];
|
|
49785
|
+
list3.push(r);
|
|
49786
|
+
members2.set(r.cluster, list3);
|
|
49645
49787
|
}
|
|
49646
49788
|
const links = /* @__PURE__ */ new Map();
|
|
49647
49789
|
for (const e of importEdges) {
|
|
@@ -49800,10 +49942,10 @@ function impact(db, ref, opts = {}) {
|
|
|
49800
49942
|
add3(e.dst, e.weight, 1, `co-changed ${meta4.count ?? "?"}\xD7 (${Math.round(e.weight * 100)}%)`);
|
|
49801
49943
|
}
|
|
49802
49944
|
}
|
|
49803
|
-
const
|
|
49804
|
-
const nodes = new Map(db.graphGetNodes(
|
|
49805
|
-
for (const h of
|
|
49806
|
-
return { root, hits:
|
|
49945
|
+
const list3 = [...hits.values()].sort((a, b) => b.score - a.score);
|
|
49946
|
+
const nodes = new Map(db.graphGetNodes(list3.map((h) => h.id)).map((n) => [n.id, n]));
|
|
49947
|
+
for (const h of list3) h.node = nodes.get(h.id);
|
|
49948
|
+
return { root, hits: list3 };
|
|
49807
49949
|
}
|
|
49808
49950
|
function dependencies(db, ref, depth = 1) {
|
|
49809
49951
|
const root = resolveNode(db, ref);
|
|
@@ -49830,10 +49972,10 @@ function dependencies(db, ref, depth = 1) {
|
|
|
49830
49972
|
frontier = next;
|
|
49831
49973
|
if (!frontier.length) break;
|
|
49832
49974
|
}
|
|
49833
|
-
const
|
|
49834
|
-
const nodes = new Map(db.graphGetNodes(
|
|
49835
|
-
for (const h of
|
|
49836
|
-
return { root, hits:
|
|
49975
|
+
const list3 = [...hits.values()].sort((a, b) => b.score - a.score);
|
|
49976
|
+
const nodes = new Map(db.graphGetNodes(list3.map((h) => h.id)).map((n) => [n.id, n]));
|
|
49977
|
+
for (const h of list3) h.node = nodes.get(h.id);
|
|
49978
|
+
return { root, hits: list3 };
|
|
49837
49979
|
}
|
|
49838
49980
|
function neighbors(db, ref, depth = 1, kinds) {
|
|
49839
49981
|
const root = resolveNode(db, ref);
|
|
@@ -50334,8 +50476,8 @@ function parseRouteAnnotations(doc) {
|
|
|
50334
50476
|
const body = m[1] ?? "";
|
|
50335
50477
|
const path3 = /^\s*"([^"]*)"/.exec(body)?.[1] ?? /\bpath\s*=\s*"([^"]*)"/.exec(body)?.[1];
|
|
50336
50478
|
if (path3 === void 0) continue;
|
|
50337
|
-
const
|
|
50338
|
-
const methods = [...
|
|
50479
|
+
const list3 = /\bmethods\s*=\s*(\{[^}]*\}|"[^"]*")/.exec(body)?.[1] ?? "";
|
|
50480
|
+
const methods = [...list3.matchAll(/"([^"]+)"/g)].map((x) => httpMethod(x[1])).filter((x) => !!x);
|
|
50339
50481
|
for (const method of methods.length ? methods : ["ALL"]) out.push({ method, path: path3 });
|
|
50340
50482
|
}
|
|
50341
50483
|
return out;
|
|
@@ -51136,16 +51278,16 @@ function phpString(n) {
|
|
|
51136
51278
|
return literalText(n)?.replace(/\\(\\|')/g, "$1");
|
|
51137
51279
|
}
|
|
51138
51280
|
function argsOf(call) {
|
|
51139
|
-
const
|
|
51140
|
-
return (
|
|
51281
|
+
const list3 = call.childForFieldName("arguments") ?? call.childForFieldName("parameters");
|
|
51282
|
+
return (list3?.namedChildren ?? []).filter((a) => a?.type === "argument").map((a) => a.namedChildren[a.namedChildren.length - 1]).filter((a) => !!a);
|
|
51141
51283
|
}
|
|
51142
51284
|
function positionalArgs(call) {
|
|
51143
|
-
const
|
|
51144
|
-
return (
|
|
51285
|
+
const list3 = call.childForFieldName("arguments") ?? call.childForFieldName("parameters");
|
|
51286
|
+
return (list3?.namedChildren ?? []).filter((a) => a?.type === "argument" && !a.childForFieldName("name")).map((a) => a.namedChildren[0]).filter((a) => !!a);
|
|
51145
51287
|
}
|
|
51146
51288
|
function namedArg(call, name) {
|
|
51147
|
-
const
|
|
51148
|
-
for (const a of
|
|
51289
|
+
const list3 = call.childForFieldName("arguments") ?? call.childForFieldName("parameters");
|
|
51290
|
+
for (const a of list3?.namedChildren ?? []) {
|
|
51149
51291
|
if (a?.type === "argument" && a.childForFieldName("name")?.text === name)
|
|
51150
51292
|
return a.namedChildren[a.namedChildren.length - 1] ?? void 0;
|
|
51151
51293
|
}
|
|
@@ -54479,21 +54621,21 @@ function detectChanges(db, root, opts = {}) {
|
|
|
54479
54621
|
}
|
|
54480
54622
|
const byFile = /* @__PURE__ */ new Map();
|
|
54481
54623
|
for (const h of hunks) {
|
|
54482
|
-
const
|
|
54483
|
-
|
|
54484
|
-
byFile.set(h.path,
|
|
54624
|
+
const list3 = byFile.get(h.path) ?? [];
|
|
54625
|
+
list3.push(h);
|
|
54626
|
+
byFile.set(h.path, list3);
|
|
54485
54627
|
}
|
|
54486
54628
|
const symbols = /* @__PURE__ */ new Map();
|
|
54487
54629
|
const files = [];
|
|
54488
54630
|
const unindexed = [];
|
|
54489
|
-
for (const [path3,
|
|
54631
|
+
for (const [path3, list3] of byFile) {
|
|
54490
54632
|
const indexed = !!db.graphGetNode(fileId(path3));
|
|
54491
|
-
files.push({ path: path3, hunks:
|
|
54633
|
+
files.push({ path: path3, hunks: list3.length, indexed });
|
|
54492
54634
|
if (!indexed) {
|
|
54493
54635
|
unindexed.push(path3);
|
|
54494
54636
|
continue;
|
|
54495
54637
|
}
|
|
54496
|
-
for (const [id, s] of symbolsAt(db, path3,
|
|
54638
|
+
for (const [id, s] of symbolsAt(db, path3, list3)) symbols.set(id, s);
|
|
54497
54639
|
}
|
|
54498
54640
|
const ids = [...symbols.keys()];
|
|
54499
54641
|
const metrics = new Map(db.metricsGet(ids).map((m) => [m.node_id, m]));
|
|
@@ -54733,7 +54875,7 @@ function architecture(ctx, db, aspects = ASPECTS) {
|
|
|
54733
54875
|
hotspots: want.has("hotspots") ? hotspots(db, 12) : [],
|
|
54734
54876
|
clusters: want.has("clusters") ? readClusters(db) : [],
|
|
54735
54877
|
cycles: want.has("cycles") ? readCycles(db) : [],
|
|
54736
|
-
decisions: want.has("decisions") ?
|
|
54878
|
+
decisions: want.has("decisions") ? list2(ctx, db, { kind: "decision", limit: 50 }).filter((r) => (r.status ?? "accepted") === "accepted").map((r) => ({
|
|
54737
54879
|
name: r.name ?? "",
|
|
54738
54880
|
title: r.content.split("\n")[0]?.replace(/^#+\s*/, "").slice(0, 120) ?? "",
|
|
54739
54881
|
status: r.status ?? "accepted",
|
|
@@ -55111,9 +55253,9 @@ function envSignals(dir, project, catalog) {
|
|
|
55111
55253
|
}
|
|
55112
55254
|
const token = name.split("_")[0];
|
|
55113
55255
|
if (token.length < 3 || GENERIC_ENV.has(token)) continue;
|
|
55114
|
-
const
|
|
55115
|
-
if (!
|
|
55116
|
-
unknownPrefixes.set(token,
|
|
55256
|
+
const list3 = unknownPrefixes.get(token) ?? [];
|
|
55257
|
+
if (!list3.includes(name)) list3.push(name);
|
|
55258
|
+
unknownPrefixes.set(token, list3);
|
|
55117
55259
|
}
|
|
55118
55260
|
}
|
|
55119
55261
|
return { signals, unknownPrefixes };
|
|
@@ -55438,15 +55580,15 @@ function discoverDocs(ctx, opts = {}) {
|
|
|
55438
55580
|
);
|
|
55439
55581
|
for (const hit of api.hits.values()) {
|
|
55440
55582
|
if (inSubproject(hit.samples)) continue;
|
|
55441
|
-
const
|
|
55442
|
-
|
|
55443
|
-
apiHits.set(hit.host,
|
|
55583
|
+
const list3 = apiHits.get(hit.host) ?? [];
|
|
55584
|
+
list3.push(hit);
|
|
55585
|
+
apiHits.set(hit.host, list3);
|
|
55444
55586
|
}
|
|
55445
55587
|
for (const link of api.docLinks.values()) {
|
|
55446
55588
|
if (inSubproject(link.samples)) continue;
|
|
55447
|
-
const
|
|
55448
|
-
|
|
55449
|
-
docLinks.set(link.host,
|
|
55589
|
+
const list3 = docLinks.get(link.host) ?? [];
|
|
55590
|
+
list3.push(link);
|
|
55591
|
+
docLinks.set(link.host, list3);
|
|
55450
55592
|
}
|
|
55451
55593
|
const env = envSignals(dir, project, catalog);
|
|
55452
55594
|
signals.push(...env.signals);
|
|
@@ -55536,12 +55678,12 @@ function discoverDocs(ctx, opts = {}) {
|
|
|
55536
55678
|
evidence: `${info.vars.slice(0, 4).join(", ")}${info.vars.length > 4 ? ", \u2026" : ""}`
|
|
55537
55679
|
});
|
|
55538
55680
|
}
|
|
55539
|
-
for (const [host,
|
|
55540
|
-
const calls =
|
|
55681
|
+
for (const [host, list3] of apiHits) {
|
|
55682
|
+
const calls = list3.reduce((n, h) => n + h.calls, 0);
|
|
55541
55683
|
if (!calls) continue;
|
|
55542
55684
|
const entry = catalogLookup("api", host, catalog);
|
|
55543
|
-
const specUrls = [...new Set(
|
|
55544
|
-
for (const h of
|
|
55685
|
+
const specUrls = [...new Set(list3.flatMap((h) => h.specUrls))];
|
|
55686
|
+
for (const h of list3) {
|
|
55545
55687
|
if (!h.calls) continue;
|
|
55546
55688
|
const evidence = `api:${host} (${h.samples.slice(0, 2).join(", ")})${specUrls.length ? ` \xB7 spec ${specUrls[0]}` : ""}`;
|
|
55547
55689
|
if (entry) {
|
|
@@ -55574,10 +55716,10 @@ function discoverDocs(ctx, opts = {}) {
|
|
|
55574
55716
|
}
|
|
55575
55717
|
}
|
|
55576
55718
|
}
|
|
55577
|
-
for (const [host,
|
|
55578
|
-
const urls = [...new Set(
|
|
55719
|
+
for (const [host, list3] of docLinks) {
|
|
55720
|
+
const urls = [...new Set(list3.flatMap((l) => l.urls))].slice(0, 3);
|
|
55579
55721
|
const entry = catalogLookup("api", host, catalog);
|
|
55580
|
-
for (const l of
|
|
55722
|
+
for (const l of list3) {
|
|
55581
55723
|
const evidence = `link:${host} (${l.samples.slice(0, 2).join(", ")})`;
|
|
55582
55724
|
if (entry) {
|
|
55583
55725
|
add3({
|
|
@@ -56025,7 +56167,7 @@ function rootOf(host) {
|
|
|
56025
56167
|
function docGuesses(host) {
|
|
56026
56168
|
const h = host.toLowerCase();
|
|
56027
56169
|
const root = rootOf(h);
|
|
56028
|
-
const
|
|
56170
|
+
const list3 = [
|
|
56029
56171
|
`https://docs.${root}/`,
|
|
56030
56172
|
`https://developer.${root}/`,
|
|
56031
56173
|
`https://developers.${root}/`,
|
|
@@ -56043,7 +56185,7 @@ function docGuesses(host) {
|
|
|
56043
56185
|
`https://${h}/openapi.json`,
|
|
56044
56186
|
`https://${h}/swagger.json`
|
|
56045
56187
|
];
|
|
56046
|
-
return [...new Set(
|
|
56188
|
+
return [...new Set(list3)];
|
|
56047
56189
|
}
|
|
56048
56190
|
async function probe2(url2, opts) {
|
|
56049
56191
|
const f = opts.fetchImpl ?? fetch;
|
|
@@ -56470,16 +56612,16 @@ function formatDiscovery(d, max = 40) {
|
|
|
56470
56612
|
]
|
|
56471
56613
|
];
|
|
56472
56614
|
for (const [conf, title, note, wants] of groups) {
|
|
56473
|
-
const
|
|
56474
|
-
if (!
|
|
56475
|
-
lines.push("", `${title} (${
|
|
56476
|
-
for (const p2 of
|
|
56615
|
+
const list3 = d.providers.filter(wants);
|
|
56616
|
+
if (!list3.length) continue;
|
|
56617
|
+
lines.push("", `${title} (${list3.length}; ${note}):`);
|
|
56618
|
+
for (const p2 of list3.slice(0, max)) {
|
|
56477
56619
|
const used = p2.usedBy.length > 1 ? ` \xB7 used by ${p2.usedBy.length} projects` : p2.usedBy[0] && p2.usedBy[0] !== "." ? ` \xB7 ${p2.usedBy[0]}` : "";
|
|
56478
56620
|
const where = p2.urls[0] ? ` \xB7 ${p2.urls[0]}` : "";
|
|
56479
56621
|
const ev3 = conf === "probe" || conf === "unknown" ? ` \xB7 ${p2.evidence[0]}` : "";
|
|
56480
56622
|
lines.push(`- ${p2.name} \u2190 ${p2.provider}${used}${where}${ev3}${reg(p2.registered)}`);
|
|
56481
56623
|
}
|
|
56482
|
-
if (
|
|
56624
|
+
if (list3.length > max) lines.push(` \u2026 ${list3.length - max} more`);
|
|
56483
56625
|
}
|
|
56484
56626
|
const rec = d.local.filter((c) => !c.registered).length + d.providers.filter(
|
|
56485
56627
|
(p2) => !p2.registered && (p2.confidence === "probe" || p2.confidence === "catalog" && (p2.tier ?? "library") === "service")
|
|
@@ -58599,7 +58741,7 @@ var init_em_memory = __esm({
|
|
|
58599
58741
|
return text(`${args.name} is now ${args.status}`);
|
|
58600
58742
|
}
|
|
58601
58743
|
case "list": {
|
|
58602
|
-
const rows =
|
|
58744
|
+
const rows = list2(ctx, db, {
|
|
58603
58745
|
topic: args.topic,
|
|
58604
58746
|
kind: args.kind,
|
|
58605
58747
|
status: args.status,
|
|
@@ -58697,7 +58839,7 @@ var init_em_recall = __esm({
|
|
|
58697
58839
|
const limit = args.limit ?? 8;
|
|
58698
58840
|
const lines = [];
|
|
58699
58841
|
if (!args.query) {
|
|
58700
|
-
const rows =
|
|
58842
|
+
const rows = list2(ctx, db, { kind: args.kind, topic: args.topic, limit });
|
|
58701
58843
|
if (!rows.length)
|
|
58702
58844
|
return text(
|
|
58703
58845
|
"no memories yet; use em_remember to record decisions and constraints (or /eminiar:em-onboard to write the onboarding set)"
|
|
@@ -60499,7 +60641,7 @@ async function searchPayload(ctx, q, mode, limit, source) {
|
|
|
60499
60641
|
function memoriesPayload(ctx, opts = {}) {
|
|
60500
60642
|
const db = getStorage(ctx);
|
|
60501
60643
|
const summary = reconcile2(ctx, db);
|
|
60502
|
-
const rows =
|
|
60644
|
+
const rows = list2(ctx, db, {
|
|
60503
60645
|
kind: opts.kind,
|
|
60504
60646
|
topic: opts.topic,
|
|
60505
60647
|
status: opts.status,
|
|
@@ -61300,9 +61442,9 @@ function clustersPayload(ctx) {
|
|
|
61300
61442
|
for (const m of db.metricsTop({ kind: "file", limit: 5e3 })) {
|
|
61301
61443
|
if (m.cluster === null || !m.path) continue;
|
|
61302
61444
|
const key = String(m.cluster);
|
|
61303
|
-
const
|
|
61304
|
-
|
|
61305
|
-
members2[key] =
|
|
61445
|
+
const list3 = members2[key] ?? [];
|
|
61446
|
+
list3.push({ path: m.path, score: m.score, fanIn: m.fan_in });
|
|
61447
|
+
members2[key] = list3;
|
|
61306
61448
|
}
|
|
61307
61449
|
return { clusters: readClusters(db), cycles: readCycles(db), members: members2 };
|
|
61308
61450
|
}
|
|
@@ -61671,11 +61813,11 @@ function historyGraphPayload(ctx, limit) {
|
|
|
61671
61813
|
function historyRiskPayload(ctx, paths2) {
|
|
61672
61814
|
const m = model(ctx);
|
|
61673
61815
|
if (!m) return NO_GIT;
|
|
61674
|
-
const
|
|
61816
|
+
const list3 = paths2?.length ? paths2 : workingTreeFiles(ctx.root);
|
|
61675
61817
|
return {
|
|
61676
61818
|
git: true,
|
|
61677
61819
|
source: paths2?.length ? "paths" : "working tree",
|
|
61678
|
-
files:
|
|
61820
|
+
files: list3.map((p2) => {
|
|
61679
61821
|
const clean3 = p2.replace(/^\.\//, "");
|
|
61680
61822
|
const h = m.files.get(clean3);
|
|
61681
61823
|
const commits = commitsForFile(m, clean3);
|
|
@@ -62477,7 +62619,16 @@ function readSwarmDoc(root) {
|
|
|
62477
62619
|
const { file: file3, rel, exists } = swarmFile(root);
|
|
62478
62620
|
const base = { file: file3, rel };
|
|
62479
62621
|
if (!exists)
|
|
62480
|
-
return {
|
|
62622
|
+
return {
|
|
62623
|
+
...base,
|
|
62624
|
+
state: "absent",
|
|
62625
|
+
text: null,
|
|
62626
|
+
hash: null,
|
|
62627
|
+
doc: null,
|
|
62628
|
+
issues: [],
|
|
62629
|
+
ignoredKeys: [],
|
|
62630
|
+
locked: []
|
|
62631
|
+
};
|
|
62481
62632
|
let bytes;
|
|
62482
62633
|
try {
|
|
62483
62634
|
bytes = readFileSync30(file3);
|
|
@@ -62489,6 +62640,7 @@ function readSwarmDoc(root) {
|
|
|
62489
62640
|
hash: null,
|
|
62490
62641
|
doc: null,
|
|
62491
62642
|
issues: [{ path: "", message: `cannot read ${rel}: ${err.message}` }],
|
|
62643
|
+
ignoredKeys: [],
|
|
62492
62644
|
locked: []
|
|
62493
62645
|
};
|
|
62494
62646
|
}
|
|
@@ -62496,9 +62648,10 @@ function readSwarmDoc(root) {
|
|
|
62496
62648
|
const hash2 = createHash13("sha256").update(bytes).digest("hex");
|
|
62497
62649
|
const result = parseSwarmYaml(text3, file3, rel);
|
|
62498
62650
|
const issues = result.state === "invalid" ? result.issues : [];
|
|
62651
|
+
const ignoredKeys = result.state === "ok" ? result.config.ignoredKeys : [];
|
|
62499
62652
|
const state = result.state === "ok" ? "ok" : "invalid";
|
|
62500
62653
|
if (text3.length > SWARM_FILE_MAX_CHARS)
|
|
62501
|
-
return { ...base, state, text: text3, hash: hash2, doc: null, issues, locked: [] };
|
|
62654
|
+
return { ...base, state, text: text3, hash: hash2, doc: null, issues, ignoredKeys, locked: [] };
|
|
62502
62655
|
const Y = yaml3();
|
|
62503
62656
|
const parsed = Y.parseDocument(text3, { uniqueKeys: true, merge: true });
|
|
62504
62657
|
let doc = null;
|
|
@@ -62513,7 +62666,7 @@ function readSwarmDoc(root) {
|
|
|
62513
62666
|
} catch {
|
|
62514
62667
|
}
|
|
62515
62668
|
}
|
|
62516
|
-
return { ...base, state, text: text3, hash: hash2, doc, issues, locked };
|
|
62669
|
+
return { ...base, state, text: text3, hash: hash2, doc, issues, ignoredKeys, locked };
|
|
62517
62670
|
}
|
|
62518
62671
|
function checkSwarmText(text3, opts = {}) {
|
|
62519
62672
|
const rel = opts.rel ?? SWARM_FILES[0];
|
|
@@ -62896,6 +63049,9 @@ function applyDiff(ctx, path3, oldV, newV) {
|
|
|
62896
63049
|
inherit(old, node2);
|
|
62897
63050
|
setAt(ctx, path3, node2);
|
|
62898
63051
|
}
|
|
63052
|
+
function ignoredKeyWarnings(ignoredKeys) {
|
|
63053
|
+
return ignoredKeys.map((i) => ({ path: i.path, kind: "ignored-key", message: i.message }));
|
|
63054
|
+
}
|
|
62899
63055
|
function docWarnings(doc, activeRuns = [], prev) {
|
|
62900
63056
|
const out = [];
|
|
62901
63057
|
const swarms = isPlain(doc.swarms) ? doc.swarms : {};
|
|
@@ -63631,9 +63787,9 @@ function runDetail(ctx, run3, opts = {}) {
|
|
|
63631
63787
|
const byAgent2 = /* @__PURE__ */ new Map();
|
|
63632
63788
|
for (const e of all) {
|
|
63633
63789
|
if (!e.agent_id) continue;
|
|
63634
|
-
const
|
|
63635
|
-
|
|
63636
|
-
byAgent2.set(e.agent_id,
|
|
63790
|
+
const list3 = byAgent2.get(e.agent_id) ?? [];
|
|
63791
|
+
list3.push(e);
|
|
63792
|
+
byAgent2.set(e.agent_id, list3);
|
|
63637
63793
|
}
|
|
63638
63794
|
const loaded = loadSwarmConfig(ctx.root);
|
|
63639
63795
|
const spec = loaded.state === "ok" ? loaded.config.swarms.find((s) => s.name === run3.swarm) : void 0;
|
|
@@ -63779,7 +63935,10 @@ function swarmConfigDoc(ctx) {
|
|
|
63779
63935
|
hash: read2.hash,
|
|
63780
63936
|
doc: read2.doc,
|
|
63781
63937
|
issues: read2.issues,
|
|
63782
|
-
warnings:
|
|
63938
|
+
warnings: [
|
|
63939
|
+
...ignoredKeyWarnings(read2.ignoredKeys),
|
|
63940
|
+
...read2.doc ? docWarnings(read2.doc, activeRuns, read2.doc) : []
|
|
63941
|
+
],
|
|
63783
63942
|
locked: read2.locked,
|
|
63784
63943
|
starter: read2.state === "absent" ? starterDoc() : void 0,
|
|
63785
63944
|
activeRuns,
|
|
@@ -63829,6 +63988,7 @@ async function prepareConfig(ctx, body) {
|
|
|
63829
63988
|
const meta4 = { file: read2.file, rel: read2.rel };
|
|
63830
63989
|
let text3;
|
|
63831
63990
|
let issues = [];
|
|
63991
|
+
let ignoredKeys = [];
|
|
63832
63992
|
let draft = null;
|
|
63833
63993
|
if (b.doc !== void 0) {
|
|
63834
63994
|
draft = b.doc;
|
|
@@ -63836,10 +63996,12 @@ async function prepareConfig(ctx, body) {
|
|
|
63836
63996
|
if (!r.ok) return { reply: fail2(422, r.error, { locked: r.locked ?? read2.locked }) };
|
|
63837
63997
|
text3 = r.text;
|
|
63838
63998
|
if (r.result.state === "invalid") issues = r.result.issues;
|
|
63999
|
+
else if (r.result.state === "ok") ignoredKeys = r.result.config.ignoredKeys;
|
|
63839
64000
|
} else {
|
|
63840
64001
|
text3 = b.text;
|
|
63841
64002
|
const { result, enforceOk } = checkSwarmText(text3, meta4);
|
|
63842
64003
|
if (result.state === "invalid") issues = result.issues;
|
|
64004
|
+
else if (result.state === "ok") ignoredKeys = result.config.ignoredKeys;
|
|
63843
64005
|
if (!enforceOk)
|
|
63844
64006
|
issues = [
|
|
63845
64007
|
...issues,
|
|
@@ -63856,7 +64018,10 @@ async function prepareConfig(ctx, body) {
|
|
|
63856
64018
|
}
|
|
63857
64019
|
}
|
|
63858
64020
|
const diff2 = lineDiff(read2.text ?? "", text3);
|
|
63859
|
-
const warnings =
|
|
64021
|
+
const warnings = [
|
|
64022
|
+
...ignoredKeyWarnings(ignoredKeys),
|
|
64023
|
+
...draft && typeof draft === "object" ? docWarnings(draft, activeRunsOf(ctx), read2.doc) : []
|
|
64024
|
+
];
|
|
63860
64025
|
return {
|
|
63861
64026
|
parsed: b,
|
|
63862
64027
|
p: {
|
|
@@ -64178,9 +64343,9 @@ function listedProjects() {
|
|
|
64178
64343
|
const now = Date.now();
|
|
64179
64344
|
if (projectList && projectList.mtime === mtime && now - projectList.at < PROJECT_LIST_TTL_MS)
|
|
64180
64345
|
return projectList.list;
|
|
64181
|
-
const
|
|
64182
|
-
projectList = { at: now, mtime, list:
|
|
64183
|
-
return
|
|
64346
|
+
const list3 = listProjects();
|
|
64347
|
+
projectList = { at: now, mtime, list: list3 };
|
|
64348
|
+
return list3;
|
|
64184
64349
|
}
|
|
64185
64350
|
function resetProjectListCache() {
|
|
64186
64351
|
projectList = void 0;
|
|
@@ -64859,7 +65024,8 @@ async function swarmCommand(args, callerCtx, io = defaultIO, opts = {}) {
|
|
|
64859
65024
|
enabled: loaded.config.enabled,
|
|
64860
65025
|
enforce: loaded.config.enforce,
|
|
64861
65026
|
allowed_agents: loaded.config.allowedAgents,
|
|
64862
|
-
swarms: loaded.config.swarms.map((s) => s.name)
|
|
65027
|
+
swarms: loaded.config.swarms.map((s) => s.name),
|
|
65028
|
+
ignored_keys: loaded.config.ignoredKeys
|
|
64863
65029
|
} : loaded.state === "invalid" ? {
|
|
64864
65030
|
state: "invalid",
|
|
64865
65031
|
file: loaded.rel,
|
|
@@ -64881,6 +65047,7 @@ async function swarmCommand(args, callerCtx, io = defaultIO, opts = {}) {
|
|
|
64881
65047
|
io.out(
|
|
64882
65048
|
`ok: ${c.rel} \xB7 ${c.swarms.length} swarm(s), ${c.swarms.reduce((n, s) => n + s.roles.length, 0)} role(s)${c.enabled ? "" : " \xB7 disabled (enabled: false)"}${enforceNote(c)}`
|
|
64883
65049
|
);
|
|
65050
|
+
if (c.ignoredKeys.length) io.err(formatIssues(c.rel, c.ignoredKeys));
|
|
64884
65051
|
return 0;
|
|
64885
65052
|
}
|
|
64886
65053
|
case "sync": {
|
|
@@ -64963,9 +65130,9 @@ async function swarmCommand(args, callerCtx, io = defaultIO, opts = {}) {
|
|
|
64963
65130
|
return 2;
|
|
64964
65131
|
}
|
|
64965
65132
|
const db = await storage2(ctx);
|
|
64966
|
-
const
|
|
64967
|
-
if (json3) emit(
|
|
64968
|
-
else io.out(formatRunList(
|
|
65133
|
+
const list3 = items(db, db.swarm.runs({ limit: Math.min(limit, 500) }));
|
|
65134
|
+
if (json3) emit(list3);
|
|
65135
|
+
else io.out(formatRunList(list3));
|
|
64969
65136
|
return 0;
|
|
64970
65137
|
}
|
|
64971
65138
|
case "status": {
|