eminiar 0.13.3 → 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.
@@ -4,12 +4,12 @@ import {
4
4
  parseJob,
5
5
  runAsyncJob,
6
6
  spawnAsyncJob
7
- } from "./hook-chunk-MVSMFCKL.js";
8
- import "./hook-chunk-ETYHCPPH.js";
7
+ } from "./hook-chunk-77LASZ3C.js";
8
+ import "./hook-chunk-G7UP4ZVA.js";
9
9
  export {
10
10
  ASYNC_JOB_MAX_MS,
11
11
  parseJob,
12
12
  runAsyncJob,
13
13
  spawnAsyncJob
14
14
  };
15
- //# sourceMappingURL=hook-async-3TLK23ZY.js.map
15
+ //# sourceMappingURL=hook-async-7GK6H3OO.js.map
@@ -13,7 +13,7 @@ import {
13
13
  init_esm_shims,
14
14
  loadConfig,
15
15
  paths
16
- } from "./hook-chunk-ETYHCPPH.js";
16
+ } from "./hook-chunk-G7UP4ZVA.js";
17
17
 
18
18
  // src/adjudicator/async.ts
19
19
  init_esm_shims();
@@ -3777,4 +3777,4 @@ export {
3777
3777
  parseJob,
3778
3778
  runAsyncJob
3779
3779
  };
3780
- //# sourceMappingURL=hook-chunk-MVSMFCKL.js.map
3780
+ //# sourceMappingURL=hook-chunk-77LASZ3C.js.map
@@ -20148,6 +20148,26 @@ function adjudicatorDefaults() {
20148
20148
  privacy: { maxChars: 2e3, storeHead: true, captureExchanges: false }
20149
20149
  };
20150
20150
  }
20151
+ function graphGlobProblem(g) {
20152
+ if (g.length > 200) return "longer than 200 characters";
20153
+ if ((g.match(/\{/g)?.length ?? 0) > 4) return "more than 4 braces";
20154
+ if ((g.match(/\(/g)?.length ?? 0) > 2) return "more than 2 extglob groups";
20155
+ let total = 0;
20156
+ for (const seg of g.split(/[\\/]/)) {
20157
+ const groups = seg.match(/\*+|\?/g)?.length ?? 0;
20158
+ if (groups > 3) return "more than 3 wildcards in one path segment";
20159
+ total += groups;
20160
+ }
20161
+ return total > 8 ? "more than 8 wildcards" : void 0;
20162
+ }
20163
+ var GraphGlob = external_exports.string().superRefine((g, ctx) => {
20164
+ const why = graphGlobProblem(g);
20165
+ if (why)
20166
+ ctx.addIssue({
20167
+ code: "custom",
20168
+ message: `graph glob ${JSON.stringify(g.slice(0, 40))} is ${why}`
20169
+ });
20170
+ });
20151
20171
  var BaseConfigSchema = external_exports.object({
20152
20172
  routing: external_exports.object({
20153
20173
  /** auto = annotate while context-mode is installed, enforce once it is gone. */
@@ -20174,18 +20194,21 @@ var BaseConfigSchema = external_exports.object({
20174
20194
  dims: external_exports.number().int().positive().default(384)
20175
20195
  }).prefault({}),
20176
20196
  graph: external_exports.object({
20177
- include: external_exports.array(external_exports.string()).default([
20197
+ include: external_exports.array(GraphGlob).default([
20178
20198
  "**/*.ts",
20179
20199
  "**/*.tsx",
20180
20200
  "**/*.js",
20181
20201
  "**/*.jsx",
20182
20202
  "**/*.mjs",
20183
20203
  "**/*.cjs",
20204
+ "**/*.mts",
20205
+ "**/*.cts",
20184
20206
  "**/*.py",
20207
+ "**/*.pyi",
20185
20208
  "**/*.go",
20186
20209
  "**/*.php"
20187
20210
  ]),
20188
- exclude: external_exports.array(external_exports.string()).default([
20211
+ exclude: external_exports.array(GraphGlob).default([
20189
20212
  "**/node_modules/**",
20190
20213
  "**/dist/**",
20191
20214
  "**/build/**",
@@ -20616,6 +20639,11 @@ function resolveProjectRoot(hint) {
20616
20639
  return root;
20617
20640
  }
20618
20641
  }
20642
+ function sessionRoot(cwd) {
20643
+ return resolveProjectRoot(
20644
+ process.env.CLAUDE_PROJECT_DIR || process.env.EMINIAR_PROJECT_ROOT || cwd || process.cwd()
20645
+ );
20646
+ }
20619
20647
  function projectId(root) {
20620
20648
  return createHash("sha256").update(root).digest("hex").slice(0, 16);
20621
20649
  }
@@ -20632,6 +20660,9 @@ function getContext(rootHint) {
20632
20660
  cache.set(root, ctx);
20633
20661
  return ctx;
20634
20662
  }
20663
+ function sessionContext(cwd) {
20664
+ return getContext(sessionRoot(cwd));
20665
+ }
20635
20666
 
20636
20667
  // src/storage/dispatch.ts
20637
20668
  init_esm_shims();
@@ -24107,9 +24138,10 @@ export {
24107
24138
  PROJECT_RELATIVE_PATH_RE,
24108
24139
  AdjudicatorConfigSchema,
24109
24140
  loadConfig,
24110
- findProjectRoot,
24111
24141
  resolveProjectRoot,
24142
+ sessionRoot,
24112
24143
  getContext,
24144
+ sessionContext,
24113
24145
  tierOf,
24114
24146
  KEPT_MODEL_FLAG,
24115
24147
  keptModel,
@@ -24123,4 +24155,4 @@ export {
24123
24155
  classifyToolCall,
24124
24156
  classifyAssistant
24125
24157
  };
24126
- //# sourceMappingURL=hook-chunk-ETYHCPPH.js.map
24158
+ //# sourceMappingURL=hook-chunk-G7UP4ZVA.js.map
@@ -7,14 +7,15 @@ import {
7
7
  __toESM,
8
8
  ensureDirs,
9
9
  external_exports,
10
- findProjectRoot,
11
10
  getContext,
12
11
  getStorage,
13
12
  init_esm_shims,
14
13
  paths,
15
14
  resolveProjectRoot,
15
+ sessionContext,
16
+ sessionRoot,
16
17
  tierOf
17
- } from "./hook-chunk-ETYHCPPH.js";
18
+ } from "./hook-chunk-G7UP4ZVA.js";
18
19
 
19
20
  // node_modules/fast-glob/out/utils/array.js
20
21
  var require_array = __commonJS({
@@ -3175,9 +3176,9 @@ var require_micromatch = __commonJS({
3175
3176
  const index = v.indexOf("{");
3176
3177
  return index > -1 && v.indexOf("}", index) > -1;
3177
3178
  };
3178
- var micromatch = (list, patterns, options) => {
3179
+ var micromatch = (list2, patterns, options) => {
3179
3180
  patterns = [].concat(patterns);
3180
- list = [].concat(list);
3181
+ list2 = [].concat(list2);
3181
3182
  let omit = /* @__PURE__ */ new Set();
3182
3183
  let keep = /* @__PURE__ */ new Set();
3183
3184
  let items = /* @__PURE__ */ new Set();
@@ -3192,7 +3193,7 @@ var require_micromatch = __commonJS({
3192
3193
  let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true);
3193
3194
  let negated = isMatch.state.negated || isMatch.state.negatedExtglob;
3194
3195
  if (negated) negatives++;
3195
- for (let item of list) {
3196
+ for (let item of list2) {
3196
3197
  let matched = isMatch(item, true);
3197
3198
  let match = negated ? !matched.isMatch : matched.isMatch;
3198
3199
  if (!match) continue;
@@ -3220,7 +3221,7 @@ var require_micromatch = __commonJS({
3220
3221
  micromatch.matcher = (pattern, options) => picomatch(pattern, options);
3221
3222
  micromatch.isMatch = (str2, patterns, options) => picomatch(patterns, options)(str2);
3222
3223
  micromatch.any = micromatch.isMatch;
3223
- micromatch.not = (list, patterns, options = {}) => {
3224
+ micromatch.not = (list2, patterns, options = {}) => {
3224
3225
  patterns = [].concat(patterns).map(String);
3225
3226
  let result = /* @__PURE__ */ new Set();
3226
3227
  let items = [];
@@ -3228,7 +3229,7 @@ var require_micromatch = __commonJS({
3228
3229
  if (options.onResult) options.onResult(state);
3229
3230
  items.push(state.output);
3230
3231
  };
3231
- let matches = new Set(micromatch(list, patterns, { ...options, onResult }));
3232
+ let matches = new Set(micromatch(list2, patterns, { ...options, onResult }));
3232
3233
  for (let item of items) {
3233
3234
  if (!matches.has(item)) {
3234
3235
  result.add(item);
@@ -3262,8 +3263,8 @@ var require_micromatch = __commonJS({
3262
3263
  for (let key of keys) res[key] = obj[key];
3263
3264
  return res;
3264
3265
  };
3265
- micromatch.some = (list, patterns, options) => {
3266
- let items = [].concat(list);
3266
+ micromatch.some = (list2, patterns, options) => {
3267
+ let items = [].concat(list2);
3267
3268
  for (let pattern of [].concat(patterns)) {
3268
3269
  let isMatch = picomatch(String(pattern), options);
3269
3270
  if (items.some((item) => isMatch(item))) {
@@ -3272,8 +3273,8 @@ var require_micromatch = __commonJS({
3272
3273
  }
3273
3274
  return false;
3274
3275
  };
3275
- micromatch.every = (list, patterns, options) => {
3276
- let items = [].concat(list);
3276
+ micromatch.every = (list2, patterns, options) => {
3277
+ let items = [].concat(list2);
3277
3278
  for (let pattern of [].concat(patterns)) {
3278
3279
  let isMatch = picomatch(String(pattern), options);
3279
3280
  if (!items.every((item) => isMatch(item))) {
@@ -6253,6 +6254,70 @@ function existingGenerated(dir) {
6253
6254
  }
6254
6255
  return out;
6255
6256
  }
6257
+ function ignoredWhere(ignored, config, agentType) {
6258
+ const hit = config.swarms.flatMap(
6259
+ (swarm) => swarm.roles.filter((r) => r.agentType === agentType).map((r) => ({ swarm, role: r }))
6260
+ )[0];
6261
+ if (!hit) return [];
6262
+ const out = [];
6263
+ for (const i of ignored) {
6264
+ const seg = i.path === "" ? [] : i.path.split(".");
6265
+ const name = /"(.+?)"/.exec(i.message)?.[1] ?? "?";
6266
+ const mine = seg[0] !== "swarms" || seg.length < 2 || seg[1] === hit.swarm.name && (seg.length < 4 || seg[2] !== "agents" || seg[3] === hit.role.role);
6267
+ if (mine) out.push(name);
6268
+ }
6269
+ return out;
6270
+ }
6271
+ var list = (v) => typeof v === "string" ? v.split(",").map((x) => x.trim()).filter(Boolean) : [];
6272
+ function frontmatterOf(raw) {
6273
+ const content = raw.replace(/\r\n/g, "\n");
6274
+ const end = content.indexOf("\n---\n", 3);
6275
+ if (!content.startsWith("---\n") || end === -1) return void 0;
6276
+ try {
6277
+ const v = yaml().parse(content.slice(4, end));
6278
+ return v && typeof v === "object" ? v : void 0;
6279
+ } catch {
6280
+ return void 0;
6281
+ }
6282
+ }
6283
+ var NEUTRAL_KEYS = /* @__PURE__ */ new Set(["name", "description", "skills", "color", "model", "effort"]);
6284
+ function tightens(oldRaw, newRaw) {
6285
+ const o = frontmatterOf(oldRaw);
6286
+ const n = frontmatterOf(newRaw);
6287
+ if (!o || !n) return false;
6288
+ let tighter = false;
6289
+ for (const k of Object.keys(o)) {
6290
+ if (NEUTRAL_KEYS.has(k)) continue;
6291
+ if (!(k in n)) return false;
6292
+ const a = o[k];
6293
+ const b = n[k];
6294
+ if (JSON.stringify(a) === JSON.stringify(b)) continue;
6295
+ if (k === "tools") {
6296
+ const ob = new Set(list(a));
6297
+ const nb = list(b);
6298
+ if (!nb.every((t) => ob.has(t))) return false;
6299
+ tighter = true;
6300
+ } else if (k === "disallowedTools") {
6301
+ const nb = new Set(list(b));
6302
+ if (!list(a).every((t) => nb.has(t))) return false;
6303
+ tighter = true;
6304
+ } else if (k === "hooks") {
6305
+ const oh = a ?? {};
6306
+ const nh = b ?? {};
6307
+ for (const [ev, entries] of Object.entries(oh)) {
6308
+ const have = new Set((nh[ev] ?? []).map((e) => JSON.stringify(e)));
6309
+ if (!Array.isArray(entries) || !entries.every((e) => have.has(JSON.stringify(e))))
6310
+ return false;
6311
+ }
6312
+ tighter = true;
6313
+ } else if (k === "maxTurns") {
6314
+ if (typeof a !== "number" || typeof b !== "number" || b > a) return false;
6315
+ tighter = true;
6316
+ } else return false;
6317
+ }
6318
+ for (const k of Object.keys(n)) if (!(k in o) && !NEUTRAL_KEYS.has(k)) tighter = true;
6319
+ return tighter;
6320
+ }
6256
6321
  function planAgentSync(root, config, opts = {}) {
6257
6322
  const dir = agentsDir(root);
6258
6323
  const wantedRoles = config?.enabled ? config.swarms.flatMap((swarm) => swarm.roles.map((role) => ({ swarm, role }))) : [];
@@ -6320,6 +6385,24 @@ function planAgentSync(root, config, opts = {}) {
6320
6385
  reason: config?.enabled ? "no longer in the swarm file" : "swarms are disabled"
6321
6386
  }
6322
6387
  );
6388
+ const ignored = config?.ignoredKeys ?? [];
6389
+ if (ignored.length && !opts.force) {
6390
+ const holds = (agentType) => ignoredWhere(ignored, config, agentType);
6391
+ return actions.map((a) => {
6392
+ if (a.action !== "update") return a;
6393
+ const where = holds(a.agentType);
6394
+ if (!where.length) return a;
6395
+ const old = generated.get(a.agentType);
6396
+ if (old && tightens(old.content, a.content ?? "")) return a;
6397
+ return {
6398
+ agentType: a.agentType,
6399
+ path: a.path,
6400
+ action: "conflict",
6401
+ held: true,
6402
+ reason: `kept: ${config.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`
6403
+ };
6404
+ });
6405
+ }
6323
6406
  return actions;
6324
6407
  }
6325
6408
  function syncAgents(root, config, opts = {}) {
@@ -7931,15 +8014,6 @@ var NAME_MSG = "use 1-32 characters: lowercase letters and digits in words joine
7931
8014
  var noFence = (s) => !s.includes("---");
7932
8015
  var FENCE_MSG = 'must not contain "---" (Claude Code would end the agent frontmatter there)';
7933
8016
  var MODEL_RE = /^(?:inherit|opusplan|(?:sonnet|opus|haiku|fable)(?:\[1m\])?|(?:[a-z0-9-]+\.)*claude-[a-z0-9.:@-]+(?:\[1m\])?)$/;
7934
- var TOP_KEYS = /* @__PURE__ */ new Set([
7935
- "version",
7936
- "enabled",
7937
- "sync",
7938
- "enforce",
7939
- "allowed_agents",
7940
- "defaults",
7941
- "swarms"
7942
- ]);
7943
8017
  var DEFAULT_CONTEXT = {
7944
8018
  memories: 4,
7945
8019
  docs: 2,
@@ -7968,7 +8042,7 @@ var SkillName = external_exports.string().regex(
7968
8042
  ).refine(noFence, FENCE_MSG);
7969
8043
  var 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);
7970
8044
  var rank = (t) => TIERS.indexOf(t);
7971
- var RawModelRange = external_exports.strictObject({ floor: external_exports.enum(TIERS).optional(), ceiling: external_exports.enum(TIERS).optional() }).refine(
8045
+ var RawModelRange = external_exports.object({ floor: external_exports.enum(TIERS).optional(), ceiling: external_exports.enum(TIERS).optional() }).refine(
7972
8046
  (r) => !r.floor || !r.ceiling || rank(r.floor) <= rank(r.ceiling),
7973
8047
  `floor must not be above ceiling (${TIERS.join(" < ")})`
7974
8048
  );
@@ -7992,7 +8066,7 @@ var AgentName = external_exports.string().trim().regex(
7992
8066
  (n) => !n.startsWith("swarm-"),
7993
8067
  "swarm workers need no entry: they are allowed during a run of their swarm"
7994
8068
  );
7995
- var RawContext = external_exports.strictObject({
8069
+ var RawContext = external_exports.object({
7996
8070
  memories: external_exports.number().int().min(0).max(10).optional(),
7997
8071
  docs: external_exports.number().int().min(0).max(10).optional(),
7998
8072
  history: external_exports.boolean().optional(),
@@ -8001,12 +8075,12 @@ var RawContext = external_exports.strictObject({
8001
8075
  // SubagentStart context over 10,000 characters is moved to a file Claude may never read.
8002
8076
  max_chars: external_exports.number().int().min(500).max(9e3).optional()
8003
8077
  });
8004
- var RawHookCommand = external_exports.strictObject({
8078
+ var RawHookCommand = external_exports.object({
8005
8079
  type: external_exports.literal("command"),
8006
8080
  command: external_exports.string().trim().min(1).max(2e3).refine(noFence, FENCE_MSG),
8007
8081
  timeout: external_exports.number().int().positive().max(600).optional()
8008
8082
  });
8009
- var RawHookMatcher = external_exports.strictObject({
8083
+ var RawHookMatcher = external_exports.object({
8010
8084
  matcher: external_exports.string().max(200).refine(noFence, FENCE_MSG).refine((m) => {
8011
8085
  try {
8012
8086
  new RegExp(m);
@@ -8017,12 +8091,12 @@ var RawHookMatcher = external_exports.strictObject({
8017
8091
  }, "not a valid regular expression (Claude Code matches tool names with it)").optional(),
8018
8092
  hooks: external_exports.array(RawHookCommand).min(1).max(10)
8019
8093
  });
8020
- var RawHooks = external_exports.strictObject({
8094
+ var RawHooks = external_exports.object({
8021
8095
  PreToolUse: external_exports.array(RawHookMatcher).max(10).optional(),
8022
8096
  PostToolUse: external_exports.array(RawHookMatcher).max(10).optional(),
8023
8097
  Stop: external_exports.array(RawHookMatcher).max(10).optional()
8024
8098
  });
8025
- var RawAgent = external_exports.strictObject({
8099
+ var RawAgent = external_exports.object({
8026
8100
  description: external_exports.string().trim().min(1).max(500).refine(noFence, FENCE_MSG),
8027
8101
  prompt: external_exports.string().max(2e4).optional(),
8028
8102
  model: Model.optional(),
@@ -8040,7 +8114,7 @@ var RawAgent = external_exports.strictObject({
8040
8114
  color: external_exports.enum(AGENT_COLORS).optional(),
8041
8115
  context: RawContext.optional()
8042
8116
  });
8043
- var RawSwarm = external_exports.strictObject({
8117
+ var RawSwarm = external_exports.object({
8044
8118
  description: external_exports.string().trim().min(1).max(500),
8045
8119
  topology: external_exports.enum(TOPOLOGIES).optional(),
8046
8120
  max_agents: external_exports.number().int().min(1).max(16).optional(),
@@ -8056,7 +8130,7 @@ var RawFile = external_exports.looseObject({
8056
8130
  sync: external_exports.enum(["auto", "manual"]).optional(),
8057
8131
  enforce: external_exports.boolean().optional(),
8058
8132
  allowed_agents: external_exports.array(AgentName).max(50).optional(),
8059
- defaults: external_exports.strictObject({
8133
+ defaults: external_exports.object({
8060
8134
  model: Model.optional(),
8061
8135
  model_range: RawModelRange.optional(),
8062
8136
  skills: external_exports.array(SkillName).max(20).optional(),
@@ -8081,6 +8155,53 @@ function mergeContext(...layers) {
8081
8155
  return out;
8082
8156
  }
8083
8157
  var uniq = (xs) => [...new Set(xs)];
8158
+ function unknownKeys(v, s = RawFile, at = []) {
8159
+ if (s instanceof external_exports.ZodOptional) s = s.unwrap();
8160
+ if (Array.isArray(v))
8161
+ return s instanceof external_exports.ZodArray ? v.flatMap((x, i) => unknownKeys(x, s.element, [...at, String(i)])) : [];
8162
+ if (!v || typeof v !== "object") return [];
8163
+ const entries = Object.entries(v);
8164
+ if (s instanceof external_exports.ZodRecord)
8165
+ return entries.flatMap(([k, x]) => unknownKeys(x, s.valueType, [...at, k]));
8166
+ if (!(s instanceof external_exports.ZodObject)) return [];
8167
+ const known = Object.keys(s.shape);
8168
+ return entries.flatMap(
8169
+ ([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 }]
8170
+ );
8171
+ }
8172
+ function schemaKeys(s = RawFile, out = /* @__PURE__ */ new Set()) {
8173
+ if (s instanceof external_exports.ZodOptional) s = s.unwrap();
8174
+ if (s instanceof external_exports.ZodArray) schemaKeys(s.element, out);
8175
+ else if (s instanceof external_exports.ZodRecord) schemaKeys(s.valueType, out);
8176
+ else if (s instanceof external_exports.ZodObject) {
8177
+ for (const [k, v] of Object.entries(s.shape))
8178
+ if (!out.has(k)) {
8179
+ out.add(k);
8180
+ schemaKeys(v, out);
8181
+ }
8182
+ }
8183
+ return out;
8184
+ }
8185
+ var RESTRICTION_KEY = /tool|scope|hook|allow|deny|permission|model|effort|count/i;
8186
+ function restrictionLike(key, known) {
8187
+ let best;
8188
+ for (const k of known) {
8189
+ if (!RESTRICTION_KEY.test(k)) continue;
8190
+ const d = editDistance(key.toLowerCase(), k.toLowerCase(), 2);
8191
+ if (d <= 2 && key.length >= 3 && (!best || d < best.d)) best = { k, d };
8192
+ }
8193
+ if (best) return best.k;
8194
+ return RESTRICTION_KEY.test(key) ? "" : void 0;
8195
+ }
8196
+ function typoOf(key, known) {
8197
+ const max = key.length >= 7 ? 2 : 1;
8198
+ let best;
8199
+ for (const k of known) {
8200
+ const d = editDistance(key.toLowerCase(), k.toLowerCase(), max);
8201
+ if (d <= max && (!best || d < best.d)) best = { k, d };
8202
+ }
8203
+ return best?.k;
8204
+ }
8084
8205
  function roleRange(defaults, a, at, issue) {
8085
8206
  const spec = a.model_range ?? defaults?.model_range;
8086
8207
  if (!spec || !spec.floor && !spec.ceiling) return void 0;
@@ -8216,6 +8337,27 @@ function parseSwarmYaml(text, file, rel) {
8216
8337
  for (const role of Object.keys(agents))
8217
8338
  checkName(["swarms", name, "agents", role], role, "agent");
8218
8339
  }
8340
+ const ignoredKeys = [];
8341
+ const allKeys = schemaKeys();
8342
+ for (const u of unknownKeys(js)) {
8343
+ const near = typoOf(u.key, u.known);
8344
+ const found = { path: u.at.join("."), line: lineOf([...u.at, u.key]) };
8345
+ if (allKeys.has(u.key))
8346
+ issues.push({ ...found, message: `unknown key "${u.key}": not allowed here` });
8347
+ else if (near)
8348
+ issues.push({ ...found, message: `unknown key "${u.key}" (did you mean "${near}"?)` });
8349
+ else if (u.at.length === 4 && u.at[0] === "swarms" && u.at[2] === "agents" && restrictionLike(u.key, u.known) !== void 0) {
8350
+ const like = restrictionLike(u.key, u.known);
8351
+ issues.push({
8352
+ ...found,
8353
+ message: `unknown key "${u.key}" looks like a restriction${like ? ` (did you mean "${like}"?)` : ""}: ignoring it would silently drop a limit`
8354
+ });
8355
+ } else
8356
+ ignoredKeys.push({
8357
+ ...found,
8358
+ message: `unknown key "${u.key}" ignored: not a setting in this eminiar version`
8359
+ });
8360
+ }
8219
8361
  const parsed = RawFile.safeParse(js);
8220
8362
  if (!parsed.success) {
8221
8363
  return {
@@ -8233,15 +8375,9 @@ function parseSwarmYaml(text, file, rel) {
8233
8375
  ]
8234
8376
  };
8235
8377
  }
8236
- for (const k of Object.keys(js))
8237
- if (!TOP_KEYS.has(k) && !k.startsWith("x-") && k !== "<<")
8238
- issue(
8239
- [k],
8240
- `unknown key "${k}" (top-level keys: ${[...TOP_KEYS].join(", ")}; x-* keys may hold YAML anchors)`
8241
- );
8242
8378
  const config = resolve2(parsed.data, file, rel, issue);
8243
8379
  if (issues.length) return { state: "invalid", file, rel, enforce, issues };
8244
- return { state: "ok", config };
8380
+ return { state: "ok", config: { ...config, ignoredKeys } };
8245
8381
  }
8246
8382
  function resolve2(raw, file, rel, issue) {
8247
8383
  const swarms = [];
@@ -9142,16 +9278,6 @@ function configFor(local, main, agentType) {
9142
9278
  }
9143
9279
  return void 0;
9144
9280
  }
9145
- function sessionRoot() {
9146
- const root = findProjectRoot(
9147
- process.env.CLAUDE_PROJECT_DIR || process.env.EMINIAR_PROJECT_ROOT || process.cwd()
9148
- );
9149
- try {
9150
- return realpathSync5(root);
9151
- } catch {
9152
- return root;
9153
- }
9154
- }
9155
9281
  function orderedRoots(hookRoot) {
9156
9282
  const out = [];
9157
9283
  try {
@@ -9162,13 +9288,8 @@ function orderedRoots(hookRoot) {
9162
9288
  return out;
9163
9289
  }
9164
9290
  function swarmRoots(input) {
9165
- let hook;
9166
- try {
9167
- hook = resolveProjectRoot(input.cwd || void 0);
9168
- } catch {
9169
- }
9170
9291
  const out = [];
9171
- for (const r of orderedRoots(hook)) {
9292
+ for (const r of orderedRoots(hookRootOf(input))) {
9172
9293
  for (const d of [r, coordinationRoot(r)]) if (!out.includes(d)) out.push(d);
9173
9294
  }
9174
9295
  return out;
@@ -9184,9 +9305,16 @@ function enforcementRoots() {
9184
9305
  return [];
9185
9306
  }
9186
9307
  }
9187
- function swarmRootCandidates(ctx) {
9308
+ function hookRootOf(input) {
9309
+ try {
9310
+ return resolveProjectRoot(input.cwd || void 0);
9311
+ } catch {
9312
+ return void 0;
9313
+ }
9314
+ }
9315
+ function swarmRootCandidates(ctx, input) {
9188
9316
  const out = [];
9189
- for (const r of orderedRoots(ctx.root)) {
9317
+ for (const r of orderedRoots(hookRootOf(input))) {
9190
9318
  if (r === ctx.root) {
9191
9319
  out.push(ctx);
9192
9320
  continue;
@@ -9198,8 +9326,8 @@ function swarmRootCandidates(ctx) {
9198
9326
  }
9199
9327
  return out;
9200
9328
  }
9201
- function swarmScope(hookCtx, agentType) {
9202
- for (const ctx of swarmRootCandidates(hookCtx)) {
9329
+ function swarmScope(hookCtx, input, agentType) {
9330
+ for (const ctx of swarmRootCandidates(hookCtx, input)) {
9203
9331
  const main = coordinationRoot(ctx.root);
9204
9332
  const config = configFor(ctx.root, main, agentType);
9205
9333
  if (!config) continue;
@@ -9219,7 +9347,7 @@ function swarmPreAgent(ctx, input) {
9219
9347
  if (!isSwarmAgentType(agentType)) return void 0;
9220
9348
  let scope;
9221
9349
  try {
9222
- scope = swarmScope(ctx, agentType);
9350
+ scope = swarmScope(ctx, input, agentType);
9223
9351
  } catch (err) {
9224
9352
  return fail("preAgent", err);
9225
9353
  }
@@ -9427,7 +9555,7 @@ function isBusy(err) {
9427
9555
  function swarmTouch(ctx, input) {
9428
9556
  if (!input.agent_id || !isSwarmAgentType(input.agent_type)) return;
9429
9557
  try {
9430
- const s = swarmScope(ctx, input.agent_type);
9558
+ const s = swarmScope(ctx, input, input.agent_type);
9431
9559
  if (s) touchWorker(s.db, input.agent_id);
9432
9560
  } catch (err) {
9433
9561
  fail("touch", err);
@@ -9474,7 +9602,7 @@ function swarmAgentReturned(ctx, input) {
9474
9602
  const agentType = spawnType(input);
9475
9603
  if (!isSwarmAgentType(agentType) || !input.tool_use_id) return;
9476
9604
  try {
9477
- const s = swarmScope(ctx, agentType);
9605
+ const s = swarmScope(ctx, input, agentType);
9478
9606
  if (s) releaseSpawn(s.db, input.tool_use_id);
9479
9607
  } catch (err) {
9480
9608
  fail("agentReturned", err);
@@ -9483,7 +9611,7 @@ function swarmAgentReturned(ctx, input) {
9483
9611
  function swarmSessionEnd(ctx, input) {
9484
9612
  if (!input.session_id) return;
9485
9613
  try {
9486
- const s = swarmScope(ctx);
9614
+ const s = swarmScope(ctx, input);
9487
9615
  if (s) closeSessionWorkers(s.db, input.session_id);
9488
9616
  } catch (err) {
9489
9617
  fail("sessionEnd", err);
@@ -9497,7 +9625,7 @@ async function swarmSubagentStart(ctx, input) {
9497
9625
  if (!isSwarmAgentType(agentType) || !input.agent_id) return void 0;
9498
9626
  let s;
9499
9627
  try {
9500
- s = swarmScope(ctx, agentType);
9628
+ s = swarmScope(ctx, input, agentType);
9501
9629
  } catch (err) {
9502
9630
  return fail("subagentStart", err);
9503
9631
  }
@@ -9555,7 +9683,7 @@ function fallbackBrief(role, swarm, runId) {
9555
9683
  var subagentStart = async (input) => {
9556
9684
  if (!isSwarmAgentType(input.agent_type) || !input.agent_id) return void 0;
9557
9685
  try {
9558
- return await swarmSubagentStart(getContext(input.cwd), input);
9686
+ return await swarmSubagentStart(sessionContext(input.cwd), input);
9559
9687
  } catch (err) {
9560
9688
  return fail("subagentStart", err);
9561
9689
  }
@@ -9564,7 +9692,7 @@ function swarmActivity(ctx, input, failed) {
9564
9692
  const agentType = input.agent_type;
9565
9693
  if (!isSwarmAgentType(agentType) || !input.agent_id || !input.tool_name) return;
9566
9694
  try {
9567
- const s = swarmScope(ctx, agentType);
9695
+ const s = swarmScope(ctx, input, agentType);
9568
9696
  if (!s) return;
9569
9697
  recordActivity(s.db, s.config, s.root, {
9570
9698
  agentId: input.agent_id,
@@ -9583,7 +9711,7 @@ function swarmSubagentStop(ctx, input) {
9583
9711
  const agentType = input.agent_type;
9584
9712
  if (!isSwarmAgentType(agentType) || !input.agent_id) return;
9585
9713
  try {
9586
- const s = swarmScope(ctx, agentType);
9714
+ const s = swarmScope(ctx, input, agentType);
9587
9715
  if (!s) return;
9588
9716
  closeWorker(s.db, s.config, {
9589
9717
  agentId: input.agent_id,
@@ -9653,9 +9781,17 @@ function sessionStartAt(ctx, sessionId) {
9653
9781
  out.push(
9654
9782
  config.sync === "auto" ? `Agent files were regenerated (${sync.changed} changed); if Claude Code does not list them yet, run /agents or restart.` : `${sync.changed} agent file(s) are out of date (sync: manual); run \`eminiar swarm sync\`.`
9655
9783
  );
9656
- if (sync.conflicts)
9784
+ const held = sync.actions.filter((a) => a.held).length;
9785
+ if (config.ignoredKeys.length)
9786
+ out.push(
9787
+ clip2(
9788
+ `${config.rel}: ${config.ignoredKeys.length} unknown key(s) ignored (first: ${issueWhere(config.ignoredKeys)}); generated agent files of the roles those keys belong to are not rewritten unless an update only tightens them (\`eminiar swarm sync --force\` does). \`eminiar swarm validate\` lists the keys.`,
9789
+ 400
9790
+ )
9791
+ );
9792
+ if (sync.conflicts > held)
9657
9793
  out.push(
9658
- `${sync.conflicts} agent file(s) in .claude/agents were left alone (hand-written, or generated and then edited); \`eminiar swarm sync --dry-run\` explains.`
9794
+ `${sync.conflicts - held} agent file(s) in .claude/agents were left alone (hand-written, or generated and then edited); \`eminiar swarm sync --dry-run\` explains.`
9659
9795
  );
9660
9796
  const mctx = main === local ? ctx : getContext(main);
9661
9797
  const db = getStorage(mctx, { vectors: false });
@@ -9905,4 +10041,4 @@ queue-microtask/index.js:
9905
10041
  run-parallel/index.js:
9906
10042
  (*! run-parallel. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> *)
9907
10043
  */
9908
- //# sourceMappingURL=hook-chunk-ZLRLOPLR.js.map
10044
+ //# sourceMappingURL=hook-chunk-RE4WT5D3.js.map
@@ -8,7 +8,7 @@ import {
8
8
  manifestPath,
9
9
  readManifestAt,
10
10
  resolvePrice
11
- } from "./hook-chunk-ZLRLOPLR.js";
11
+ } from "./hook-chunk-RE4WT5D3.js";
12
12
  import {
13
13
  adjudicateOne,
14
14
  briefUnitsOf,
@@ -18,7 +18,7 @@ import {
18
18
  resolveAdjudicator,
19
19
  spawnAsyncJob,
20
20
  topIntent
21
- } from "./hook-chunk-MVSMFCKL.js";
21
+ } from "./hook-chunk-77LASZ3C.js";
22
22
  import {
23
23
  AGENT_EFFORT_SINCE,
24
24
  KEPT_MODEL_FLAG,
@@ -30,7 +30,7 @@ import {
30
30
  init_esm_shims,
31
31
  keptModel,
32
32
  tierOf
33
- } from "./hook-chunk-ETYHCPPH.js";
33
+ } from "./hook-chunk-G7UP4ZVA.js";
34
34
 
35
35
  // src/adjudicator/hooks.ts
36
36
  init_esm_shims();
@@ -1826,4 +1826,4 @@ export {
1826
1826
  withModel,
1827
1827
  withNote
1828
1828
  };
1829
- //# sourceMappingURL=hook-hooks-5U2AI6W7.js.map
1829
+ //# sourceMappingURL=hook-hooks-5H6LFYD5.js.map