@voybio/ace-swarm 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -20
- package/assets/scripts/ace-hook-dispatch.mjs +1 -1
- package/dist/ace-server-instructions.js +2 -2
- package/dist/cli.js +7 -7
- package/dist/helpers.js +1 -1
- package/dist/store/ace-packed-store.d.ts +65 -26
- package/dist/store/ace-packed-store.js +448 -261
- package/dist/store/bootstrap-store.d.ts +1 -1
- package/dist/store/bootstrap-store.js +4 -4
- package/dist/store/catalog-builder.js +3 -3
- package/dist/store/importer.d.ts +2 -2
- package/dist/store/importer.js +2 -2
- package/dist/store/materializers/hook-context-materializer.d.ts +1 -1
- package/dist/store/materializers/hook-context-materializer.js +1 -1
- package/dist/store/materializers/host-file-materializer.js +1 -1
- package/dist/store/skills-install.d.ts +1 -1
- package/dist/store/skills-install.js +3 -3
- package/dist/store/state-reader.js +7 -12
- package/dist/store/store-artifacts.js +74 -36
- package/dist/store/store-snapshot.js +3 -3
- package/dist/store/types.d.ts +4 -2
- package/dist/store/types.js +4 -2
- package/dist/tools-framework.js +2 -2
- package/dist/tui/dashboard.d.ts +1 -1
- package/dist/tui/dashboard.js +7 -2
- package/dist/tui/index.js +10 -0
- package/package.json +4 -6
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Autonomous Coding Entity (ACE) is a local MCP server and CLI for agent-assisted coding.
|
|
4
4
|
|
|
5
|
-
`ace-swarm` gives Claude Code, Codex, Cursor, VS Code, and local-model workflows a shared runtime: durable workspace state, typed handoffs, scheduler primitives, change intelligence, and operator tooling.
|
|
5
|
+
`ace-swarm` gives Claude Code, Codex, Cursor, VS Code, and local-model workflows a shared runtime: durable workspace state, typed handoffs, scheduler primitives, change intelligence, and operator tooling. All state lives in a single binary file — `.agents/ACE/ace-state.ace` — so the workspace keeps one source of truth instead of a forest of generated state files.
|
|
6
6
|
|
|
7
7
|
Modern coding agents can already read files, write code, run commands, and call tools. The missing layer is coordination that survives restarts, model switches, and multi-agent work. ACE fills that gap by keeping the workflow in the store and projecting only the few files external clients still need. For local models, ACE provides the eyes and ears they usually lack: task context, tool surfaces, status events, evidence trails, and resumable state.
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ Modern coding agents can already read files, write code, run commands, and call
|
|
|
12
12
|
- Handoffs should be typed, evidence-linked, and validated.
|
|
13
13
|
- Shared workflow state should live in the workspace, not only in chat history.
|
|
14
14
|
- Local models should get the same structure and observability as hosted models.
|
|
15
|
-
- Bootstrap should be contained and reversible: ACE writes into `.agents/ACE/ace-state.
|
|
15
|
+
- Bootstrap should be contained and reversible: ACE writes into `.agents/ACE/ace-state.ace`.
|
|
16
16
|
|
|
17
17
|
### Serving local models
|
|
18
18
|
|
|
@@ -33,21 +33,62 @@ Frontier models are getting more capable and more restricted at the same time. P
|
|
|
33
33
|
|
|
34
34
|
ACE sits underneath that stack. It does not compete with the host you already use. It gives that host a durable local runtime.
|
|
35
35
|
|
|
36
|
-
##
|
|
36
|
+
## ACEPACK State Model
|
|
37
37
|
|
|
38
|
-
ACE uses
|
|
39
|
-
|
|
38
|
+
ACE uses a custom binary format called ACEPACK to present `.agents/ACE/ace-state.ace` as a structured single-file store. The file has three regions:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
ace-state.ace
|
|
42
|
+
├── Header (128 bytes)
|
|
43
|
+
│ magic · version · flags
|
|
44
|
+
│ kv_index_offset · kv_index_length · kv_chunk_end
|
|
45
|
+
│ evt_offset · evt_length · evt_count · evt_base_id
|
|
46
|
+
├── KV Chunk Region (append-only, random-access)
|
|
47
|
+
│ knowledge/agents/{name}/{file} → agent instruction text
|
|
48
|
+
│ knowledge/skills/{name}/{file} → skill content
|
|
49
|
+
│ topology/{kind} → swarm registry, route tables
|
|
50
|
+
│ state/{...} → handoffs, todo, ledger, scheduler
|
|
51
|
+
│ meta/{...} → schema version, project name
|
|
52
|
+
│ Each chunk: [uint32 length][bytes]
|
|
53
|
+
└── Columnar Event Section (rewritten on commit)
|
|
54
|
+
uint32 event count
|
|
55
|
+
int64[N] timestamps (epoch ms, big-endian)
|
|
56
|
+
uint8[N] kinds (EntityKind enum)
|
|
57
|
+
uint8[N] sources (ContentSource enum)
|
|
58
|
+
uint8[N] flags (0x01 = deleted)
|
|
59
|
+
uint32[N] payload offsets (→ payload pool)
|
|
60
|
+
uint32[N] payload lengths
|
|
61
|
+
uint32 pool length
|
|
62
|
+
bytes[M] payload pool (UTF-8 JSON blobs)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### KV region — random-access blob cache
|
|
66
|
+
|
|
67
|
+
All persistent state — agent instructions, skills, topology, task indexes, scheduler queues — lives in the KV region. Each key maps to an immutable chunk appended at write time. `commit()` rewrites the KV index (a small JSON map at the file tail) to reflect the live keys. `compact()` rewrites the KV region to remove dead space from overwritten keys, atomically via tmp-rename.
|
|
68
|
+
|
|
69
|
+
Write cost: O(1) append + O(index_size) index rewrite.
|
|
70
|
+
Read cost: O(1) seek + O(chunk_length) read.
|
|
71
|
+
|
|
72
|
+
### Columnar event section — typed handoff log
|
|
73
|
+
|
|
74
|
+
Every `appendEntry()` call — handoffs, status events, ledger entries, session events — lands in an in-memory buffer and is flushed to the columnar section on `commit()`. The columnar layout stores fixed-width fields (timestamp, kind, source, flags) separately from payloads. This means:
|
|
75
|
+
|
|
76
|
+
- Scanning "all handoffs in the last hour" reads only `timestamps[]` + `kinds[]` — 9 bytes per event, never touching the payload pool.
|
|
77
|
+
- Per-event overhead is ~19 bytes fixed vs ~150 bytes for equivalent JSON.
|
|
78
|
+
- At 100,000 events, the fixed columns are ~1.9 MB; a full JSON log would be ~15 MB.
|
|
79
|
+
|
|
80
|
+
Events accumulate for the workspace lifetime and survive `compact()`. Full historical replay is always available. See `HOT_COLD_EVENT_TIERING.md` for the future branch that adds compressed batch archiving for very long-lived workspaces.
|
|
40
81
|
|
|
41
82
|
### Why one state file
|
|
42
83
|
|
|
43
|
-
| One `.
|
|
84
|
+
| One `.ace` authority | What it avoids |
|
|
44
85
|
|---|---|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
86
|
+
| Single append-only file | Hundreds of generated state files drifting apart |
|
|
87
|
+
| KV region with typed keys | Hand-rolled file sprawl for runtime state, instructions, indexes |
|
|
88
|
+
| Columnar event log | Repeated full-JSON parsing for timestamp and kind scanning |
|
|
48
89
|
| Store-backed projections | External tools reading the same truth through different paths |
|
|
49
90
|
|
|
50
|
-
The store holds runtime state, agent instructions, skills, topology, schemas, and
|
|
91
|
+
The store holds runtime state, agent instructions, skills, topology, schemas, and the complete event history. Materialized files exist only when an external client still needs a path on disk.
|
|
51
92
|
|
|
52
93
|
## Quick Start
|
|
53
94
|
|
|
@@ -87,9 +128,9 @@ If you already have a local runtime running, `ace doctor --scan` will probe comm
|
|
|
87
128
|
|
|
88
129
|
## What Bootstrap Writes
|
|
89
130
|
|
|
90
|
-
ACE bootstrap is intentionally contained. The store is authoritative at `.agents/ACE/ace-state.
|
|
131
|
+
ACE bootstrap is intentionally contained. The store is authoritative at `.agents/ACE/ace-state.ace`; only a few host-facing files land in the workspace when requested.
|
|
91
132
|
|
|
92
|
-
- `.agents/ACE/ace-state.
|
|
133
|
+
- `.agents/ACE/ace-state.ace` — runtime state, agent instructions, skills, topology, schemas, and the event log
|
|
93
134
|
- `.agents/ACE/ace-hook-context.json` — compact hook snapshot for external clients
|
|
94
135
|
- `.agents/ACE/tasks/todo.md` — human-facing todo surface
|
|
95
136
|
- Optional workspace-root stubs — `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, `.github/copilot-instructions.md`, and `.vscode/mcp.json`
|
|
@@ -115,7 +156,7 @@ Developer or MCP host
|
|
|
115
156
|
|
|
|
116
157
|
+-- .agents/ACE/
|
|
117
158
|
| |
|
|
118
|
-
| +-- ace-state.
|
|
159
|
+
| +-- ace-state.ace
|
|
119
160
|
| +-- ace-hook-context.json
|
|
120
161
|
| +-- tasks/todo.md
|
|
121
162
|
| `-- host config bundles
|
|
@@ -137,13 +178,15 @@ Developer or MCP host
|
|
|
137
178
|
| Runtime roles | 17 runtime roles: 4 swarm roles + 13 composable roles |
|
|
138
179
|
| Skills | 15 packaged skills |
|
|
139
180
|
| MCP server | stdio server for tools, prompts, resources, and workflows |
|
|
140
|
-
| Durable state | single
|
|
181
|
+
| Durable state | single .ace authority for handoffs, status events, todo |
|
|
182
|
+
| | state, run ledger, job queue, and discovery |
|
|
141
183
|
| Projections | hook context, todo surface, and host configs when needed |
|
|
142
184
|
| Coordination | priority dispatch, dependency gates, leases, resource locks |
|
|
143
185
|
| Change intelligence | delta scan, semantic snapshots, drift reports, rewrite hints |
|
|
144
186
|
| Terminal UI | provider-aware TUI with chat, tabs, telemetry, agent tabs |
|
|
145
|
-
| Local models | Ollama and llama.cpp bootstrap, doctor checks, model bridge,
|
|
146
|
-
|
|
|
187
|
+
| Local models | Ollama and llama.cpp bootstrap, doctor checks, model bridge, |
|
|
188
|
+
| | tool loops |
|
|
189
|
+
| Verification | 242 tests passing in the current suite |
|
|
147
190
|
+----------------------+--------------------------------------------------------------+
|
|
148
191
|
```
|
|
149
192
|
|
|
@@ -162,7 +205,7 @@ In that setup, the host remains the interface. ACE becomes the state contract un
|
|
|
162
205
|
|
|
163
206
|
Local models are good at generating text. They usually need help seeing the workspace, hearing the handoff trail, and remembering what changed two turns ago. ACE closes that gap.
|
|
164
207
|
|
|
165
|
-
- `ace init --llm ollama` or `ace init --llm llama.cpp` seeds the profile inside `.agents/ACE/ace-state.
|
|
208
|
+
- `ace init --llm ollama` or `ace init --llm llama.cpp` seeds the profile inside `.agents/ACE/ace-state.ace`.
|
|
166
209
|
- `ace doctor` verifies that the selected runtime is reachable and configured.
|
|
167
210
|
- `ace tui` can talk to either local runtime and surface the same workspace state the MCP server sees.
|
|
168
211
|
- The ACE model bridge gives local runs tool selection, execution flow, and persisted state instead of a fragile one-shot chat loop.
|
|
@@ -199,7 +242,6 @@ If you want local agents with memory, evidence, and handoff discipline, this is
|
|
|
199
242
|
+---------------------------------------------+---------------------------------------------------+
|
|
200
243
|
```
|
|
201
244
|
|
|
202
|
-
|
|
203
245
|
## Development
|
|
204
246
|
|
|
205
247
|
```bash
|
|
@@ -216,10 +258,8 @@ See [CHANGELOG.md](./CHANGELOG.md) for release history.
|
|
|
216
258
|
|
|
217
259
|
- [Claude Code overview](https://docs.anthropic.com/en/docs/claude-code/overview)
|
|
218
260
|
- [OpenAI connectors and MCP servers](https://platform.openai.com/docs/guides/tools-remote-mcp?lang=python)
|
|
219
|
-
- [Introducing GPT-5.2-Codex](https://openai.com/index/introducing-gpt-5-2-codex/)
|
|
220
261
|
- [Ollama tool calling and agent loops](https://docs.ollama.com/capabilities/tool-calling)
|
|
221
262
|
- [llama.cpp](https://github.com/ggerganov/llama.cpp)
|
|
222
|
-
- [Zarrita.js](https://zarrita.dev/)
|
|
223
263
|
- [Model Context Protocol SDKs](https://modelcontextprotocol.io/docs/sdk)
|
|
224
264
|
|
|
225
265
|
## License
|
|
@@ -206,7 +206,7 @@ function buildRoleToolHint(role) {
|
|
|
206
206
|
* Try to read the store-materialized hook context snapshot.
|
|
207
207
|
* Returns the parsed snapshot or undefined if not present / unreadable.
|
|
208
208
|
* When present this is the single authoritative source; the dispatcher
|
|
209
|
-
* never needs to open the .
|
|
209
|
+
* never needs to open the .ace store directly.
|
|
210
210
|
*/
|
|
211
211
|
function tryReadHookContextSnapshot(workspaceRoot) {
|
|
212
212
|
const snapshotPath = resolve(workspaceRoot, ACE_ROOT, "ace-hook-context.json");
|
|
@@ -187,7 +187,7 @@ export function buildHostInstructionText(host, workspaceRoot) {
|
|
|
187
187
|
`# ACE Bootstrap For ${hostLabel}`,
|
|
188
188
|
"",
|
|
189
189
|
"This is a thin ACE bootstrap stub.",
|
|
190
|
-
"Full instructions, skills, task packs, and runtime state live inside `.agents/ACE/ace-state.
|
|
190
|
+
"Full instructions, skills, task packs, and runtime state live inside `.agents/ACE/ace-state.ace` and should be accessed through the ACE MCP server.",
|
|
191
191
|
"",
|
|
192
192
|
"Session start protocol:",
|
|
193
193
|
"1. Call `recall_context` to load task, scope, and status from ACE state.",
|
|
@@ -195,7 +195,7 @@ export function buildHostInstructionText(host, workspaceRoot) {
|
|
|
195
195
|
"3. Prefer ACE prompts/resources (`ace-orchestrator`, `get_task_pack`, `get_skill_instructions`) over relying on this file.",
|
|
196
196
|
"",
|
|
197
197
|
"Ground truth:",
|
|
198
|
-
"- `.agents/ACE/ace-state.
|
|
198
|
+
"- `.agents/ACE/ace-state.ace` is authoritative.",
|
|
199
199
|
"- `.agents/ACE/tasks/todo.md` is the human-facing todo surface.",
|
|
200
200
|
"- `.agents/ACE/ace-hook-context.json` is the compact hook snapshot.",
|
|
201
201
|
"",
|
package/dist/cli.js
CHANGED
|
@@ -33,7 +33,7 @@ Options for tui:
|
|
|
33
33
|
--ollama-url <url> Legacy alias for --base-url
|
|
34
34
|
|
|
35
35
|
Options for init:
|
|
36
|
-
--project <name> Project name stored in ${ACE_ROOT_REL}/ace-state.
|
|
36
|
+
--project <name> Project name stored in ${ACE_ROOT_REL}/ace-state.ace metadata
|
|
37
37
|
--force Overwrite scaffolded files if they already exist
|
|
38
38
|
--mcp-config Also write .vscode/mcp.json workspace bridge
|
|
39
39
|
--client-config-bundle Also write minimal workspace host stubs (AGENTS.md, CLAUDE.md, .cursorrules, .github/copilot-instructions.md)
|
|
@@ -43,7 +43,7 @@ Options for init:
|
|
|
43
43
|
--ollama-url <url> Legacy alias for --base-url
|
|
44
44
|
|
|
45
45
|
Options for doctor:
|
|
46
|
-
--llm <provider> ollama|llama.cpp (default: auto from ${ACE_ROOT_REL}/ace-state.
|
|
46
|
+
--llm <provider> ollama|llama.cpp (default: auto from ${ACE_ROOT_REL}/ace-state.ace)
|
|
47
47
|
--model <name> Model name override
|
|
48
48
|
--base-url <url> Local runtime base URL override
|
|
49
49
|
--ollama-url <url> Legacy alias for --base-url
|
|
@@ -224,7 +224,7 @@ async function runInit(args, mode = "init") {
|
|
|
224
224
|
message: `ace ${mode} completed: ${storeResult.materialized.length} bootstrap files materialized`,
|
|
225
225
|
artifacts: [
|
|
226
226
|
`${ACE_TASKS_ROOT_REL}/`,
|
|
227
|
-
`${ACE_ROOT_REL}/ace-state.
|
|
227
|
+
`${ACE_ROOT_REL}/ace-state.ace`,
|
|
228
228
|
delta.index_path,
|
|
229
229
|
astIndex.output_json_path,
|
|
230
230
|
],
|
|
@@ -302,7 +302,7 @@ async function runDoctor(args) {
|
|
|
302
302
|
detail: hasMcpConfig
|
|
303
303
|
? hasWorkspaceMcpConfig
|
|
304
304
|
? "Found one or more workspace MCP bridge files."
|
|
305
|
-
: "Store-backed MCP snippets are baked into ace-state.
|
|
305
|
+
: "Store-backed MCP snippets are baked into ace-state.ace. Run `ace mcp-config --all` for global install."
|
|
306
306
|
: "No MCP bridge or baked snippets found. Run `ace init` first.",
|
|
307
307
|
});
|
|
308
308
|
const profilePath = `${getWorkspaceStorePath(WORKSPACE_ROOT)}#state/runtime/llm_profile`;
|
|
@@ -312,7 +312,7 @@ async function runDoctor(args) {
|
|
|
312
312
|
ok: hasProfile,
|
|
313
313
|
detail: hasProfile
|
|
314
314
|
? profilePath
|
|
315
|
-
: `Missing ${ACE_ROOT_REL}/ace-state.
|
|
315
|
+
: `Missing ${ACE_ROOT_REL}/ace-state.ace#state/runtime/llm_profile. Run \`ace init --llm ollama\` or \`ace doctor --scan\`.`,
|
|
316
316
|
});
|
|
317
317
|
let provider = llm.llmProvider;
|
|
318
318
|
let model = llm.llmModel;
|
|
@@ -354,7 +354,7 @@ async function runDoctor(args) {
|
|
|
354
354
|
}
|
|
355
355
|
}
|
|
356
356
|
if (!provider) {
|
|
357
|
-
throw new Error(`No local runtime provider configured. Use --llm <provider>, bootstrap one into ${ACE_ROOT_REL}/ace-state.
|
|
357
|
+
throw new Error(`No local runtime provider configured. Use --llm <provider>, bootstrap one into ${ACE_ROOT_REL}/ace-state.ace#state/runtime/llm_profile, or run \`ace doctor --scan\`.`);
|
|
358
358
|
}
|
|
359
359
|
if (!model) {
|
|
360
360
|
model = provider === "llama.cpp" ? DEFAULT_LLAMA_CPP_MODEL : DEFAULT_OLLAMA_MODEL;
|
|
@@ -540,7 +540,7 @@ async function main() {
|
|
|
540
540
|
}
|
|
541
541
|
if (command === "migrate") {
|
|
542
542
|
const { importFromFileWorkspace } = await import("./store/importer.js");
|
|
543
|
-
const storePath = args[1] ?? `${WORKSPACE_ROOT}/.agents/ACE/ace-state.
|
|
543
|
+
const storePath = args[1] ?? `${WORKSPACE_ROOT}/.agents/ACE/ace-state.ace`;
|
|
544
544
|
console.log(`Migrating file workspace at ${WORKSPACE_ROOT} to store at ${storePath}...`);
|
|
545
545
|
const result = await importFromFileWorkspace(WORKSPACE_ROOT, storePath);
|
|
546
546
|
console.log(`Migration complete:`);
|
package/dist/helpers.js
CHANGED
|
@@ -530,7 +530,7 @@ export function classifyPathSource(path) {
|
|
|
530
530
|
if (!path)
|
|
531
531
|
return "missing";
|
|
532
532
|
const root = currentWorkspaceRoot();
|
|
533
|
-
if (path.includes(".
|
|
533
|
+
if (path.includes(".ace#"))
|
|
534
534
|
return "store";
|
|
535
535
|
if (isInside(root, path))
|
|
536
536
|
return "workspace";
|
|
@@ -1,42 +1,81 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AcePackedStore
|
|
2
|
+
* AcePackedStore — ACEPACK v2
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Single-file binary store. One file, no subdirectories, no companion files.
|
|
5
|
+
* Events grow in the columnar section indefinitely (Option A). compact() only
|
|
6
|
+
* reclaims dead space in the KV chunk region — it does NOT reset or archive
|
|
7
|
+
* events. Historical event replay across all past runs is always available.
|
|
6
8
|
*
|
|
7
|
-
* File
|
|
8
|
-
* [ Header 64 bytes ] magic(8) version(4) flags(4) index_offset(8) index_length(8) reserved(32)
|
|
9
|
-
* [ Chunk region ] chunk_0: [uint32 length][bytes] ... chunk_N: [uint32 length][bytes]
|
|
10
|
-
* [ Index region ] UTF-8 JSON: { key → { offset, length } }
|
|
9
|
+
* File layout:
|
|
11
10
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
11
|
+
* ┌─────────────────────────────────────────────────────────┐
|
|
12
|
+
* │ Header (128 bytes, big-endian) │
|
|
13
|
+
* │ magic "ACEPACK\0" · version uint32 · flags uint32 │
|
|
14
|
+
* │ kv_index_offset uint64 · kv_index_length uint64 │
|
|
15
|
+
* │ kv_chunk_end uint64 │
|
|
16
|
+
* │ evt_offset uint64 · evt_length uint64 │
|
|
17
|
+
* │ evt_count uint32 · evt_base_id uint32 │
|
|
18
|
+
* │ reserved (zeros) │
|
|
19
|
+
* ├─────────────────────────────────────────────────────────┤
|
|
20
|
+
* │ KV Chunk Region (append-only, random-access) │
|
|
21
|
+
* │ knowledge/agents/{name}/{file} → instruction text │
|
|
22
|
+
* │ knowledge/skills/{name}/{file} → skill content │
|
|
23
|
+
* │ topology/{kind} → JSON array │
|
|
24
|
+
* │ state/{...} → runtime state blobs │
|
|
25
|
+
* │ meta/{...} → schema version etc. │
|
|
26
|
+
* │ Each chunk: [uint32 length BE][bytes] │
|
|
27
|
+
* ├─────────────────────────────────────────────────────────┤
|
|
28
|
+
* │ Columnar Event Section (rewritten on every commit) │
|
|
29
|
+
* │ uint32 count │
|
|
30
|
+
* │ int64[N] timestamps (epoch ms, big-endian) │
|
|
31
|
+
* │ uint8[N] kinds (EntityKind enum) │
|
|
32
|
+
* │ uint8[N] sources (ContentSource enum) │
|
|
33
|
+
* │ uint8[N] flags (0x01=deleted) │
|
|
34
|
+
* │ [pad to 4-byte alignment] │
|
|
35
|
+
* │ uint32[N] pay_offsets (relative to pool start) │
|
|
36
|
+
* │ uint32[N] pay_lengths │
|
|
37
|
+
* │ uint32 pool_length │
|
|
38
|
+
* │ bytes[M] payload pool (UTF-8 JSON: {key,payload,...})│
|
|
39
|
+
* ├─────────────────────────────────────────────────────────┤
|
|
40
|
+
* │ KV Index (JSON, rewritten on commit) │
|
|
41
|
+
* │ { "knowledge/agents/ace-ops/AGENT.md": {offset, length}, ... }
|
|
42
|
+
* └─────────────────────────────────────────────────────────┘
|
|
16
43
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
44
|
+
* Event overhead: ~19 bytes fixed + payload (vs ~150 bytes full JSON).
|
|
45
|
+
* Timestamp/kind scanning reads only the fixed-width columns, never the pool.
|
|
19
46
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
47
|
+
* compact() removes dead KV space (overwritten keys) via atomic tmp-rename.
|
|
48
|
+
* Events are preserved across compact() — they accumulate for the workspace
|
|
49
|
+
* lifetime. See HOT_COLD_EVENT_TIERING.md for a future branch that adds
|
|
50
|
+
* BGZF batch archiving for very long-lived workspaces.
|
|
51
|
+
*
|
|
52
|
+
* Backward compat: v1 files (64-byte header) are migrated on first commit().
|
|
53
|
+
* v1 events live in core/log/ KV blobs and are pulled into the columnar section.
|
|
23
54
|
*/
|
|
24
55
|
import { IAcePackedStore, UnifiedEntry, EntryFilter, TopologyEntry, ContentSourceCode } from "./types.js";
|
|
25
56
|
export declare class AcePackedStore implements IAcePackedStore {
|
|
26
57
|
private storePath;
|
|
27
|
-
private lockPath;
|
|
28
58
|
private readOnly;
|
|
29
|
-
private index;
|
|
30
|
-
private chunkEnd;
|
|
31
59
|
private fh;
|
|
32
|
-
private
|
|
33
|
-
private
|
|
60
|
+
private kvIndex;
|
|
61
|
+
private kvChunkEnd;
|
|
62
|
+
private committed;
|
|
63
|
+
private pending;
|
|
64
|
+
private evtBaseId;
|
|
34
65
|
open(path: string, opts?: {
|
|
35
66
|
readOnly?: boolean;
|
|
36
67
|
}): Promise<void>;
|
|
37
|
-
private
|
|
38
|
-
private
|
|
68
|
+
private _initNew;
|
|
69
|
+
private _loadExisting;
|
|
70
|
+
/** Read a KV blob directly from a loaded file buffer (used during migration). */
|
|
71
|
+
private _readKvBlobDirect;
|
|
39
72
|
commit(): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Compacts the KV chunk region — removes dead space left by overwritten keys.
|
|
75
|
+
* Events are NOT reset or archived; they accumulate in the columnar section
|
|
76
|
+
* for the workspace lifetime (Option A — grow forever).
|
|
77
|
+
* See HOT_COLD_EVENT_TIERING.md for the future branch that adds BGZF archiving.
|
|
78
|
+
*/
|
|
40
79
|
compact(): Promise<void>;
|
|
41
80
|
close(): Promise<void>;
|
|
42
81
|
get(key: string): Promise<Uint8Array | undefined>;
|
|
@@ -49,7 +88,7 @@ export declare class AcePackedStore implements IAcePackedStore {
|
|
|
49
88
|
setBlob(key: string, content: string): Promise<void>;
|
|
50
89
|
appendEntry(entry: Omit<UnifiedEntry, "id" | "ts">): Promise<UnifiedEntry>;
|
|
51
90
|
getEntries(filter?: EntryFilter): Promise<UnifiedEntry[]>;
|
|
52
|
-
getEntry(
|
|
91
|
+
getEntry(_key: string): Promise<UnifiedEntry | undefined>;
|
|
53
92
|
getTopology(kind: string): Promise<TopologyEntry[]>;
|
|
54
93
|
setTopology(kind: string, entries: TopologyEntry[]): Promise<void>;
|
|
55
94
|
getAgentInstruction(agent: string, file: string): Promise<string | undefined>;
|
|
@@ -58,9 +97,9 @@ export declare class AcePackedStore implements IAcePackedStore {
|
|
|
58
97
|
getSkillContent(skill: string, file: string): Promise<string | undefined>;
|
|
59
98
|
setSkillContent(skill: string, file: string, content: string, source?: ContentSourceCode): Promise<void>;
|
|
60
99
|
listSkills(): Promise<string[]>;
|
|
61
|
-
/** Dead space ratio
|
|
100
|
+
/** Dead space ratio in the KV chunk region. Used to decide if compaction is needed. */
|
|
62
101
|
get deadSpaceRatio(): number;
|
|
63
|
-
/**
|
|
102
|
+
/** Total events in log (committed + pending). */
|
|
64
103
|
get entryCount(): number;
|
|
65
104
|
}
|
|
66
105
|
export declare function openStore(storePath: string, opts?: {
|