@voybio/ace-swarm 2.4.6 → 2.4.8
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/README.md +4 -0
- package/assets/logo/ace-logo.png +0 -0
- package/dist/ace-server-instructions.js +17 -3
- package/dist/cli.js +12 -4
- package/dist/server.d.ts +14 -3
- package/dist/server.js +14 -3
- package/dist/tools-files.js +31 -7
- package/docs/cli-reference.md +2 -0
- package/docs/state-model.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
Binary file
|
|
@@ -31,6 +31,13 @@ const REFRESH_TOOLS = new Set([
|
|
|
31
31
|
// New mutation tools with non-standard prefixes must be added here explicitly.
|
|
32
32
|
const NAMED_MUTATION_TOOLS = new Set([
|
|
33
33
|
"rewrite_targets",
|
|
34
|
+
"apply_patch",
|
|
35
|
+
"astgrep_rewrite",
|
|
36
|
+
"reap_stale_jobs",
|
|
37
|
+
"heartbeat_job",
|
|
38
|
+
"generate_kanban_ui",
|
|
39
|
+
"codemunch_snapshot",
|
|
40
|
+
"codemunch_index",
|
|
34
41
|
]);
|
|
35
42
|
const MUTATION_PREFIXES = [
|
|
36
43
|
"ack_",
|
|
@@ -207,15 +214,19 @@ export function buildServerInstructions(workspaceRoot) {
|
|
|
207
214
|
const lines = [
|
|
208
215
|
"You are operating in an ACE-governed workspace.",
|
|
209
216
|
coreFiles.length > 0
|
|
210
|
-
? `Ground truth
|
|
211
|
-
: `Ground truth
|
|
217
|
+
? `Ground truth for task/status/scope/evidence is store-backed under ${coreFiles.join(", ")} (canonical store: ${ACE_ROOT_REL}/agent-state/ace-state.ace).`
|
|
218
|
+
: `Ground truth is store-backed under ${ACE_ROOT_REL}/agent-state/* artifacts (canonical store: ${ACE_ROOT_REL}/agent-state/ace-state.ace), not chat history.`,
|
|
219
|
+
"`ace compact` and the automatic lifecycle sweep intentionally remove loose agent-state/* files from disk after folding them into the store — this is expected, not data loss, and applies to every swept artifact (kanban, run-ledger, handoffs, playbook, tracker snapshots, etc.), not only TASK/STATUS/SCOPE/EVIDENCE_LOG. If a path is not on disk, call list_workspace on its directory to see the full store-backed listing (or `ace ls` from the CLI), then read it back with read_workspace_file (or `ace read <path>`); never recreate swept files.",
|
|
212
220
|
stateDirs.length > 0
|
|
213
|
-
? `Durable artifacts belong under ${stateDirs.map((entry) => `${entry}/`).join(", ")}.`
|
|
221
|
+
? `Durable artifacts belong under ${stateDirs.map((entry) => `${entry}/`).join(", ")} and are persisted into the store; the loose copies are sweep inputs, not the source of truth.`
|
|
214
222
|
: undefined,
|
|
215
223
|
"Before significant work, call recall_context to load current task, scope, and status.",
|
|
216
224
|
"Use route_task and get_agent_instructions for role guidance; do not self-assign by guesswork.",
|
|
217
225
|
"After meaningful edits or state changes, call execute_gates and persist evidence/handoffs in ACE artifacts.",
|
|
218
226
|
"For delegated or long-running work, use create_handoff / ack_handoff and append_vericify_process_post instead of ad-hoc status notes.",
|
|
227
|
+
"For self-paced, evidence-gated multi-step objectives beyond this session, use start_goal / get_goal_status / resume_goal / stop_goal (or `ace goal` from the CLI).",
|
|
228
|
+
"Prefer the matching MCP tool over ad-hoc shell/chat tracking: git_status / git_diff / git_log / git_commit for git; enqueue_job / dispatch_jobs / heartbeat_job / get_lock_table for background jobs; snapshot_state / semantic_diff / drift_report / rewrite_targets for change intelligence.",
|
|
229
|
+
"skill_catalog_summary / skill_audit / problem_triage surface packaged skills; get_todo / update_todo / get_run_ledger is the human-facing todo surface; scan_workspace_delta / web_research_packet / codemunch_snapshot / codemunch_index cover workspace-wide search and indexing.",
|
|
219
230
|
`Current ACE digest: ${digest}.`,
|
|
220
231
|
autonomyHint ? `Runtime autonomy signals: ${autonomyHint}.` : undefined,
|
|
221
232
|
];
|
|
@@ -239,10 +250,13 @@ export function buildHostInstructionText(host, workspaceRoot) {
|
|
|
239
250
|
"2. Call `route_task` and `get_agent_instructions` before choosing a role.",
|
|
240
251
|
"3. Prefer ACE prompts/resources (`ace-orchestrator`, `get_task_pack`, `get_skill_instructions`) over relying on this file.",
|
|
241
252
|
"4. Read/write task state through MCP tools (`recall_context`, `read_workspace_file`, `write_workspace_file`, lifecycle append tools); do not create files under `agent-state/` directly.",
|
|
253
|
+
"5. For self-paced, evidence-gated multi-step objectives beyond this session, use `start_goal` / `get_goal_status` / `resume_goal` / `stop_goal` (or `ace goal` from the CLI).",
|
|
254
|
+
"6. Also prefer the matching MCP domain over ad-hoc equivalents for git, background jobs/scheduler, change intelligence, discovery/indexing, skills, and todo — see docs/mcp-tool-reference.md for the full per-domain tool catalog.",
|
|
242
255
|
"",
|
|
243
256
|
"Ground truth:",
|
|
244
257
|
"- ACE MCP tools are the authoritative interface for task state and lifecycle updates.",
|
|
245
258
|
"- `agent-state/ace-state.ace` is the canonical store path; visible `agent-state/*` files are compatibility projections or sweep inputs.",
|
|
259
|
+
"- `ace compact` and the automatic lifecycle sweep intentionally remove loose `agent-state/*` files from disk after folding them into the store — this is expected, not data loss, for any swept artifact. Do NOT recreate them; if a path isn't on disk, call `list_workspace` on its directory (or `ace ls`) to see the full store-backed listing, then retrieve it via `ace read <path>` or the `read_workspace_file` / `recall_context` MCP tools.",
|
|
246
260
|
"- `.agents/ACE/tasks/todo.md` is the human-facing todo surface.",
|
|
247
261
|
"- Hook context is store-backed in `agent-state/ace-state.ace` and consumed without extra workspace projections.",
|
|
248
262
|
"",
|
package/dist/cli.js
CHANGED
|
@@ -98,8 +98,13 @@ Options for turnkey:
|
|
|
98
98
|
Options for mcp:
|
|
99
99
|
--profile <host-min|full> Select the visible tool schema (default: full)
|
|
100
100
|
|
|
101
|
-
Options for playbook
|
|
102
|
-
--
|
|
101
|
+
Options for playbook:
|
|
102
|
+
list [--section <s>] [--status <s>] List playbook bullets (default subcommand)
|
|
103
|
+
show <id> Show one bullet as JSON
|
|
104
|
+
add --content <text> [--section <s>] Add a bullet
|
|
105
|
+
[--reason-code <code>] Scope the lesson to a matching failure reason code
|
|
106
|
+
tag <id> helpful|harmful Curate a bullet's helpful/harmful tag
|
|
107
|
+
gc Prune and quarantine curated bullets
|
|
103
108
|
|
|
104
109
|
Options for eval:
|
|
105
110
|
--model, --models <csv> Model name or comma-separated model names (required)
|
|
@@ -1696,7 +1701,10 @@ async function main() {
|
|
|
1696
1701
|
const savedKb = Math.round((result.before - result.after) / 1024);
|
|
1697
1702
|
console.log(`Store compacted: ${result.before} → ${result.after} bytes (saved ${savedKb}KB)`);
|
|
1698
1703
|
if (result.sweep) {
|
|
1699
|
-
console.log(`Sweep:
|
|
1704
|
+
console.log(`Sweep: folded ${result.sweep.cached_files} artifact(s) into the store, freed ${result.sweep.removed_files} loose file(s) from disk, semantic GC removed ${result.sweep.removed_semantic_cache_files}`);
|
|
1705
|
+
if (result.sweep.removed_files > 0) {
|
|
1706
|
+
console.log(" Swept files are stored, not lost — read them back with `ace read <path>` (e.g. `ace read agent-state/TASK.md`). Do not recreate them.");
|
|
1707
|
+
}
|
|
1700
1708
|
}
|
|
1701
1709
|
return;
|
|
1702
1710
|
}
|
|
@@ -1739,7 +1747,7 @@ async function main() {
|
|
|
1739
1747
|
console.log(`Cached files: ${result.cached_files}`);
|
|
1740
1748
|
console.log(`Kept projected files: ${result.kept_projected_files}`);
|
|
1741
1749
|
console.log(`Skipped files: ${result.skipped_files}`);
|
|
1742
|
-
console.log(`Removed files: ${result.removed_files}`);
|
|
1750
|
+
console.log(`Removed files: ${result.removed_files} (folded into the store, not lost — read back with \`ace read <path>\`; do not recreate)`);
|
|
1743
1751
|
console.log(`Semantic cache GC removed files: ${result.removed_semantic_cache_files}`);
|
|
1744
1752
|
console.log(`Staging GC removed entries: ${stagingGc.removed_entries}`);
|
|
1745
1753
|
if (result.warnings.length > 0) {
|
package/dist/server.d.ts
CHANGED
|
@@ -11,9 +11,20 @@ export declare function createAceServer(options?: CreateAceServerOptions): McpSe
|
|
|
11
11
|
export type AceHostProfile = "host-min" | "full";
|
|
12
12
|
/**
|
|
13
13
|
* Curated premium-host surface (report WS-G). ~15–25 high-value tools instead of the
|
|
14
|
-
* full tool surface, cutting the per-session schema tax.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* full tool surface, cutting the per-session schema tax. `run_orchestrator` only reaches an
|
|
15
|
+
* omitted tool if the model-bridge child it spawns happens to have that tool in its own MCP
|
|
16
|
+
* session — it is a role/plan dispatcher, not a generic proxy for any omitted tool by name.
|
|
17
|
+
* The reliable way to reach anything below is to start with `--profile full`.
|
|
18
|
+
*
|
|
19
|
+
* Whole domains are intentionally absent, not just individual tools: goal-engine
|
|
20
|
+
* (start_goal/get_goal_status/resume_goal/stop_goal — until WS-F ships), git
|
|
21
|
+
* (git_status/git_diff/git_log/git_commit), scheduler (enqueue_job/dispatch_jobs/
|
|
22
|
+
* heartbeat_job/reap_stale_jobs/get_lock_table/…), drift/change-intelligence
|
|
23
|
+
* (snapshot_state/semantic_diff/drift_report/rewrite_targets/list_snapshots), discovery
|
|
24
|
+
* (scan_workspace_delta/web_research_packet/codemunch_snapshot/codemunch_index/
|
|
25
|
+
* mcp_ingestion_probe/refresh_astgrep_index), skills (skill_catalog_summary/skill_audit/
|
|
26
|
+
* problem_triage), and todo (get_todo/update_todo/get_run_ledger) all have zero
|
|
27
|
+
* representation below.
|
|
17
28
|
*/
|
|
18
29
|
export declare const HOST_MIN_TOOL_PROFILE: readonly string[];
|
|
19
30
|
export declare function resolveHostProfileAllowlist(profile: AceHostProfile): readonly string[] | undefined;
|
package/dist/server.js
CHANGED
|
@@ -94,9 +94,20 @@ async function verifyMcpStoreStartup(workspaceRoot, logStartup) {
|
|
|
94
94
|
}
|
|
95
95
|
/**
|
|
96
96
|
* Curated premium-host surface (report WS-G). ~15–25 high-value tools instead of the
|
|
97
|
-
* full tool surface, cutting the per-session schema tax.
|
|
98
|
-
*
|
|
99
|
-
*
|
|
97
|
+
* full tool surface, cutting the per-session schema tax. `run_orchestrator` only reaches an
|
|
98
|
+
* omitted tool if the model-bridge child it spawns happens to have that tool in its own MCP
|
|
99
|
+
* session — it is a role/plan dispatcher, not a generic proxy for any omitted tool by name.
|
|
100
|
+
* The reliable way to reach anything below is to start with `--profile full`.
|
|
101
|
+
*
|
|
102
|
+
* Whole domains are intentionally absent, not just individual tools: goal-engine
|
|
103
|
+
* (start_goal/get_goal_status/resume_goal/stop_goal — until WS-F ships), git
|
|
104
|
+
* (git_status/git_diff/git_log/git_commit), scheduler (enqueue_job/dispatch_jobs/
|
|
105
|
+
* heartbeat_job/reap_stale_jobs/get_lock_table/…), drift/change-intelligence
|
|
106
|
+
* (snapshot_state/semantic_diff/drift_report/rewrite_targets/list_snapshots), discovery
|
|
107
|
+
* (scan_workspace_delta/web_research_packet/codemunch_snapshot/codemunch_index/
|
|
108
|
+
* mcp_ingestion_probe/refresh_astgrep_index), skills (skill_catalog_summary/skill_audit/
|
|
109
|
+
* problem_triage), and todo (get_todo/update_todo/get_run_ledger) all have zero
|
|
110
|
+
* representation below.
|
|
100
111
|
*/
|
|
101
112
|
export const HOST_MIN_TOOL_PROFILE = [
|
|
102
113
|
"recall_context",
|
package/dist/tools-files.js
CHANGED
|
@@ -17,7 +17,8 @@ import { safeEditFile, diffContents, applyPatch } from "./safe-edit.js";
|
|
|
17
17
|
import { detectAstgrepCommand, flattenMetaVariables, locateAstgrepMatches, runAstgrepQuery, } from "./astgrep-index.js";
|
|
18
18
|
import { readRuntimeProfile, resolveEffectiveSurgicalReadBudget, validateRuntimeProfileContent, } from "./runtime-profile.js";
|
|
19
19
|
import { withLocalModelRuntimeRepository } from "./store/repositories/local-model-runtime-repository.js";
|
|
20
|
-
import { listStoreKeysSync } from "./store/store-snapshot.js";
|
|
20
|
+
import { getWorkspaceStorePath, listStoreKeysSync } from "./store/store-snapshot.js";
|
|
21
|
+
import { listStoreEntries } from "./store/store-cli.js";
|
|
21
22
|
function reasonCodeFromError(error) {
|
|
22
23
|
return typeof error === "object" && error !== null && "reason_code" in error
|
|
23
24
|
? String(error.reason_code)
|
|
@@ -1092,7 +1093,7 @@ export function registerFileTools(server) {
|
|
|
1092
1093
|
],
|
|
1093
1094
|
};
|
|
1094
1095
|
});
|
|
1095
|
-
server.tool("list_workspace", "List files/directories in a workspace path", {
|
|
1096
|
+
server.tool("list_workspace", "List files/directories in a workspace path, plus any ACEPACK store-only artifacts under it (content the lifecycle sweep folded into the store and removed from disk). Store-only entries are flat logical paths, not directory entries; read them back with read_workspace_file.", {
|
|
1096
1097
|
path: z
|
|
1097
1098
|
.string()
|
|
1098
1099
|
.optional()
|
|
@@ -1110,24 +1111,47 @@ export function registerFileTools(server) {
|
|
|
1110
1111
|
],
|
|
1111
1112
|
};
|
|
1112
1113
|
}
|
|
1114
|
+
const diskNames = new Set();
|
|
1115
|
+
let diskSection;
|
|
1116
|
+
let diskError;
|
|
1113
1117
|
try {
|
|
1114
|
-
const
|
|
1118
|
+
const diskEntries = readdirSync(dir, { withFileTypes: true });
|
|
1119
|
+
for (const entry of diskEntries)
|
|
1120
|
+
diskNames.add(entry.name);
|
|
1121
|
+
diskSection = diskEntries
|
|
1115
1122
|
.map((entry) => `${entry.isDirectory() ? "[DIR]" : "[FILE]"} ${entry.name}`)
|
|
1116
1123
|
.join("\n");
|
|
1117
|
-
return {
|
|
1118
|
-
content: [{ type: "text", text: `# ${dir}\n\n${entries}` }],
|
|
1119
|
-
};
|
|
1120
1124
|
}
|
|
1121
1125
|
catch (err) {
|
|
1126
|
+
diskError = String(err);
|
|
1127
|
+
}
|
|
1128
|
+
const storePrefix = normalizeRelPath(rel);
|
|
1129
|
+
let storeSection;
|
|
1130
|
+
if (existsSync(getWorkspaceStorePath(WORKSPACE_ROOT))) {
|
|
1131
|
+
const storeOnly = listStoreEntries(WORKSPACE_ROOT, storePrefix).filter((entry) => !diskNames.has(entry.path.slice(storePrefix.length).replace(/^\//, "").split("/")[0]));
|
|
1132
|
+
if (storeOnly.length > 0) {
|
|
1133
|
+
storeSection = storeOnly
|
|
1134
|
+
.map((entry) => `[STORE] ${entry.path} (${entry.bytes}B)`)
|
|
1135
|
+
.join("\n");
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
if (diskError && !storeSection) {
|
|
1122
1139
|
return {
|
|
1123
1140
|
content: [
|
|
1124
1141
|
{
|
|
1125
1142
|
type: "text",
|
|
1126
|
-
text: `❌ Could not list ${dir}\n${
|
|
1143
|
+
text: `❌ Could not list ${dir}\n${diskError}`,
|
|
1127
1144
|
},
|
|
1128
1145
|
],
|
|
1129
1146
|
};
|
|
1130
1147
|
}
|
|
1148
|
+
const sections = [
|
|
1149
|
+
diskError ? `(no such disk directory: ${diskError})` : diskSection || "(empty)",
|
|
1150
|
+
storeSection ? `\nStore-only (not on disk):\n${storeSection}` : undefined,
|
|
1151
|
+
].filter(Boolean);
|
|
1152
|
+
return {
|
|
1153
|
+
content: [{ type: "text", text: `# ${dir}\n\n${sections.join("\n")}` }],
|
|
1154
|
+
};
|
|
1131
1155
|
});
|
|
1132
1156
|
// ── Safe-edit (new P0 tool) ───────────────────────────────────────
|
|
1133
1157
|
server.tool("safe_edit_file", "Edit a file using copy→validate→swap pattern. Automatically rolls back if validation or tests fail. Prefer apply_patch for small targeted edits. Cost: heavy for large files.", {
|
package/docs/cli-reference.md
CHANGED
|
@@ -73,6 +73,8 @@ ACE_HERMES_ROOT=/path/to/hermes-agent HERMES_PYTHON=/path/to/python \
|
|
|
73
73
|
ace tui --provider llama.cpp --base-url http://localhost:8080 --model gemma-3-4b-it --hermes
|
|
74
74
|
|
|
75
75
|
# Compact the store and sweep loose generated artifacts
|
|
76
|
+
# (the sweep removes loose agent-state/*.md from disk on purpose after storing
|
|
77
|
+
# them — not data loss; read them back with `ace read <path>`, don't recreate)
|
|
76
78
|
ace compact
|
|
77
79
|
ace compact --no-sweep
|
|
78
80
|
|
package/docs/state-model.md
CHANGED
|
@@ -88,7 +88,7 @@ ace compact --no-sweep # store rewrite only
|
|
|
88
88
|
ace compact # store rewrite plus loose generated-artifact sweep
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
The default command runs a sweep after compaction: eligible loose generated ACE artifacts are ingested into the store and removed from disk. Use `--no-sweep` when only the container rewrite is intended. Back up the store and active goal directory before maintenance on a critical workspace.
|
|
91
|
+
The default command runs a sweep after compaction: eligible loose generated ACE artifacts are ingested into the store and removed from disk. This removal is by design and is not data loss — the content lives in the store and is read back with `ace read <path>` (e.g. `ace read agent-state/TASK.md`) or the `read_workspace_file` / `recall_context` MCP tools. Agents should not recreate swept files. The same sweep also runs automatically on a lifecycle cadence (silently, with a short min-age guard), so loose `agent-state/*` files disappearing between sessions is expected. Use `--no-sweep` when only the container rewrite is intended. Back up the store and active goal directory before maintenance on a critical workspace.
|
|
92
92
|
|
|
93
93
|
### Repair
|
|
94
94
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voybio/ace-swarm",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.8",
|
|
4
4
|
"description": "ACE Framework MCP server and CLI — single-file ACEPACK state, local-model serving, agent orchestration, and host compliance enforcement.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|