eminiar 0.13.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/README.md +43 -15
- package/bin/_resolve.sh +7 -4
- package/bin/em-hook +2 -1
- package/bin/em-server +2 -1
- package/bin/eminiar +2 -1
- package/dist/cli.js +1502 -224
- package/dist/{hook-async-4MIP3VHX.js → hook-async-J3UKDO62.js} +3 -3
- package/dist/{hook-chunk-IYHVLMJ4.js → hook-chunk-BECSRJFD.js} +26 -11
- package/dist/{hook-chunk-MVOBVFQL.js → hook-chunk-DSLVDGOB.js} +57 -12
- package/dist/{hook-chunk-77I6QQ43.js → hook-chunk-RYZAFUTT.js} +2 -2
- package/dist/{hook-hooks-U6GDOQSY.js → hook-hooks-IDTGXCFD.js} +8 -6
- package/dist/hook.js +234 -57
- package/dist/server.js +80 -43
- package/dist/ui/app.global.js +78 -72
- package/dist/ui/styles.css +4724 -1508
- package/package.json +1 -1
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
parseJob,
|
|
5
5
|
runAsyncJob,
|
|
6
6
|
spawnAsyncJob
|
|
7
|
-
} from "./hook-chunk-
|
|
8
|
-
import "./hook-chunk-
|
|
7
|
+
} from "./hook-chunk-RYZAFUTT.js";
|
|
8
|
+
import "./hook-chunk-BECSRJFD.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-
|
|
15
|
+
//# sourceMappingURL=hook-async-J3UKDO62.js.map
|
|
@@ -19929,6 +19929,12 @@ import { join } from "path";
|
|
|
19929
19929
|
function eminiarHome() {
|
|
19930
19930
|
return process.env.EMINIAR_HOME || join(homedir(), ".eminiar");
|
|
19931
19931
|
}
|
|
19932
|
+
function claudeConfigDir(env = process.env, home = homedir()) {
|
|
19933
|
+
return env.CLAUDE_CONFIG_DIR?.trim() || join(home, ".claude");
|
|
19934
|
+
}
|
|
19935
|
+
function claudePluginsDir(env = process.env, home = homedir()) {
|
|
19936
|
+
return env.CLAUDE_CODE_PLUGIN_CACHE_DIR?.trim() || join(claudeConfigDir(env, home), "plugins");
|
|
19937
|
+
}
|
|
19932
19938
|
function paths() {
|
|
19933
19939
|
const home = eminiarHome();
|
|
19934
19940
|
return {
|
|
@@ -20032,9 +20038,9 @@ var buildAdjudicatorObject = () => external_exports.object({
|
|
|
20032
20038
|
}).prefault({}),
|
|
20033
20039
|
minPromptChars: external_exports.number().int().min(0).default(12),
|
|
20034
20040
|
/**
|
|
20035
|
-
* Ordered ladder, smallest first; "fable" may be inserted by the user.
|
|
20036
|
-
*
|
|
20037
|
-
* tier at most once (task #56).
|
|
20041
|
+
* Ordered ladder, smallest first; "fable" may be inserted by the user. Personal config only
|
|
20042
|
+
* (a committed project file cannot set it). Every provider request carries the whole ladder,
|
|
20043
|
+
* so it is bounded: each tier at most once (task #56).
|
|
20038
20044
|
*/
|
|
20039
20045
|
tiers: external_exports.array(external_exports.enum(TIERS)).min(1).max(TIERS.length).refine((t) => new Set(t).size === t.length, "adjudicator.tiers must not repeat a tier").meta({ uniqueItems: true }).default(["haiku", "sonnet", "opus"]),
|
|
20040
20046
|
weights: external_exports.object({
|
|
@@ -20384,22 +20390,22 @@ function envOverrides() {
|
|
|
20384
20390
|
}
|
|
20385
20391
|
var PROJECT_ADJUDICATOR_KEYS = [
|
|
20386
20392
|
"enabled",
|
|
20387
|
-
"mode",
|
|
20388
20393
|
"surfaces",
|
|
20389
20394
|
"promptMode",
|
|
20390
20395
|
"minPromptChars",
|
|
20391
|
-
"tiers",
|
|
20392
20396
|
"weights",
|
|
20393
|
-
"apply",
|
|
20394
20397
|
"advice",
|
|
20395
20398
|
"embedding",
|
|
20396
20399
|
"learning",
|
|
20397
20400
|
"cache"
|
|
20398
20401
|
];
|
|
20402
|
+
function projectKeeps(adj, k) {
|
|
20403
|
+
return PROJECT_ADJUDICATOR_KEYS.includes(k) || k === "mode" && adj.mode === "advise";
|
|
20404
|
+
}
|
|
20399
20405
|
function droppedProjectAdjudicatorKeys(raw) {
|
|
20400
20406
|
const adj = raw.adjudicator;
|
|
20401
20407
|
if (!isPlainObject2(adj)) return [];
|
|
20402
|
-
return Object.keys(adj).filter((k) => !
|
|
20408
|
+
return Object.keys(adj).filter((k) => !projectKeeps(adj, k)).sort();
|
|
20403
20409
|
}
|
|
20404
20410
|
var CASE_INSENSITIVE_FS = process.platform === "darwin" || process.platform === "win32";
|
|
20405
20411
|
function realPath(p) {
|
|
@@ -20516,7 +20522,7 @@ function projectLayer(raw) {
|
|
|
20516
20522
|
if (!isPlainObject2(adj)) return raw;
|
|
20517
20523
|
if (findSecretFields(adj).length) return raw;
|
|
20518
20524
|
const kept = {};
|
|
20519
|
-
for (const k of
|
|
20525
|
+
for (const k of Object.keys(adj)) if (projectKeeps(adj, k)) kept[k] = adj[k];
|
|
20520
20526
|
return { ...ownJson(raw), adjudicator: kept };
|
|
20521
20527
|
}
|
|
20522
20528
|
function withoutUnsafeDocsManifest(raw, source) {
|
|
@@ -22603,7 +22609,7 @@ function usageWhere(f, opts = {}) {
|
|
|
22603
22609
|
var SqliteAdapter = class _SqliteAdapter {
|
|
22604
22610
|
constructor(path2, opts = {}) {
|
|
22605
22611
|
this.path = path2;
|
|
22606
|
-
this.db = new Database(path2, { timeout: 2e3 });
|
|
22612
|
+
this.db = new Database(path2, { timeout: opts.busyTimeoutMs ?? 2e3 });
|
|
22607
22613
|
this.swarm = new SqliteSwarmStore(this.db);
|
|
22608
22614
|
this.adjudicator = new SqliteAdjudicatorStore(this.db);
|
|
22609
22615
|
this.db.pragma("journal_mode = WAL");
|
|
@@ -23817,13 +23823,18 @@ var SqliteAdapter = class _SqliteAdapter {
|
|
|
23817
23823
|
|
|
23818
23824
|
// src/storage/index.ts
|
|
23819
23825
|
var open2 = /* @__PURE__ */ new Map();
|
|
23826
|
+
var busyTimeoutMs;
|
|
23827
|
+
function setStorageBusyTimeout(ms) {
|
|
23828
|
+
busyTimeoutMs = ms;
|
|
23829
|
+
}
|
|
23820
23830
|
function getStorage(ctx, opts = {}) {
|
|
23821
23831
|
const key = `${ctx.dbPath}|${opts.vectors === false ? "novec" : "vec"}`;
|
|
23822
23832
|
let adapter = open2.get(key);
|
|
23823
23833
|
if (!adapter) {
|
|
23824
23834
|
adapter = new SqliteAdapter(ctx.dbPath, {
|
|
23825
23835
|
dims: ctx.config.embeddings.dims,
|
|
23826
|
-
vectors: opts.vectors ?? true
|
|
23836
|
+
vectors: opts.vectors ?? true,
|
|
23837
|
+
...busyTimeoutMs === void 0 ? {} : { busyTimeoutMs }
|
|
23827
23838
|
});
|
|
23828
23839
|
open2.set(key, adapter);
|
|
23829
23840
|
}
|
|
@@ -24077,16 +24088,20 @@ export {
|
|
|
24077
24088
|
AGENT_EFFORT_SINCE,
|
|
24078
24089
|
TOOL_IDS,
|
|
24079
24090
|
DEFAULT_ROLES,
|
|
24091
|
+
claudeConfigDir,
|
|
24092
|
+
claudePluginsDir,
|
|
24080
24093
|
paths,
|
|
24081
24094
|
ensureDirs,
|
|
24082
24095
|
projectDir,
|
|
24083
24096
|
AdjudicatorConfigSchema,
|
|
24084
24097
|
loadConfig,
|
|
24085
24098
|
findProjectRoot,
|
|
24099
|
+
resolveProjectRoot,
|
|
24086
24100
|
getContext,
|
|
24087
24101
|
tierOf,
|
|
24088
24102
|
KEPT_MODEL_FLAG,
|
|
24089
24103
|
keptModel,
|
|
24104
|
+
setStorageBusyTimeout,
|
|
24090
24105
|
getStorage,
|
|
24091
24106
|
GUIDE_ORDER,
|
|
24092
24107
|
ev,
|
|
@@ -24096,4 +24111,4 @@ export {
|
|
|
24096
24111
|
classifyToolCall,
|
|
24097
24112
|
classifyAssistant
|
|
24098
24113
|
};
|
|
24099
|
-
//# sourceMappingURL=hook-chunk-
|
|
24114
|
+
//# sourceMappingURL=hook-chunk-BECSRJFD.js.map
|
|
@@ -11,8 +11,9 @@ import {
|
|
|
11
11
|
getStorage,
|
|
12
12
|
init_esm_shims,
|
|
13
13
|
paths,
|
|
14
|
+
resolveProjectRoot,
|
|
14
15
|
tierOf
|
|
15
|
-
} from "./hook-chunk-
|
|
16
|
+
} from "./hook-chunk-BECSRJFD.js";
|
|
16
17
|
|
|
17
18
|
// node_modules/fast-glob/out/utils/array.js
|
|
18
19
|
var require_array = __commonJS({
|
|
@@ -6065,6 +6066,14 @@ function yaml() {
|
|
|
6065
6066
|
yamlLib ??= createRequire(import.meta.url)("yaml");
|
|
6066
6067
|
return yamlLib;
|
|
6067
6068
|
}
|
|
6069
|
+
var EXEC_TOOLS = /* @__PURE__ */ new Set([
|
|
6070
|
+
"em_execute",
|
|
6071
|
+
"em_execute_file",
|
|
6072
|
+
"em_batch_execute"
|
|
6073
|
+
]);
|
|
6074
|
+
function roleHasShell(role) {
|
|
6075
|
+
return (role.tools?.includes("Bash") ?? true) && !role.disallowedTools?.includes("Bash");
|
|
6076
|
+
}
|
|
6068
6077
|
var EM_MCP_PREFIXES = ["mcp__plugin_eminiar_eminiar__", "mcp__eminiar__"];
|
|
6069
6078
|
var AGENTS_REL = ".claude/agents";
|
|
6070
6079
|
function agentsDir(root) {
|
|
@@ -6078,21 +6087,26 @@ var TOPOLOGY_RULE = {
|
|
|
6078
6087
|
mesh: "peers share one task board. Claim any open task (your role's first), and read the blackboard for what the other workers found.",
|
|
6079
6088
|
pipeline: "work moves in stages. You can claim a task only once every task of the earlier stages is done."
|
|
6080
6089
|
};
|
|
6081
|
-
function workerTools(tools) {
|
|
6090
|
+
function workerTools(tools, shell = tools.includes("Bash")) {
|
|
6082
6091
|
const out = tools.includes("ToolSearch") ? [...tools] : [...tools, "ToolSearch"];
|
|
6083
6092
|
for (const prefix of EM_MCP_PREFIXES)
|
|
6084
|
-
for (const t of WORKER_EM_TOOLS)
|
|
6093
|
+
for (const t of WORKER_EM_TOOLS)
|
|
6094
|
+
if ((shell || !EXEC_TOOLS.has(t)) && !out.includes(prefix + t)) out.push(prefix + t);
|
|
6085
6095
|
return out;
|
|
6086
6096
|
}
|
|
6097
|
+
var execToolNames = () => EM_MCP_PREFIXES.flatMap((prefix) => [...EXEC_TOOLS].map((t) => prefix + t));
|
|
6087
6098
|
function frontmatter(swarm, role) {
|
|
6088
6099
|
const fm = {
|
|
6089
6100
|
name: role.agentType,
|
|
6090
6101
|
description: `Worker "${role.role}" of the eminiar swarm "${swarm.name}": ${role.description} Spawn it for a task of this swarm and name the task as "task #N" in the prompt; the em-swarm skill coordinates runs.`
|
|
6091
6102
|
};
|
|
6092
6103
|
if (role.model) fm.model = role.model;
|
|
6093
|
-
if (role.tools) fm.tools = workerTools(role.tools).join(", ");
|
|
6104
|
+
if (role.tools) fm.tools = workerTools(role.tools, roleHasShell(role)).join(", ");
|
|
6094
6105
|
const spawns = role.tools?.some((t) => t === "Agent" || t === "Task");
|
|
6095
|
-
const
|
|
6106
|
+
const noShell = role.disallowedTools?.includes("Bash") ? execToolNames() : [];
|
|
6107
|
+
const disallowed = [
|
|
6108
|
+
.../* @__PURE__ */ new Set([...role.disallowedTools ?? [], ...spawns ? [] : ["Agent"], ...noShell])
|
|
6109
|
+
];
|
|
6096
6110
|
if (disallowed.length) fm.disallowedTools = disallowed.join(", ");
|
|
6097
6111
|
if (role.skills.length) fm.skills = role.skills;
|
|
6098
6112
|
if (role.hooks) {
|
|
@@ -6111,6 +6125,7 @@ var hashOf = (fm, rest, range) => createHash("sha1").update(range ? `range=${ran
|
|
|
6111
6125
|
${fm}
|
|
6112
6126
|
${rest}` : `${fm}
|
|
6113
6127
|
${rest}`).digest("hex").slice(0, 12);
|
|
6128
|
+
var 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.";
|
|
6114
6129
|
function renderAgentFile(config, swarm, role) {
|
|
6115
6130
|
const fm = yaml().stringify(frontmatter(swarm, role), { lineWidth: 0 }).trimEnd();
|
|
6116
6131
|
if (fm.includes("---"))
|
|
@@ -6124,12 +6139,15 @@ function renderAgentFile(config, swarm, role) {
|
|
|
6124
6139
|
...role.prompt ? [role.prompt, ""] : [],
|
|
6125
6140
|
"## Swarm protocol",
|
|
6126
6141
|
"",
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6142
|
+
...[
|
|
6143
|
+
'eminiar starts you with a swarm brief: the run goal, the open tasks, the shared notes and what the project knows (memories, history, structure). First claim the task your prompt names with `em_swarm {action:"claim", task:N}` (or the next open one with `em_swarm {action:"claim"}`); if the brief says you already hold a task, continue it.',
|
|
6144
|
+
'Ask eminiar before acting: `em_recall {query}` for decisions and constraints, `em_history {action:"file", path}` before editing a file, `em_graph_impact {node}` before changing a symbol, `em_symbols` / `em_search` instead of grepping.',
|
|
6145
|
+
...!role.isolation && roleHasShell(role) ? [SHARED_TREE_RULE] : [],
|
|
6146
|
+
'Share what other workers need with `em_swarm {action:"post", key, value}` and read theirs with `em_swarm {action:"read"}`.',
|
|
6147
|
+
'Close every task with `em_swarm {action:"update", task, status, result}`: status `done`, `failed` or `blocked`; the result says what changed and how you verified it.',
|
|
6148
|
+
"Record durable decisions with `em_remember` so later sessions know them.",
|
|
6149
|
+
"Your final message goes back to the coordinator: lead with the outcome, then the files you changed and anything left open."
|
|
6150
|
+
].map((step, i) => `${i + 1}. ${step}`),
|
|
6133
6151
|
""
|
|
6134
6152
|
].join("\n");
|
|
6135
6153
|
const range = role.range ? modelRangeText(role.range) : void 0;
|
|
@@ -9123,6 +9141,18 @@ function orderedRoots(hookRoot) {
|
|
|
9123
9141
|
if (hookRoot && !out.includes(hookRoot)) out.push(hookRoot);
|
|
9124
9142
|
return out;
|
|
9125
9143
|
}
|
|
9144
|
+
function swarmRoots(input) {
|
|
9145
|
+
let hook;
|
|
9146
|
+
try {
|
|
9147
|
+
hook = resolveProjectRoot(input.cwd || void 0);
|
|
9148
|
+
} catch {
|
|
9149
|
+
}
|
|
9150
|
+
const out = [];
|
|
9151
|
+
for (const r of orderedRoots(hook)) {
|
|
9152
|
+
for (const d of [r, coordinationRoot(r)]) if (!out.includes(d)) out.push(d);
|
|
9153
|
+
}
|
|
9154
|
+
return out;
|
|
9155
|
+
}
|
|
9126
9156
|
function enforcementRoots() {
|
|
9127
9157
|
try {
|
|
9128
9158
|
const r = sessionRoot();
|
|
@@ -9383,6 +9413,19 @@ function swarmTouch(ctx, input) {
|
|
|
9383
9413
|
fail("touch", err);
|
|
9384
9414
|
}
|
|
9385
9415
|
}
|
|
9416
|
+
function workerLacksTool(input, agentType, tool) {
|
|
9417
|
+
if (!EXEC_TOOLS.has(tool) || !isSwarmAgentType(agentType)) return false;
|
|
9418
|
+
try {
|
|
9419
|
+
for (const dir of swarmRoots(input)) {
|
|
9420
|
+
const config = activeSwarmConfig(dir);
|
|
9421
|
+
const found = config && findRole(config, agentType);
|
|
9422
|
+
if (found) return !roleHasShell(found.role);
|
|
9423
|
+
}
|
|
9424
|
+
} catch (err) {
|
|
9425
|
+
fail("shell", err);
|
|
9426
|
+
}
|
|
9427
|
+
return false;
|
|
9428
|
+
}
|
|
9386
9429
|
function allowWith(updatedInput) {
|
|
9387
9430
|
return {
|
|
9388
9431
|
hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow", updatedInput }
|
|
@@ -9773,12 +9816,14 @@ export {
|
|
|
9773
9816
|
commitContext,
|
|
9774
9817
|
recallForError,
|
|
9775
9818
|
isSwarmTool,
|
|
9819
|
+
spawnType,
|
|
9776
9820
|
coordinationRoot,
|
|
9777
9821
|
swarmPreAgent,
|
|
9778
9822
|
failedText,
|
|
9779
9823
|
rawEnforced,
|
|
9780
9824
|
swarmGate,
|
|
9781
9825
|
swarmTouch,
|
|
9826
|
+
workerLacksTool,
|
|
9782
9827
|
swarmStampCaller,
|
|
9783
9828
|
swarmAgentReturned,
|
|
9784
9829
|
swarmSessionEnd,
|
|
@@ -9840,4 +9885,4 @@ queue-microtask/index.js:
|
|
|
9840
9885
|
run-parallel/index.js:
|
|
9841
9886
|
(*! run-parallel. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> *)
|
|
9842
9887
|
*/
|
|
9843
|
-
//# sourceMappingURL=hook-chunk-
|
|
9888
|
+
//# sourceMappingURL=hook-chunk-DSLVDGOB.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
init_esm_shims,
|
|
14
14
|
loadConfig,
|
|
15
15
|
paths
|
|
16
|
-
} from "./hook-chunk-
|
|
16
|
+
} from "./hook-chunk-BECSRJFD.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-
|
|
3780
|
+
//# sourceMappingURL=hook-chunk-RYZAFUTT.js.map
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
manifestPath,
|
|
9
9
|
readManifestAt,
|
|
10
10
|
resolvePrice
|
|
11
|
-
} from "./hook-chunk-
|
|
11
|
+
} from "./hook-chunk-DSLVDGOB.js";
|
|
12
12
|
import {
|
|
13
13
|
adjudicateOne,
|
|
14
14
|
briefUnitsOf,
|
|
@@ -18,17 +18,19 @@ import {
|
|
|
18
18
|
resolveAdjudicator,
|
|
19
19
|
spawnAsyncJob,
|
|
20
20
|
topIntent
|
|
21
|
-
} from "./hook-chunk-
|
|
21
|
+
} from "./hook-chunk-RYZAFUTT.js";
|
|
22
22
|
import {
|
|
23
23
|
AGENT_EFFORT_SINCE,
|
|
24
24
|
KEPT_MODEL_FLAG,
|
|
25
25
|
TIERS,
|
|
26
|
+
claudeConfigDir,
|
|
27
|
+
claudePluginsDir,
|
|
26
28
|
getContext,
|
|
27
29
|
getStorage,
|
|
28
30
|
init_esm_shims,
|
|
29
31
|
keptModel,
|
|
30
32
|
tierOf
|
|
31
|
-
} from "./hook-chunk-
|
|
33
|
+
} from "./hook-chunk-BECSRJFD.js";
|
|
32
34
|
|
|
33
35
|
// src/adjudicator/hooks.ts
|
|
34
36
|
init_esm_shims();
|
|
@@ -349,7 +351,7 @@ function projectDirs(root, cwd) {
|
|
|
349
351
|
}
|
|
350
352
|
function pluginDirs(plugin, env, home) {
|
|
351
353
|
const out = /* @__PURE__ */ new Set();
|
|
352
|
-
const pluginsRoot = env
|
|
354
|
+
const pluginsRoot = claudePluginsDir(env, home);
|
|
353
355
|
try {
|
|
354
356
|
const j = JSON.parse(readFileSync(join(pluginsRoot, "installed_plugins.json"), "utf8"));
|
|
355
357
|
for (const [key, val] of Object.entries(j?.plugins ?? {})) {
|
|
@@ -450,7 +452,7 @@ function resolveAgentPin(agentType, q) {
|
|
|
450
452
|
const scopes = [];
|
|
451
453
|
if (managed) scopes.push(["managed", join(managed, ".claude", "agents")]);
|
|
452
454
|
for (const d of projectDirs(q.root, q.cwd)) scopes.push(["project", d]);
|
|
453
|
-
scopes.push(["user", join(
|
|
455
|
+
scopes.push(["user", join(claudeConfigDir(env, home), "agents")]);
|
|
454
456
|
let truncated = false;
|
|
455
457
|
for (const [source, dir] of scopes) {
|
|
456
458
|
const found = byName(dir, agentType);
|
|
@@ -1824,4 +1826,4 @@ export {
|
|
|
1824
1826
|
withModel,
|
|
1825
1827
|
withNote
|
|
1826
1828
|
};
|
|
1827
|
-
//# sourceMappingURL=hook-hooks-
|
|
1829
|
+
//# sourceMappingURL=hook-hooks-IDTGXCFD.js.map
|