@voybio/ace-swarm 2.4.8 → 2.4.10
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/CHANGELOG.md +52 -14
- package/README.md +14 -10
- package/assets/.agents/ACE/ACE_coders/AGENTS.md +23 -30
- package/assets/.agents/ACE/ACE_coders/INSTRUCTIONS.md +21 -30
- package/assets/.agents/skills/landing-review-watcher/SKILL.md +1 -1
- package/assets/.agents/skills/learn-from-work/SKILL.md +41 -0
- package/assets/agent-state/ACE_WORKFLOW.md +25 -2
- package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +143 -2
- package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +2 -2
- package/assets/agent-state/MODULES/schemas/SWARM_HANDOFF.schema.json +10 -0
- package/assets/eval-battery/battery.json +1 -1
- package/assets/instructions/ACE_Coder.instructions.md +9 -13
- package/assets/scripts/ace-hook-dispatch.mjs +16 -411
- package/assets/tasks/SWARM_HANDOFF.example_ui_to_coders.json +1 -2
- package/assets/vendor/README.md +9 -0
- package/assets/vendor/vericify-reader.mjs +272 -0
- package/assets/vendor/vericify-reader.provenance.json +10 -0
- package/dist/ace-autonomy.d.ts +58 -0
- package/dist/ace-autonomy.js +211 -6
- package/dist/ace-internal-tools.d.ts +1 -0
- package/dist/ace-internal-tools.js +3 -3
- package/dist/ace-server-instructions.d.ts +3 -3
- package/dist/ace-server-instructions.js +46 -192
- package/dist/cli.js +44 -6
- package/dist/experience-reflector.d.ts +7 -0
- package/dist/experience-reflector.js +39 -0
- package/dist/goal-engine.d.ts +64 -7
- package/dist/goal-engine.js +197 -41
- package/dist/handoff-registry.d.ts +10 -0
- package/dist/handoff-registry.js +59 -0
- package/dist/helpers/artifacts.d.ts +6 -2
- package/dist/helpers/artifacts.js +8 -6
- package/dist/helpers/bootstrap.js +13 -20
- package/dist/helpers/path-utils.js +2 -0
- package/dist/helpers/store-resolution.js +18 -3
- package/dist/helpers/workspace-root.d.ts +2 -0
- package/dist/helpers/workspace-root.js +9 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +1 -0
- package/dist/hermes/bridge-protocol.d.ts +1 -1
- package/dist/hermes/session-manager.d.ts +17 -0
- package/dist/hermes/session-manager.js +67 -14
- package/dist/host-goal-engine.d.ts +138 -0
- package/dist/host-goal-engine.js +793 -0
- package/dist/host-goal-status.d.ts +113 -0
- package/dist/host-goal-status.js +175 -0
- package/dist/host-learning.d.ts +68 -0
- package/dist/host-learning.js +115 -0
- package/dist/host-observation.d.ts +12 -0
- package/dist/host-observation.js +91 -0
- package/dist/host-plan-revision.d.ts +14 -0
- package/dist/host-plan-revision.js +101 -0
- package/dist/host-verification-job.d.ts +12 -0
- package/dist/host-verification-job.js +183 -0
- package/dist/host-work-context.d.ts +12 -0
- package/dist/host-work-context.js +8 -0
- package/dist/job-scheduler.d.ts +58 -13
- package/dist/job-scheduler.js +298 -48
- package/dist/job-worker.d.ts +3 -1
- package/dist/job-worker.js +10 -3
- package/dist/kanban.d.ts +4 -1
- package/dist/kanban.js +44 -16
- package/dist/learned-artifacts.d.ts +64 -0
- package/dist/learned-artifacts.js +321 -0
- package/dist/learning-controls.d.ts +142 -0
- package/dist/learning-controls.js +135 -0
- package/dist/learning-input-context.d.ts +9 -0
- package/dist/learning-input-context.js +62 -0
- package/dist/learning-lifecycle.d.ts +10 -0
- package/dist/learning-lifecycle.js +11 -0
- package/dist/learning-overlays.d.ts +3 -0
- package/dist/learning-overlays.js +17 -0
- package/dist/learning-policy.d.ts +40 -0
- package/dist/learning-policy.js +38 -0
- package/dist/learning-records.d.ts +35 -0
- package/dist/learning-records.js +17 -0
- package/dist/learning-scorecard.d.ts +82 -0
- package/dist/learning-scorecard.js +86 -0
- package/dist/learning-serving.d.ts +29 -0
- package/dist/learning-serving.js +134 -0
- package/dist/linked-work.d.ts +9 -0
- package/dist/linked-work.js +28 -0
- package/dist/local-model-runtime.js +1 -1
- package/dist/mcp-command-progress.d.ts +16 -0
- package/dist/mcp-command-progress.js +70 -0
- package/dist/model-bridge.d.ts +14 -13
- package/dist/model-bridge.js +73 -41
- package/dist/orchestrator-supervisor.d.ts +111 -6
- package/dist/orchestrator-supervisor.js +67 -43
- package/dist/plan-proposal.js +3 -3
- package/dist/playbook-curator.d.ts +1 -0
- package/dist/playbook-curator.js +11 -9
- package/dist/process-identity.d.ts +8 -0
- package/dist/process-identity.js +38 -0
- package/dist/progress-command.d.ts +34 -0
- package/dist/progress-command.js +153 -0
- package/dist/prompts.js +15 -15
- package/dist/resources.js +2 -2
- package/dist/runtime-command.d.ts +8 -1
- package/dist/runtime-command.js +48 -7
- package/dist/runtime-executor.js +33 -11
- package/dist/runtime-profile-syntax.d.ts +6 -0
- package/dist/runtime-profile-syntax.js +121 -0
- package/dist/runtime-profile.d.ts +37 -5
- package/dist/runtime-profile.js +36 -129
- package/dist/runtime-tool-specs.js +1 -1
- package/dist/safe-edit.d.ts +7 -3
- package/dist/safe-edit.js +40 -47
- package/dist/schemas.js +4 -2
- package/dist/server.d.ts +2 -16
- package/dist/server.js +14 -20
- package/dist/shared.d.ts +2 -0
- package/dist/shared.js +2 -0
- package/dist/skill-auditor.d.ts +19 -0
- package/dist/skill-auditor.js +32 -2
- package/dist/skill-catalog.d.ts +4 -1
- package/dist/skill-catalog.js +6 -5
- package/dist/store/ace-packed-store.d.ts +5 -1
- package/dist/store/ace-packed-store.js +33 -1
- package/dist/store/bootstrap-store.js +19 -12
- package/dist/store/cache-workspace.d.ts +8 -0
- package/dist/store/cache-workspace.js +94 -27
- package/dist/store/importer.js +11 -20
- package/dist/store/knowledge-bake.d.ts +3 -1
- package/dist/store/knowledge-bake.js +10 -1
- package/dist/store/legacy-vericify-posts.d.ts +8 -0
- package/dist/store/legacy-vericify-posts.js +76 -0
- package/dist/store/materializers/hook-context-materializer.d.ts +2 -1
- package/dist/store/materializers/hook-context-materializer.js +6 -2
- package/dist/store/materializers/host-file-materializer.js +2 -2
- package/dist/store/materializers/projection-manager.d.ts +4 -1
- package/dist/store/materializers/projection-manager.js +10 -3
- package/dist/store/materializers/todo-syncer.d.ts +39 -20
- package/dist/store/materializers/todo-syncer.js +208 -110
- package/dist/store/materializers/vericify-projector.js +15 -26
- package/dist/store/repositories/goal-repository.d.ts +51 -2
- package/dist/store/repositories/goal-repository.js +114 -48
- package/dist/store/repositories/playbook-repository.d.ts +41 -3
- package/dist/store/repositories/playbook-repository.js +61 -5
- package/dist/store/repositories/todo-repository.d.ts +8 -2
- package/dist/store/repositories/todo-repository.js +1 -1
- package/dist/store/repositories/vericify-repository.d.ts +4 -0
- package/dist/store/repositories/vericify-repository.js +46 -0
- package/dist/store/skills-install.d.ts +1 -0
- package/dist/store/skills-install.js +20 -16
- package/dist/store/source-preservation.d.ts +24 -0
- package/dist/store/source-preservation.js +79 -0
- package/dist/store/store-artifacts.js +8 -1
- package/dist/store/test-write-boundary.d.ts +16 -0
- package/dist/store/test-write-boundary.js +175 -0
- package/dist/store/types.d.ts +5 -1
- package/dist/store/write-coordinator.js +16 -0
- package/dist/task-plan-context.d.ts +11 -0
- package/dist/task-plan-context.js +59 -0
- package/dist/todo-state.d.ts +19 -9
- package/dist/todo-state.js +204 -321
- package/dist/tools-agent.d.ts +1 -1
- package/dist/tools-agent.js +38 -62
- package/dist/tools-files.d.ts +0 -3
- package/dist/tools-files.js +21 -11
- package/dist/tools-framework.js +16 -25
- package/dist/tools-goal.d.ts +2 -4
- package/dist/tools-goal.js +119 -16
- package/dist/tools-handoff.d.ts +3 -2
- package/dist/tools-handoff.js +53 -23
- package/dist/tools-lifecycle.js +1 -1
- package/dist/tools-memory.d.ts +0 -3
- package/dist/tools-memory.js +51 -6
- package/dist/tools-scheduler.js +20 -17
- package/dist/tools-todo.js +160 -148
- package/dist/vericify-bridge.d.ts +8 -0
- package/dist/vericify-bridge.js +18 -0
- package/dist/vericify-context.d.ts +4 -0
- package/dist/vericify-context.js +26 -5
- package/dist/vericify-native.d.ts +101 -0
- package/dist/vericify-native.js +221 -0
- package/dist/verification-worker.d.ts +2 -0
- package/dist/verification-worker.js +31 -0
- package/docs/mcp-tool-reference.md +50 -10
- package/docs/troubleshooting.md +29 -0
- package/package.json +19 -6
- package/scripts/dev/run-tests-isolated.mjs +165 -0
- package/scripts/dev/run_hermes_crispr_live.mjs +1 -0
- package/scripts/dev/test-isolation-guard.mjs +20 -0
- package/scripts/dev/test-preload.mjs +153 -0
- package/scripts/dev/test-source-inventory.mjs +31 -0
- package/docs/development.md +0 -46
|
@@ -99,7 +99,7 @@ async function materializeStoreSurfaces(store, workspaceRoot, opts) {
|
|
|
99
99
|
await todoSyncer.initStarter();
|
|
100
100
|
await store.commit();
|
|
101
101
|
const projections = new ProjectionManager(store, workspaceRoot);
|
|
102
|
-
await projections.projectAfterCommit(["hook_context", "todo_state", "scheduler", "context_snapshots"]);
|
|
102
|
+
await projections.projectAfterCommit(["vericify_posts", "hook_context", "todo_state", "scheduler", "context_snapshots"]);
|
|
103
103
|
materialized.push(join(workspaceRoot, ".agents", "ACE", "tasks", "todo.md"));
|
|
104
104
|
return [...new Set(materialized)];
|
|
105
105
|
}
|
|
@@ -113,6 +113,8 @@ const GATE_CONTRACT_OPERATIONAL_ARTIFACT_RELS = [
|
|
|
113
113
|
async function seedOperationalArtifacts(store) {
|
|
114
114
|
const bootstrapTs = new Date().toISOString();
|
|
115
115
|
for (const relPath of OPERATIONAL_ARTIFACT_REL_PATHS) {
|
|
116
|
+
if (await store.getBlob(operationalArtifactKey(relPath)) !== undefined)
|
|
117
|
+
continue;
|
|
116
118
|
const knowledgeKey = `knowledge/agent-state/${relPath.replace(/^agent-state\//, "")}`;
|
|
117
119
|
let content = relPath.endsWith("-archive.ndjson")
|
|
118
120
|
? ""
|
|
@@ -156,6 +158,7 @@ export async function bootstrapStoreWorkspace(opts) {
|
|
|
156
158
|
try {
|
|
157
159
|
await migrateExistingStoreGateContract(existingStore, workspaceRoot, assetsRoot, warnings);
|
|
158
160
|
if (!(opts.includeMcpConfig ?? false) && !(opts.includeClientConfigBundle ?? false) && !opts.llm) {
|
|
161
|
+
await existingStore.commit();
|
|
159
162
|
const agents = (await existingStore.listAgents()).length;
|
|
160
163
|
warnings.push(`Reused existing store at ${storePath}. Refreshed package gate contract state.`);
|
|
161
164
|
return { storePath, agents, modules: { gates: 0, roles: 0, schemas: 0 }, materialized, warnings };
|
|
@@ -166,7 +169,7 @@ export async function bootstrapStoreWorkspace(opts) {
|
|
|
166
169
|
return { storePath, agents, modules: { gates: 0, roles: 0, schemas: 0 }, materialized, warnings };
|
|
167
170
|
}
|
|
168
171
|
finally {
|
|
169
|
-
await existingStore.close();
|
|
172
|
+
await existingStore.close({ commit: false });
|
|
170
173
|
}
|
|
171
174
|
}
|
|
172
175
|
for (const dir of [
|
|
@@ -197,7 +200,9 @@ export async function bootstrapStoreWorkspace(opts) {
|
|
|
197
200
|
await store.setJSON("state/memory/context_snapshots/index.json", { snapshots: [] });
|
|
198
201
|
await store.setJSON("state/runtime/sessions/index", []);
|
|
199
202
|
await store.setJSON("state/discovery/index", []);
|
|
200
|
-
await store.
|
|
203
|
+
if (await store.getBlob("state/vericify/posts/index") === undefined) {
|
|
204
|
+
await store.setJSON("state/vericify/posts/index", []);
|
|
205
|
+
}
|
|
201
206
|
await applyLlmRuntimeConfig(store, opts);
|
|
202
207
|
await seedOperationalArtifacts(store);
|
|
203
208
|
await buildCatalog(store);
|
|
@@ -214,7 +219,7 @@ export async function bootstrapStoreWorkspace(opts) {
|
|
|
214
219
|
};
|
|
215
220
|
}
|
|
216
221
|
finally {
|
|
217
|
-
await store.close();
|
|
222
|
+
await store.close({ commit: false });
|
|
218
223
|
}
|
|
219
224
|
}, { operation_label: "bootstrapStoreWorkspace" });
|
|
220
225
|
}
|
|
@@ -303,7 +308,7 @@ export async function repairWorkspace(workspaceRoot) {
|
|
|
303
308
|
warnings.push(`repair error: ${e.message}`);
|
|
304
309
|
}
|
|
305
310
|
finally {
|
|
306
|
-
await store.close();
|
|
311
|
+
await store.close({ commit: false });
|
|
307
312
|
}
|
|
308
313
|
return warnings;
|
|
309
314
|
}
|
|
@@ -318,13 +323,15 @@ export async function compactWorkspace(workspaceRoot, options = {}) {
|
|
|
318
323
|
const { storePath } = resolved;
|
|
319
324
|
const { statSync } = await import("fs");
|
|
320
325
|
const before = statSync(storePath).size;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
326
|
+
await withStoreWriteCoordinator(storePath, async () => {
|
|
327
|
+
const store = await openStore(storePath);
|
|
328
|
+
try {
|
|
329
|
+
await store.compact();
|
|
330
|
+
}
|
|
331
|
+
finally {
|
|
332
|
+
await store.close({ commit: false });
|
|
333
|
+
}
|
|
334
|
+
}, { operation_label: "compactWorkspace" });
|
|
328
335
|
const after = statSync(storePath).size;
|
|
329
336
|
const sweep = options.sweep === false
|
|
330
337
|
? undefined
|
|
@@ -25,6 +25,14 @@ export interface CacheWorkspaceResult {
|
|
|
25
25
|
key: string;
|
|
26
26
|
bytes: number;
|
|
27
27
|
}>;
|
|
28
|
+
verified_sources: Array<{
|
|
29
|
+
path: string;
|
|
30
|
+
sha256: string;
|
|
31
|
+
source_key: string;
|
|
32
|
+
target_key: string;
|
|
33
|
+
receipt_key: string;
|
|
34
|
+
removed: boolean;
|
|
35
|
+
}>;
|
|
28
36
|
}
|
|
29
37
|
export declare function cacheWorkspaceArtifacts(workspaceRoot: string, options?: CacheWorkspaceOptions): Promise<CacheWorkspaceResult>;
|
|
30
38
|
//# sourceMappingURL=cache-workspace.d.ts.map
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { existsSync, readdirSync,
|
|
1
|
+
import { existsSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
2
2
|
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
3
3
|
import { ACE_ROOT_REL, isProjectedAceWorkspacePath, mapAceWorkspaceRelativePath, resolveStoreFallbackKeysForPath, } from "../helpers.js";
|
|
4
4
|
import { normalizeRelPath } from "../shared.js";
|
|
5
|
-
import { getWorkspaceStorePath } from "./store-snapshot.js";
|
|
6
|
-
import {
|
|
5
|
+
import { getWorkspaceStorePath, readStoreBlobByPathSync, readStoreJsonByPathSync } from "./store-snapshot.js";
|
|
6
|
+
import { openStore } from "./ace-packed-store.js";
|
|
7
|
+
import { withStoreWriteCoordinator } from "./write-coordinator.js";
|
|
8
|
+
import { captureWorkspaceSource, preservedSourceKey, sourceUnchanged, stagePreservedSource, verifyPreservedSource } from "./source-preservation.js";
|
|
7
9
|
const SCAN_ROOTS_REL = [
|
|
8
10
|
"agent-state",
|
|
9
11
|
".agents/ACE/agent-state",
|
|
@@ -146,8 +148,17 @@ export async function cacheWorkspaceArtifacts(workspaceRoot, options = {}) {
|
|
|
146
148
|
keptProjected += 1;
|
|
147
149
|
continue;
|
|
148
150
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
+
let source;
|
|
152
|
+
try {
|
|
153
|
+
source = captureWorkspaceSource(workspaceRoot, absPath);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
skipped += 1;
|
|
157
|
+
warnings.push(`Kept unstable source ${relPath}: ${error.message}`);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const raw = Buffer.from(source.content_base64, "base64");
|
|
161
|
+
if (!isTextBuffer(raw) || !Buffer.from(raw.toString("utf8"), "utf8").equals(raw)) {
|
|
151
162
|
skipped += 1;
|
|
152
163
|
warnings.push(`Skipped non-text artifact: ${canonicalPath}`);
|
|
153
164
|
continue;
|
|
@@ -164,32 +175,87 @@ export async function cacheWorkspaceArtifacts(workspaceRoot, options = {}) {
|
|
|
164
175
|
key: fallbackKeys[0],
|
|
165
176
|
content: raw.toString("utf-8"),
|
|
166
177
|
bytes: raw.byteLength,
|
|
178
|
+
source,
|
|
167
179
|
});
|
|
168
180
|
}
|
|
169
181
|
}
|
|
170
|
-
const
|
|
182
|
+
const byKey = new Map();
|
|
171
183
|
for (const candidate of candidates) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (!dryRun && uniqueForWrite.length > 0) {
|
|
176
|
-
await writeStoreBlobsQueued(workspaceRoot, uniqueForWrite.map((candidate) => ({
|
|
177
|
-
key: candidate.key,
|
|
178
|
-
content: candidate.content,
|
|
179
|
-
})), { operation_label: "cacheWorkspace" });
|
|
184
|
+
const group = byKey.get(candidate.key) ?? [];
|
|
185
|
+
group.push(candidate);
|
|
186
|
+
byKey.set(candidate.key, group);
|
|
180
187
|
}
|
|
181
188
|
let removed = 0;
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
const cached = [];
|
|
190
|
+
const verifiedSources = [];
|
|
191
|
+
if (!dryRun && candidates.length > 0) {
|
|
192
|
+
await withStoreWriteCoordinator(storePath, async () => {
|
|
193
|
+
const store = await openStore(storePath);
|
|
194
|
+
try {
|
|
195
|
+
for (const group of byKey.values()) {
|
|
196
|
+
if (new Set(group.map((candidate) => candidate.source.sha256)).size > 1) {
|
|
197
|
+
warnings.push(`Fallback-key collision at ${group[0].key}; kept all sources: ${group.map((c) => c.source.source_path).join(", ")}`);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
for (const candidate of group) {
|
|
201
|
+
if (!sourceUnchanged(workspaceRoot, candidate.absPath, candidate.source)) {
|
|
202
|
+
warnings.push(`Source changed since scan; kept ${candidate.source.source_path}`);
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
await stagePreservedSource(store, candidate.source);
|
|
206
|
+
const existing = await store.getBlob(candidate.key);
|
|
207
|
+
if (existing !== undefined && existing !== candidate.content) {
|
|
208
|
+
warnings.push(`Canonical content conflict at ${candidate.key}; kept ${candidate.source.source_path}`);
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (existing === undefined)
|
|
212
|
+
await store.setBlob(candidate.key, candidate.content);
|
|
213
|
+
cached.push(candidate);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
await store.commit();
|
|
217
|
+
// Independent committed-file readback precedes the durable receipt.
|
|
218
|
+
for (const candidate of cached) {
|
|
219
|
+
verifyPreservedSource(storePath, candidate.source);
|
|
220
|
+
if (readStoreBlobByPathSync(storePath, candidate.key) !== candidate.content) {
|
|
221
|
+
throw new Error(`Canonical readback failed: ${candidate.source.source_path}`);
|
|
222
|
+
}
|
|
223
|
+
const sourceKey = preservedSourceKey(candidate.source);
|
|
224
|
+
const receiptKey = sourceKey.replace("/sources/", "/receipts/");
|
|
225
|
+
await store.setJSON(receiptKey, {
|
|
226
|
+
source_key: sourceKey, target_key: candidate.key,
|
|
227
|
+
sha256: candidate.source.sha256, identity: candidate.source.identity,
|
|
228
|
+
verified_at: new Date().toISOString(),
|
|
229
|
+
});
|
|
230
|
+
verifiedSources.push({ path: candidate.source.source_path, sha256: candidate.source.sha256, source_key: sourceKey, target_key: candidate.key, receipt_key: receiptKey, removed: false });
|
|
231
|
+
}
|
|
232
|
+
await store.commit();
|
|
233
|
+
// No awaits between the final source identity check and unlink.
|
|
234
|
+
for (let i = 0; i < cached.length; i++) {
|
|
235
|
+
const candidate = cached[i];
|
|
236
|
+
const receipt = verifiedSources[i];
|
|
237
|
+
const committedReceipt = readStoreJsonByPathSync(storePath, receipt.receipt_key);
|
|
238
|
+
verifyPreservedSource(storePath, candidate.source);
|
|
239
|
+
if (committedReceipt?.sha256 !== receipt.sha256 || committedReceipt.target_key !== candidate.key || readStoreBlobByPathSync(storePath, candidate.key) !== candidate.content) {
|
|
240
|
+
throw new Error(`Migration receipt readback failed: ${candidate.source.source_path}`);
|
|
241
|
+
}
|
|
242
|
+
if (!clean)
|
|
243
|
+
continue;
|
|
244
|
+
if (!sourceUnchanged(workspaceRoot, candidate.absPath, candidate.source)) {
|
|
245
|
+
warnings.push(`Source changed before removal; kept ${candidate.source.source_path}`);
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
rmSync(candidate.absPath);
|
|
249
|
+
receipt.removed = true;
|
|
250
|
+
removed += 1;
|
|
251
|
+
const pruneRoot = scanRoots.find((root) => isInside(root, candidate.absPath)) ?? workspaceRoot;
|
|
252
|
+
pruneEmptyParents(candidate.absPath, pruneRoot);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
finally {
|
|
256
|
+
await store.close({ commit: false });
|
|
257
|
+
}
|
|
258
|
+
}, { operation_label: "cacheWorkspace" });
|
|
193
259
|
}
|
|
194
260
|
const removedSemanticCache = gcSemanticCache
|
|
195
261
|
? removeSemanticCache(workspaceRoot, minAgeMs, dryRun)
|
|
@@ -199,13 +265,14 @@ export async function cacheWorkspaceArtifacts(workspaceRoot, options = {}) {
|
|
|
199
265
|
dry_run: dryRun,
|
|
200
266
|
clean,
|
|
201
267
|
scanned_files: scanned,
|
|
202
|
-
cached_files: candidates.length,
|
|
268
|
+
cached_files: dryRun ? candidates.length : cached.length,
|
|
203
269
|
removed_files: removed,
|
|
204
270
|
removed_semantic_cache_files: removedSemanticCache,
|
|
205
271
|
kept_projected_files: keptProjected,
|
|
206
272
|
skipped_files: skipped,
|
|
207
273
|
warnings,
|
|
208
|
-
|
|
274
|
+
verified_sources: verifiedSources,
|
|
275
|
+
cached: (dryRun ? candidates : cached).map((candidate) => ({
|
|
209
276
|
path: candidate.canonicalPath,
|
|
210
277
|
key: candidate.key,
|
|
211
278
|
bytes: candidate.bytes,
|
package/dist/store/importer.js
CHANGED
|
@@ -14,7 +14,8 @@ import { HandoffRepository } from "./repositories/handoff-repository.js";
|
|
|
14
14
|
import { TodoRepository } from "./repositories/todo-repository.js";
|
|
15
15
|
import { LedgerRepository } from "./repositories/ledger-repository.js";
|
|
16
16
|
import { TrackerRepository } from "./repositories/tracker-repository.js";
|
|
17
|
-
import {
|
|
17
|
+
import { preserveLegacyVericifyPosts } from "./legacy-vericify-posts.js";
|
|
18
|
+
import { withStoreWriteCoordinator } from "./write-coordinator.js";
|
|
18
19
|
function readJSON(path) {
|
|
19
20
|
if (!existsSync(path))
|
|
20
21
|
return undefined;
|
|
@@ -36,6 +37,11 @@ function readText(path) {
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
export async function importFromFileWorkspace(workspaceRoot, storePath) {
|
|
40
|
+
return withStoreWriteCoordinator(storePath, () => importFileWorkspaceLocked(workspaceRoot, storePath), {
|
|
41
|
+
operation_label: "importFromFileWorkspace",
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async function importFileWorkspaceLocked(workspaceRoot, storePath) {
|
|
39
45
|
const result = {
|
|
40
46
|
handoffs: 0,
|
|
41
47
|
todos: 0,
|
|
@@ -50,7 +56,6 @@ export async function importFromFileWorkspace(workspaceRoot, storePath) {
|
|
|
50
56
|
const todoRepo = new TodoRepository(store);
|
|
51
57
|
const ledgerRepo = new LedgerRepository(store);
|
|
52
58
|
const trackerRepo = new TrackerRepository(store);
|
|
53
|
-
const vericifyRepo = new VericifyRepository(store);
|
|
54
59
|
await ledgerRepo.init();
|
|
55
60
|
// ── Handoffs ──────────────────────────────────────────────────────────
|
|
56
61
|
const handoffReg = readJSON(join(workspaceRoot, "agent-state", "handoff-registry.json"));
|
|
@@ -129,28 +134,14 @@ export async function importFromFileWorkspace(workspaceRoot, storePath) {
|
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
136
|
// ── Vericify Posts ────────────────────────────────────────────────────
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
await vericifyRepo.appendPost({
|
|
137
|
-
run_id: String(post.run_id ?? "migrated"),
|
|
138
|
-
agent_id: String(post.agent_id ?? "unknown"),
|
|
139
|
-
kind: post.kind ?? "completion",
|
|
140
|
-
summary: String(post.summary ?? ""),
|
|
141
|
-
});
|
|
142
|
-
result.vericify_posts++;
|
|
143
|
-
}
|
|
144
|
-
catch (e) {
|
|
145
|
-
result.warnings.push(`vericify post: ${e.message}`);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
137
|
+
const legacy = await preserveLegacyVericifyPosts(store, workspaceRoot, storePath);
|
|
138
|
+
result.vericify_posts = legacy.imported;
|
|
139
|
+
result.warnings.push(...legacy.warnings);
|
|
149
140
|
await store.commit();
|
|
150
141
|
await store.compact();
|
|
151
142
|
}
|
|
152
143
|
finally {
|
|
153
|
-
await store.close();
|
|
144
|
+
await store.close({ commit: false });
|
|
154
145
|
}
|
|
155
146
|
return result;
|
|
156
147
|
}
|
|
@@ -31,7 +31,9 @@ export declare function bakeTaskArtifacts(store: AcePackedStore, assetsRoot: str
|
|
|
31
31
|
tasks: number;
|
|
32
32
|
runtime: number;
|
|
33
33
|
}>;
|
|
34
|
-
export declare function bakeSkillPack(store: AcePackedStore, assetsRoot: string, skillName: string
|
|
34
|
+
export declare function bakeSkillPack(store: AcePackedStore, assetsRoot: string, skillName: string, options?: {
|
|
35
|
+
onSkip?: (key: string) => void;
|
|
36
|
+
}): Promise<number>;
|
|
35
37
|
export declare function listAvailableSkills(assetsRoot: string): Promise<string[]>;
|
|
36
38
|
export declare function bakeAllCoreKnowledge(store: AcePackedStore, assetsRoot: string): Promise<{
|
|
37
39
|
agents: {
|
|
@@ -292,17 +292,26 @@ export async function bakeTaskArtifacts(store, assetsRoot) {
|
|
|
292
292
|
return { state, tasks, runtime };
|
|
293
293
|
}
|
|
294
294
|
// ── Skills ───────────────────────────────────────────────────────────────────
|
|
295
|
-
export async function bakeSkillPack(store, assetsRoot, skillName) {
|
|
295
|
+
export async function bakeSkillPack(store, assetsRoot, skillName, options = {}) {
|
|
296
296
|
const skillDir = join(assetsRoot, ".agents", "skills", skillName);
|
|
297
297
|
if (!existsSync(skillDir)) {
|
|
298
298
|
throw new Error(`[knowledge-bake] skill pack not found: ${skillName} at ${skillDir}`);
|
|
299
299
|
}
|
|
300
300
|
let fileCount = 0;
|
|
301
|
+
const prefix = `knowledge/skills/${skillName}/`;
|
|
302
|
+
const owners = new Map((await store.getEntries({ keyPrefix: prefix })).map((entry) => [entry.key, entry.content_source]));
|
|
301
303
|
for (const filePath of walkDir(skillDir)) {
|
|
302
304
|
const ext = extname(filePath);
|
|
303
305
|
if (!MARKDOWN_EXTS.has(ext))
|
|
304
306
|
continue;
|
|
305
307
|
const relPath = relative(skillDir, filePath);
|
|
308
|
+
const key = `${prefix}${relPath.replaceAll("\\", "/")}`;
|
|
309
|
+
const existing = await store.getBlob(key);
|
|
310
|
+
if (key.startsWith("knowledge/skills/learned/") || (existing !== undefined && owners.get(key) !== ContentSource.Package)) {
|
|
311
|
+
options.onSkip?.(key);
|
|
312
|
+
console.log(`[knowledge-bake] skipped user-owned file: ${key}`);
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
306
315
|
const content = readText(filePath);
|
|
307
316
|
await store.setSkillContent(skillName, relPath, content, ContentSource.Package);
|
|
308
317
|
fileCount++;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AcePackedStore } from "./ace-packed-store.js";
|
|
2
|
+
/** Caller owns the store coordinator. No projection or unlink is performed here. */
|
|
3
|
+
export declare function preserveLegacyVericifyPosts(store: AcePackedStore, root: string, storePath?: string): Promise<{
|
|
4
|
+
imported: number;
|
|
5
|
+
canProject: boolean;
|
|
6
|
+
warnings: string[];
|
|
7
|
+
}>;
|
|
8
|
+
//# sourceMappingURL=legacy-vericify-posts.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { operationalArtifactKey } from "./store-artifacts.js";
|
|
4
|
+
import { VericifyRepository, projectVericifyPost } from "./repositories/vericify-repository.js";
|
|
5
|
+
import { captureWorkspaceSource, sourceFromBytes, stagePreservedSource, verifyPreservedSource } from "./source-preservation.js";
|
|
6
|
+
import { getWorkspaceStorePath, readStoreJsonByPathSync } from "./store-snapshot.js";
|
|
7
|
+
import { isDeepStrictEqual } from "node:util";
|
|
8
|
+
const REL = "agent-state/vericify/process-posts.json";
|
|
9
|
+
/** Caller owns the store coordinator. No projection or unlink is performed here. */
|
|
10
|
+
export async function preserveLegacyVericifyPosts(store, root, storePath = getWorkspaceStorePath(root)) {
|
|
11
|
+
const warnings = [];
|
|
12
|
+
const sources = [];
|
|
13
|
+
const loose = join(root, REL);
|
|
14
|
+
let canProject = true;
|
|
15
|
+
if (existsSync(loose)) {
|
|
16
|
+
try {
|
|
17
|
+
sources.push(captureWorkspaceSource(root, loose));
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
warnings.push(`Kept legacy posts: ${error.message}`);
|
|
21
|
+
canProject = false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const packed = await store.getBlob(operationalArtifactKey(REL));
|
|
25
|
+
const checksums = await store.getJSON("host/materializations/checksums");
|
|
26
|
+
const repo = new VericifyRepository(store);
|
|
27
|
+
if (packed?.trim()) {
|
|
28
|
+
const source = sourceFromBytes(`${REL}#prior-store-value`, Buffer.from(packed));
|
|
29
|
+
let represented = false;
|
|
30
|
+
if (checksums?.["vericify/process-posts.json"]?.hash === source.sha256) {
|
|
31
|
+
try {
|
|
32
|
+
const prior = JSON.parse(packed);
|
|
33
|
+
const records = new Map((await repo.list()).map((p) => [p.id, JSON.parse(JSON.stringify(projectVericifyPost(p)))]));
|
|
34
|
+
represented = Array.isArray(prior.posts) && prior.posts.every((p) => isDeepStrictEqual(records.get(String(p.process_post_id ?? p.id)), p));
|
|
35
|
+
}
|
|
36
|
+
catch { /* Unverified content is preserved below, never projected over. */ }
|
|
37
|
+
}
|
|
38
|
+
if (!represented && !sources.some((s) => s.sha256 === source.sha256))
|
|
39
|
+
sources.push(source);
|
|
40
|
+
}
|
|
41
|
+
const expected = new Map();
|
|
42
|
+
let imported = 0;
|
|
43
|
+
for (const source of sources) {
|
|
44
|
+
await stagePreservedSource(store, source);
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(Buffer.from(source.content_base64, "base64").toString("utf8"));
|
|
47
|
+
if (!parsed || !Array.isArray(parsed.posts))
|
|
48
|
+
throw new Error("Expected a posts array");
|
|
49
|
+
for (const post of parsed.posts) {
|
|
50
|
+
if (!post || typeof post !== "object" || Array.isArray(post))
|
|
51
|
+
throw new Error("Invalid historical post");
|
|
52
|
+
const record = await repo.importPost(post);
|
|
53
|
+
expected.set(record.id, post);
|
|
54
|
+
imported += 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
canProject = false;
|
|
59
|
+
warnings.push(`Legacy post projection retained: ${error.message}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (sources.length > 0) {
|
|
63
|
+
await store.commit();
|
|
64
|
+
for (const source of sources)
|
|
65
|
+
verifyPreservedSource(storePath, source);
|
|
66
|
+
const index = readStoreJsonByPathSync(storePath, "state/vericify/posts/index") ?? [];
|
|
67
|
+
for (const [id, original] of expected) {
|
|
68
|
+
const actual = readStoreJsonByPathSync(storePath, `state/vericify/posts/${id}`);
|
|
69
|
+
const retained = actual && (actual.legacy_record ?? JSON.parse(JSON.stringify(projectVericifyPost(actual))));
|
|
70
|
+
if (!index.includes(id) || !isDeepStrictEqual(retained, original))
|
|
71
|
+
throw new Error(`Historical post readback failed: ${id}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return { imported, canProject, warnings };
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=legacy-vericify-posts.js.map
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
import { AcePackedStore } from "../ace-packed-store.js";
|
|
8
8
|
export declare class HookContextMaterializer {
|
|
9
9
|
private store;
|
|
10
|
+
private workspaceRoot;
|
|
10
11
|
static readonly STORE_KEY = "state/runtime/hook_context";
|
|
11
12
|
private kv;
|
|
12
|
-
constructor(store: AcePackedStore);
|
|
13
|
+
constructor(store: AcePackedStore, workspaceRoot: string);
|
|
13
14
|
private buildSnapshot;
|
|
14
15
|
stageStoreProjection(): Promise<void>;
|
|
15
16
|
private _readContent;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Stages the compact hook snapshot into ace-state.ace so hook clients can
|
|
5
5
|
* read a single runtime payload without extra workspace projections.
|
|
6
6
|
*/
|
|
7
|
+
import { resolveCurrentWork, formatCurrentWork } from "../../ace-autonomy.js";
|
|
7
8
|
import { RuntimeKVRepository } from "../repositories/runtime-kv-repository.js";
|
|
8
9
|
function fnv1a(s) {
|
|
9
10
|
let h = 2166136261;
|
|
@@ -15,10 +16,12 @@ function fnv1a(s) {
|
|
|
15
16
|
}
|
|
16
17
|
export class HookContextMaterializer {
|
|
17
18
|
store;
|
|
19
|
+
workspaceRoot;
|
|
18
20
|
static STORE_KEY = "state/runtime/hook_context";
|
|
19
21
|
kv;
|
|
20
|
-
constructor(store) {
|
|
22
|
+
constructor(store, workspaceRoot) {
|
|
21
23
|
this.store = store;
|
|
24
|
+
this.workspaceRoot = workspaceRoot;
|
|
22
25
|
this.kv = new RuntimeKVRepository(store);
|
|
23
26
|
}
|
|
24
27
|
async buildSnapshot() {
|
|
@@ -32,6 +35,7 @@ export class HookContextMaterializer {
|
|
|
32
35
|
return {
|
|
33
36
|
schema_version: 1,
|
|
34
37
|
generated_at: new Date().toISOString(),
|
|
38
|
+
current_work: formatCurrentWork(resolveCurrentWork({ workspaceRoot: this.workspaceRoot }), "block"),
|
|
35
39
|
task: { content: task, hash: fnv1a(task) },
|
|
36
40
|
status: { content: status, hash: fnv1a(status) },
|
|
37
41
|
scope: { content: scope, hash: fnv1a(scope) },
|
|
@@ -59,7 +63,7 @@ export class HookContextMaterializer {
|
|
|
59
63
|
evidence_log: "knowledge/agent-state/EVIDENCE_LOG.md",
|
|
60
64
|
};
|
|
61
65
|
const fallbackKey = fallback[kind];
|
|
62
|
-
return fallbackKey ? (await this.store.getBlob(fallbackKey)) ?? "" : "";
|
|
66
|
+
return fallbackKey ? (await this.store.getBlob(fallbackKey.replace("knowledge/", "state/artifacts/"))) ?? (await this.store.getBlob(fallbackKey)) ?? "" : "";
|
|
63
67
|
}
|
|
64
68
|
async _readKernelWorkflow() {
|
|
65
69
|
return ((await this.store.getBlob("knowledge/runtime/ACE_WORKFLOW.md")) ??
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { dirname, join, resolve } from "node:path";
|
|
11
|
-
import { fileURLToPath } from "node:url";
|
|
11
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
12
12
|
import { buildHostInstructionText } from "../../ace-server-instructions.js";
|
|
13
13
|
import { ALL_MCP_CLIENTS, getAllMcpServerConfigSnippets, getMcpClientInstallHint, getMcpServerConfigSnippet, } from "../../helpers.js";
|
|
14
14
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -186,7 +186,7 @@ export class HostFileMaterializer {
|
|
|
186
186
|
return {
|
|
187
187
|
absPath: this.ace("scripts", "ace", scriptName),
|
|
188
188
|
keyParts: [".agents", "ACE", "scripts", "ace", scriptName],
|
|
189
|
-
fallbackContent: readFileSync(src, "utf8"),
|
|
189
|
+
fallbackContent: readFileSync(src, "utf8").replace("__ACE_AUTONOMY_MODULE_URL__", pathToFileURL(resolve(__dirname, "..", "..", "ace-autonomy.js")).href),
|
|
190
190
|
};
|
|
191
191
|
});
|
|
192
192
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AcePackedStore } from "../ace-packed-store.js";
|
|
2
|
+
import { type TodoProjectionResult } from "./todo-syncer.js";
|
|
2
3
|
export type RuntimeProjectionTarget = "context_snapshots" | "handoffs" | "ledger" | "scheduler" | "status_events" | "todo_state" | "vericify_posts" | "hook_context";
|
|
3
4
|
/**
|
|
4
5
|
* Awaitable handle for the detached lifecycle sweep. CLI entry points and
|
|
@@ -15,6 +16,8 @@ export declare class ProjectionManager {
|
|
|
15
16
|
private scheduler;
|
|
16
17
|
private static lifecycleSweepActive;
|
|
17
18
|
constructor(store: AcePackedStore, workspaceRoot: string);
|
|
18
|
-
projectAfterCommit(targets: readonly RuntimeProjectionTarget[]): Promise<
|
|
19
|
+
projectAfterCommit(targets: readonly RuntimeProjectionTarget[]): Promise<{
|
|
20
|
+
todo?: TodoProjectionResult;
|
|
21
|
+
}>;
|
|
19
22
|
}
|
|
20
23
|
//# sourceMappingURL=projection-manager.d.ts.map
|
|
@@ -27,10 +27,11 @@ export class ProjectionManager {
|
|
|
27
27
|
this.workspaceRoot = workspaceRoot;
|
|
28
28
|
this.vericify = new VericifyProjector(store, workspaceRoot);
|
|
29
29
|
this.todoSyncer = new TodoSyncer(store, workspaceRoot);
|
|
30
|
-
this.hookContext = new HookContextMaterializer(store);
|
|
30
|
+
this.hookContext = new HookContextMaterializer(store, workspaceRoot);
|
|
31
31
|
this.scheduler = new SchedulerProjectionMaterializer(store, workspaceRoot);
|
|
32
32
|
}
|
|
33
33
|
async projectAfterCommit(targets) {
|
|
34
|
+
const result = {};
|
|
34
35
|
const uniqueTargets = [...new Set(targets)];
|
|
35
36
|
let stagedStoreWrites = false;
|
|
36
37
|
let renderedScheduler;
|
|
@@ -81,7 +82,11 @@ export class ProjectionManager {
|
|
|
81
82
|
// REPORT_STORE_WIRING_MITIGATIONS_2026-07-09.md F1). The detached promise
|
|
82
83
|
// is exposed via waitForPendingLifecycleSweep() for CLI/test flows.
|
|
83
84
|
pendingLifecycleSweep = cacheWorkspaceArtifacts(workspaceRoot, {
|
|
84
|
-
|
|
85
|
+
// Automatic discovery must not ingest over live state or remove an
|
|
86
|
+
// unverified loose source. Explicit cache/compact uses verified migration.
|
|
87
|
+
dryRun: true,
|
|
88
|
+
clean: false,
|
|
89
|
+
gcSemanticCache: false,
|
|
85
90
|
minAgeMs: 5 * 60 * 1000,
|
|
86
91
|
})
|
|
87
92
|
.then(() => undefined)
|
|
@@ -94,9 +99,11 @@ export class ProjectionManager {
|
|
|
94
99
|
}
|
|
95
100
|
for (const target of uniqueTargets) {
|
|
96
101
|
if (target === "todo_state") {
|
|
97
|
-
await this.todoSyncer.writeToFile();
|
|
102
|
+
result.todo = await this.todoSyncer.writeToFile();
|
|
103
|
+
await this.store.commit();
|
|
98
104
|
}
|
|
99
105
|
}
|
|
106
|
+
return result;
|
|
100
107
|
}
|
|
101
108
|
}
|
|
102
109
|
//# sourceMappingURL=projection-manager.js.map
|
|
@@ -1,30 +1,49 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TodoSyncer
|
|
3
|
-
*
|
|
4
|
-
* Bidirectional sync between tasks/todo.md (human-editable) and the store.
|
|
5
|
-
*
|
|
6
|
-
* - On write: store → tasks/todo.md (ACE writes todo state from store)
|
|
7
|
-
* - On read: tasks/todo.md → store (if externally modified by mtime + hash)
|
|
8
|
-
*
|
|
9
|
-
* tasks/todo.md format:
|
|
10
|
-
* - [ ] Todo item title (id: todo-001)
|
|
11
|
-
* - [x] Completed item (id: todo-002)
|
|
12
|
-
* - [~] In progress (id: todo-003)
|
|
13
|
-
* - [!] Blocked (id: todo-004)
|
|
14
|
-
*/
|
|
15
1
|
import { AcePackedStore } from "../ace-packed-store.js";
|
|
2
|
+
import { type TodoNode } from "../repositories/todo-repository.js";
|
|
3
|
+
export declare const STATUS_ICONS: Record<TodoNode["status"], string>;
|
|
4
|
+
export declare const ICON_STATUS: Record<string, TodoNode["status"]>;
|
|
5
|
+
export interface TodoImportResult {
|
|
6
|
+
changed: boolean;
|
|
7
|
+
import_warnings: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface TodoProjectionResult {
|
|
10
|
+
written: boolean;
|
|
11
|
+
import_warnings: string[];
|
|
12
|
+
}
|
|
13
|
+
interface ParsedTodo {
|
|
14
|
+
raw_line: string;
|
|
15
|
+
id?: string;
|
|
16
|
+
title: string;
|
|
17
|
+
status: TodoNode["status"];
|
|
18
|
+
section?: string;
|
|
19
|
+
source_line: number;
|
|
20
|
+
depends_on?: string[];
|
|
21
|
+
priority?: TodoNode["priority"];
|
|
22
|
+
assigned_to?: string;
|
|
23
|
+
notes?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function parseTodoMd(content: string): {
|
|
26
|
+
items: ParsedTodo[];
|
|
27
|
+
import_warnings: string[];
|
|
28
|
+
};
|
|
29
|
+
export declare function renderTodoMd(todos: TodoNode[]): string;
|
|
16
30
|
export declare class TodoSyncer {
|
|
17
31
|
private store;
|
|
18
32
|
private workspaceRoot;
|
|
19
33
|
private repo;
|
|
20
|
-
private
|
|
34
|
+
private submittedStamp?;
|
|
21
35
|
private todoMdPath;
|
|
22
36
|
constructor(store: AcePackedStore, workspaceRoot: string);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
syncFromFile(): Promise<
|
|
27
|
-
/**
|
|
37
|
+
private stamp;
|
|
38
|
+
private setStamp;
|
|
39
|
+
/** Stage a non-destructive native import. The caller owns commit/discard and the coordinator. */
|
|
40
|
+
syncFromFile(content?: string, force?: boolean, observeNative?: boolean): Promise<TodoImportResult>;
|
|
41
|
+
/** Supplied content is an observation only after its file publication succeeds. */
|
|
42
|
+
acknowledgeSubmittedFile(content: string): Promise<void>;
|
|
43
|
+
projectionIsCurrent(): Promise<boolean>;
|
|
44
|
+
/** Do not overwrite unimported edits or malformed source text. */
|
|
45
|
+
writeToFile(): Promise<TodoProjectionResult>;
|
|
28
46
|
initStarter(): Promise<void>;
|
|
29
47
|
}
|
|
48
|
+
export {};
|
|
30
49
|
//# sourceMappingURL=todo-syncer.d.ts.map
|