@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
package/dist/tools-scheduler.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Job scheduler tool registrations.
|
|
3
3
|
*/
|
|
4
4
|
import { z } from "zod";
|
|
5
|
+
import { resolveWorkspaceRoot } from "./helpers.js";
|
|
5
6
|
import { acknowledgeJob, completeJob, dispatchJobNow, dispatchJobs, enqueueJob, getJobLockTablePath, getJobQueuePath, getSchedulerLeasePath, heartbeatJob, reapStaleRunningJobsTick, readJobQueue, readJobLockTable, readSchedulerLease, } from "./job-scheduler.js";
|
|
6
7
|
// Event emission handled in core job-scheduler.ts — no wrapper duplication.
|
|
7
8
|
const PRIORITY_BAND_ENUM = z.enum(["P0", "P1", "P2", "P3"]);
|
|
@@ -22,6 +23,7 @@ function asJsonBlock(value) {
|
|
|
22
23
|
return `\`\`\`json\n${JSON.stringify(value, null, 2)}\n\`\`\``;
|
|
23
24
|
}
|
|
24
25
|
export function registerSchedulerTools(server) {
|
|
26
|
+
const workspaceRoot = resolveWorkspaceRoot();
|
|
25
27
|
server.tool("enqueue_job", "Add a handoff job to the scheduler queue with priority/dependency/resource metadata", {
|
|
26
28
|
kind: z.string().describe("Job kind/type identifier"),
|
|
27
29
|
payload: z
|
|
@@ -46,7 +48,7 @@ export function registerSchedulerTools(server) {
|
|
|
46
48
|
backoff_ms: z.number().int().min(1000).max(86_400_000).optional(),
|
|
47
49
|
job_id: z.string().optional().describe("Optional caller-provided job id"),
|
|
48
50
|
}, async (input) => {
|
|
49
|
-
const result = await enqueueJob(input);
|
|
51
|
+
const result = await enqueueJob(input, workspaceRoot);
|
|
50
52
|
return {
|
|
51
53
|
content: [
|
|
52
54
|
{
|
|
@@ -78,15 +80,15 @@ export function registerSchedulerTools(server) {
|
|
|
78
80
|
.describe("Include lock table payload (default true)"),
|
|
79
81
|
limit: z.number().int().min(1).max(1000).optional().describe("Max jobs returned"),
|
|
80
82
|
}, async ({ status, include_locks, limit }) => {
|
|
81
|
-
const queue = readJobQueue();
|
|
83
|
+
const queue = readJobQueue(workspaceRoot);
|
|
82
84
|
const filtered = queue.jobs.filter((job) => (status ? job.status === status : true));
|
|
83
85
|
const clipped = typeof limit === "number" ? filtered.slice(0, limit) : filtered;
|
|
84
|
-
const lockTable = readJobLockTable();
|
|
85
|
-
const lease = readSchedulerLease();
|
|
86
|
+
const lockTable = readJobLockTable(workspaceRoot);
|
|
87
|
+
const lease = readSchedulerLease(workspaceRoot);
|
|
86
88
|
const payload = {
|
|
87
|
-
queue_path: getJobQueuePath(),
|
|
88
|
-
lock_path: getJobLockTablePath(),
|
|
89
|
-
lease_path: getSchedulerLeasePath(),
|
|
89
|
+
queue_path: getJobQueuePath(workspaceRoot),
|
|
90
|
+
lock_path: getJobLockTablePath(workspaceRoot),
|
|
91
|
+
lease_path: getSchedulerLeasePath(workspaceRoot),
|
|
90
92
|
total_jobs: queue.jobs.length,
|
|
91
93
|
returned_jobs: clipped.length,
|
|
92
94
|
jobs: clipped,
|
|
@@ -109,7 +111,7 @@ export function registerSchedulerTools(server) {
|
|
|
109
111
|
action: z.enum(["accept", "reject", "cancel", "resume"]),
|
|
110
112
|
reason: z.string().optional(),
|
|
111
113
|
}, async ({ job_id, action, reason }) => {
|
|
112
|
-
const result = await acknowledgeJob({ job_id, action, reason });
|
|
114
|
+
const result = await acknowledgeJob({ job_id, action, reason }, workspaceRoot);
|
|
113
115
|
return {
|
|
114
116
|
content: [
|
|
115
117
|
{
|
|
@@ -135,7 +137,7 @@ export function registerSchedulerTools(server) {
|
|
|
135
137
|
lease_ttl_seconds: z.number().int().min(5).max(3600).optional(),
|
|
136
138
|
now_iso: z.string().optional().describe("Optional deterministic clock override"),
|
|
137
139
|
}, async (input) => {
|
|
138
|
-
const result = await dispatchJobs(input);
|
|
140
|
+
const result = await dispatchJobs(input, workspaceRoot);
|
|
139
141
|
return {
|
|
140
142
|
content: [
|
|
141
143
|
{
|
|
@@ -144,6 +146,7 @@ export function registerSchedulerTools(server) {
|
|
|
144
146
|
result.ok ? "✅ Scheduler dispatch completed" : "⚠️ Scheduler lease not acquired",
|
|
145
147
|
`Owner: ${result.owner}`,
|
|
146
148
|
`Lease acquired: ${result.lease_acquired}`,
|
|
149
|
+
`Lease retained for execution: ${result.lease_retained}`,
|
|
147
150
|
`Queue: ${result.queue_path}`,
|
|
148
151
|
`Locks: ${result.lock_path}`,
|
|
149
152
|
asJsonBlock(result),
|
|
@@ -157,7 +160,7 @@ export function registerSchedulerTools(server) {
|
|
|
157
160
|
owner: z.string().optional(),
|
|
158
161
|
now_iso: z.string().optional(),
|
|
159
162
|
}, async ({ job_id, owner, now_iso }) => {
|
|
160
|
-
const result = await dispatchJobNow({ job_id, owner, now_iso });
|
|
163
|
+
const result = await dispatchJobNow({ job_id, owner, now_iso }, workspaceRoot);
|
|
161
164
|
return {
|
|
162
165
|
content: [
|
|
163
166
|
{
|
|
@@ -184,7 +187,7 @@ export function registerSchedulerTools(server) {
|
|
|
184
187
|
evidence_ref,
|
|
185
188
|
error,
|
|
186
189
|
now_iso,
|
|
187
|
-
});
|
|
190
|
+
}, workspaceRoot);
|
|
188
191
|
return {
|
|
189
192
|
content: [
|
|
190
193
|
{
|
|
@@ -202,7 +205,7 @@ export function registerSchedulerTools(server) {
|
|
|
202
205
|
lease_ttl_seconds: z.number().int().min(5).max(3600).optional(),
|
|
203
206
|
now_iso: z.string().optional().describe("Optional deterministic clock override"),
|
|
204
207
|
}, async ({ job_id, owner, lease_ttl_seconds, now_iso }) => {
|
|
205
|
-
const result = await heartbeatJob({ job_id, owner, lease_ttl_seconds, now_iso });
|
|
208
|
+
const result = await heartbeatJob({ job_id, owner, lease_ttl_seconds, now_iso }, workspaceRoot);
|
|
206
209
|
return {
|
|
207
210
|
content: [
|
|
208
211
|
{
|
|
@@ -224,7 +227,7 @@ export function registerSchedulerTools(server) {
|
|
|
224
227
|
.describe("Staleness window in seconds (default 120)"),
|
|
225
228
|
now_iso: z.string().optional().describe("Optional deterministic clock override"),
|
|
226
229
|
}, async ({ heartbeat_stale_seconds, now_iso }) => {
|
|
227
|
-
const result = await reapStaleRunningJobsTick({ heartbeat_stale_seconds, now_iso });
|
|
230
|
+
const result = await reapStaleRunningJobsTick({ heartbeat_stale_seconds, now_iso }, workspaceRoot);
|
|
228
231
|
return {
|
|
229
232
|
content: [
|
|
230
233
|
{
|
|
@@ -246,9 +249,9 @@ export function registerSchedulerTools(server) {
|
|
|
246
249
|
text: [
|
|
247
250
|
"# Lock Table",
|
|
248
251
|
"",
|
|
249
|
-
`Path: ${getJobLockTablePath()}`,
|
|
252
|
+
`Path: ${getJobLockTablePath(workspaceRoot)}`,
|
|
250
253
|
"",
|
|
251
|
-
asJsonBlock(readJobLockTable()),
|
|
254
|
+
asJsonBlock(readJobLockTable(workspaceRoot)),
|
|
252
255
|
].join("\n"),
|
|
253
256
|
},
|
|
254
257
|
],
|
|
@@ -260,9 +263,9 @@ export function registerSchedulerTools(server) {
|
|
|
260
263
|
text: [
|
|
261
264
|
"# Scheduler Lease",
|
|
262
265
|
"",
|
|
263
|
-
`Path: ${getSchedulerLeasePath()}`,
|
|
266
|
+
`Path: ${getSchedulerLeasePath(workspaceRoot)}`,
|
|
264
267
|
"",
|
|
265
|
-
asJsonBlock(readSchedulerLease() ?? null),
|
|
268
|
+
asJsonBlock(readSchedulerLease(workspaceRoot) ?? null),
|
|
266
269
|
].join("\n"),
|
|
267
270
|
},
|
|
268
271
|
],
|
package/dist/tools-todo.js
CHANGED
|
@@ -1,35 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
* TODO, task management, and run-ledger tool registrations.
|
|
3
|
-
*/
|
|
1
|
+
import { resolveCurrentWork, formatCurrentWork } from "./ace-autonomy.js";
|
|
4
2
|
import { z } from "zod";
|
|
5
|
-
import { ACE_TASKS_ROOT_REL,
|
|
3
|
+
import { ACE_TASKS_ROOT_REL, resolveWritableTaskPath, } from "./helpers.js";
|
|
6
4
|
import { TODO_STATUS_ENUM } from "./shared.js";
|
|
7
|
-
import { appendTodoItemSafe,
|
|
5
|
+
import { appendTodoItemSafe, deleteTodoItemSafe, getTodoStatePath, syncTodoStateSafe, transitionTodoNodeSafe, } from "./todo-state.js";
|
|
8
6
|
import { appendRunLedgerEntrySafe, getRunLedgerPath, readRunLedger, } from "./run-ledger.js";
|
|
9
|
-
import { refreshKanbanArtifacts } from "./kanban.js";
|
|
7
|
+
import { formatKanbanRefresh, refreshKanbanArtifacts } from "./kanban.js";
|
|
8
|
+
import { hostAgent } from './host-work-context.js';
|
|
9
|
+
import { readStoreJsonSync } from './store/store-snapshot.js';
|
|
10
|
+
import { resolveWorkspaceRoot } from './helpers.js';
|
|
11
|
+
import { GoalRepository } from './store/repositories/goal-repository.js';
|
|
12
|
+
import { deriveLinkedTodo } from './linked-work.js';
|
|
13
|
+
function todoRefusal(reason_code, message, options = [{ tool: "get_todo_state", args: {}, why: "Read current task identities and statuses." }]) {
|
|
14
|
+
const now = formatCurrentWork(resolveCurrentWork(), "line");
|
|
15
|
+
return { isError: true, structuredContent: { reason_code, message, options, now }, content: [{ type: "text", text: [message, ...options.map((o) => `${o.tool}(${JSON.stringify(o.args)}): ${o.why}`), now].join("\n") }] };
|
|
16
|
+
}
|
|
17
|
+
function importNotes(result) {
|
|
18
|
+
return [...(result.import_warnings ?? []).map((warning) => `Import warning: ${warning}`), ...(result.projection_pending ? ["Canonical todo state is current; markdown refresh pending."] : [])].join("\n");
|
|
19
|
+
}
|
|
10
20
|
export function registerTodoTools(server) {
|
|
11
|
-
server.tool("get_todo", "Read the current swarm TODO execution board", {}, async () =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
],
|
|
21
|
-
}));
|
|
22
|
-
server.tool("update_todo", "Replace TODO board content, append a new TODO item, or transition a TODO node status with gate validation", {
|
|
21
|
+
server.tool("get_todo", "Read the current swarm TODO execution board", {}, async () => {
|
|
22
|
+
const synced = await syncTodoStateSafe();
|
|
23
|
+
return { structuredContent: { ...synced }, content: [{ type: "text", text: [synced.markdown, importNotes(synced)].filter(Boolean).join("\n") }] };
|
|
24
|
+
});
|
|
25
|
+
server.tool("get_todo_state", "Read synced TODO node state with dependencies and explicit statuses", {}, async () => {
|
|
26
|
+
const synced = await syncTodoStateSafe();
|
|
27
|
+
return { structuredContent: { ...synced }, content: [{ type: "text", text: `# TODO State\n\nPath: ${getTodoStatePath()}\n\n\`\`\`json\n${JSON.stringify(synced.state, null, 2)}\n\`\`\`\n${importNotes(synced)}` }] };
|
|
28
|
+
});
|
|
29
|
+
server.tool("update_todo", "Import TODO edits without deleting absent rows; append, explicitly delete, or transition a task", {
|
|
23
30
|
new_content: z
|
|
24
31
|
.string()
|
|
25
32
|
.optional()
|
|
26
|
-
.describe("
|
|
33
|
+
.describe("TODO markdown to import; omitted rows are retained, use delete_id to remove"),
|
|
34
|
+
delete_id: z.string().optional().describe("Explicitly delete this task; omission from markdown never deletes"),
|
|
27
35
|
node_id: z
|
|
28
36
|
.string()
|
|
29
37
|
.optional()
|
|
30
38
|
.describe("Todo node id to transition (transition mode)"),
|
|
31
39
|
status: TODO_STATUS_ENUM.optional().describe("Target status for transition mode"),
|
|
32
40
|
note: z.string().optional().describe("Optional transition context note"),
|
|
41
|
+
agent: z.string().optional().describe('Host label when completing a linked goal step'),
|
|
33
42
|
append_title: z
|
|
34
43
|
.string()
|
|
35
44
|
.optional()
|
|
@@ -48,146 +57,149 @@ export function registerTodoTools(server) {
|
|
|
48
57
|
.string()
|
|
49
58
|
.optional()
|
|
50
59
|
.describe("Optional explicit node id for the new append-mode item"),
|
|
51
|
-
}, async ({ new_content, node_id, status, note, append_title, append_section, append_depends_on, append_id, }) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
}, async ({ new_content, delete_id, node_id, status, note, append_title, append_section, append_depends_on, append_id, agent, }, extra) => {
|
|
61
|
+
try {
|
|
62
|
+
if (delete_id) {
|
|
63
|
+
const deleted = await deleteTodoItemSafe(delete_id);
|
|
64
|
+
if (!deleted.ok)
|
|
65
|
+
return todoRefusal("unknown_todo", deleted.error ?? "Todo not found.");
|
|
66
|
+
const kanban = refreshKanbanArtifacts("tool:update_todo");
|
|
67
|
+
return { structuredContent: { ...deleted }, content: [{ type: "text", text: [`TODO deleted: ${delete_id}`, importNotes(deleted), formatKanbanRefresh(kanban)].filter(Boolean).join("\n") }] };
|
|
68
|
+
}
|
|
69
|
+
if (typeof append_title === "string") {
|
|
70
|
+
const appended = await appendTodoItemSafe(append_title, {
|
|
71
|
+
section: append_section,
|
|
72
|
+
depends_on: append_depends_on,
|
|
73
|
+
id: append_id,
|
|
74
|
+
});
|
|
75
|
+
if (!appended.ok) {
|
|
76
|
+
return todoRefusal("todo_append_rejected", appended.error ?? "Failed to append TODO item.");
|
|
77
|
+
}
|
|
78
|
+
const runLedger = await appendRunLedgerEntrySafe({
|
|
79
|
+
tool: "update_todo",
|
|
80
|
+
category: "info",
|
|
81
|
+
message: `Appended TODO item ${appended.node_id}`,
|
|
82
|
+
artifacts: [`${ACE_TASKS_ROOT_REL}/todo.md`, "agent-state/todo-state.json"],
|
|
83
|
+
metadata: {
|
|
84
|
+
mode: "append",
|
|
85
|
+
node_id: appended.node_id,
|
|
86
|
+
todo_id: appended.node_id,
|
|
87
|
+
section: appended.section,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
const kanban = refreshKanbanArtifacts("tool:update_todo");
|
|
91
|
+
const counts = kanban.counts;
|
|
59
92
|
return {
|
|
93
|
+
structuredContent: { ...appended },
|
|
60
94
|
content: [
|
|
61
|
-
{
|
|
95
|
+
{
|
|
96
|
+
type: "text",
|
|
97
|
+
text: [
|
|
98
|
+
`✅ TODO item appended: ${appended.node_id}`,
|
|
99
|
+
`Section: ${appended.section}`,
|
|
100
|
+
`TODO state: ${appended.path}`,
|
|
101
|
+
`TODO markdown: ${appended.todo_path}`,
|
|
102
|
+
importNotes(appended),
|
|
103
|
+
`Run ledger: ${runLedger.path} (${runLedger.entry.id})`,
|
|
104
|
+
formatKanbanRefresh(kanban),
|
|
105
|
+
`Kanban counts: backlog=${counts.backlog}, blocked=${counts.blocked}, in_progress=${counts.in_progress}, gated=${counts.gated}, done=${counts.done}`,
|
|
106
|
+
].join("\n"),
|
|
107
|
+
},
|
|
62
108
|
],
|
|
63
109
|
};
|
|
64
110
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const kanban = refreshKanbanArtifacts("tool:update_todo");
|
|
77
|
-
const counts = kanban.counts;
|
|
78
|
-
return {
|
|
79
|
-
content: [
|
|
80
|
-
{
|
|
81
|
-
type: "text",
|
|
82
|
-
text: [
|
|
83
|
-
`✅ TODO item appended: ${appended.node_id}`,
|
|
84
|
-
`Section: ${appended.section}`,
|
|
85
|
-
`TODO state: ${appended.path}`,
|
|
86
|
-
`TODO markdown: ${appended.todo_path}`,
|
|
87
|
-
`Run ledger: ${runLedger.path} (${runLedger.entry.id})`,
|
|
88
|
-
`Kanban updated: ${kanban.html_path}`,
|
|
89
|
-
`Kanban counts: backlog=${counts.backlog}, blocked=${counts.blocked}, in_progress=${counts.in_progress}, gated=${counts.gated}, done=${counts.done}`,
|
|
90
|
-
].join("\n"),
|
|
111
|
+
if (typeof new_content === "string") {
|
|
112
|
+
const synced = await syncTodoStateSafe(new_content);
|
|
113
|
+
const path = resolveWritableTaskPath("todo");
|
|
114
|
+
const runLedger = await appendRunLedgerEntrySafe({
|
|
115
|
+
tool: "update_todo",
|
|
116
|
+
category: "major_update",
|
|
117
|
+
message: "Imported TODO markdown edits; omitted tasks retained",
|
|
118
|
+
artifacts: [`${ACE_TASKS_ROOT_REL}/todo.md`, "agent-state/todo-state.json"],
|
|
119
|
+
metadata: {
|
|
120
|
+
mode: "replace",
|
|
121
|
+
node_count: synced.state.order.length,
|
|
91
122
|
},
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (typeof new_content === "string") {
|
|
96
|
-
const synced = await syncTodoStateSafe(new_content);
|
|
97
|
-
const path = await safeWriteAsync(resolveWritableTaskPath("todo"), new_content);
|
|
98
|
-
const runLedger = await appendRunLedgerEntrySafe({
|
|
99
|
-
tool: "update_todo",
|
|
100
|
-
category: "major_update",
|
|
101
|
-
message: "Replaced TODO markdown board content",
|
|
102
|
-
artifacts: [`${ACE_TASKS_ROOT_REL}/todo.md`, "agent-state/todo-state.json"],
|
|
103
|
-
metadata: {
|
|
104
|
-
mode: "replace",
|
|
105
|
-
node_count: synced.state.order.length,
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
const kanban = refreshKanbanArtifacts("tool:update_todo");
|
|
109
|
-
const counts = kanban.counts;
|
|
110
|
-
return {
|
|
111
|
-
content: [
|
|
112
|
-
{
|
|
113
|
-
type: "text",
|
|
114
|
-
text: [
|
|
115
|
-
`✅ TODO updated: ${path}`,
|
|
116
|
-
`TODO state synced: ${synced.path}`,
|
|
117
|
-
`Run ledger: ${runLedger.path} (${runLedger.entry.id})`,
|
|
118
|
-
`Kanban updated: ${kanban.html_path}`,
|
|
119
|
-
`Kanban counts: backlog=${counts.backlog}, blocked=${counts.blocked}, in_progress=${counts.in_progress}, gated=${counts.gated}, done=${counts.done}`,
|
|
120
|
-
].join("\n"),
|
|
121
|
-
},
|
|
122
|
-
],
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
if (node_id && status) {
|
|
126
|
-
const transition = await transitionTodoNodeSafe(node_id, status);
|
|
127
|
-
if (!transition.ok) {
|
|
128
|
-
const detailLines = [
|
|
129
|
-
transition.error
|
|
130
|
-
? `❌ ${transition.error}`
|
|
131
|
-
: "❌ TODO transition failed.",
|
|
132
|
-
transition.node_id ? `Node: ${transition.node_id}` : "",
|
|
133
|
-
transition.from && transition.to
|
|
134
|
-
? `Attempted: ${transition.from} -> ${transition.to}`
|
|
135
|
-
: "",
|
|
136
|
-
transition.allowed?.length
|
|
137
|
-
? `Allowed next states: ${transition.allowed.join(", ")}`
|
|
138
|
-
: "",
|
|
139
|
-
transition.unresolved_dependencies?.length
|
|
140
|
-
? `Unresolved dependencies: ${transition.unresolved_dependencies.join(", ")}`
|
|
141
|
-
: "",
|
|
142
|
-
].filter(Boolean);
|
|
123
|
+
});
|
|
124
|
+
const kanban = refreshKanbanArtifacts("tool:update_todo");
|
|
125
|
+
const counts = kanban.counts;
|
|
143
126
|
return {
|
|
144
|
-
|
|
127
|
+
structuredContent: { ...synced },
|
|
128
|
+
content: [
|
|
129
|
+
{
|
|
130
|
+
type: "text",
|
|
131
|
+
text: [
|
|
132
|
+
`✅ TODO updated: ${path}`,
|
|
133
|
+
`TODO state synced: ${synced.path}`,
|
|
134
|
+
importNotes(synced),
|
|
135
|
+
`Run ledger: ${runLedger.path} (${runLedger.entry.id})`,
|
|
136
|
+
formatKanbanRefresh(kanban),
|
|
137
|
+
`Kanban counts: backlog=${counts.backlog}, blocked=${counts.blocked}, in_progress=${counts.in_progress}, gated=${counts.gated}, done=${counts.done}`,
|
|
138
|
+
].join("\n"),
|
|
139
|
+
},
|
|
140
|
+
],
|
|
145
141
|
};
|
|
146
142
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
143
|
+
if (node_id && status) {
|
|
144
|
+
const rawTodo = readStoreJsonSync(resolveWorkspaceRoot(), `state/todo/${node_id}`);
|
|
145
|
+
const linked = rawTodo && deriveLinkedTodo(rawTodo, resolveWorkspaceRoot()).step_ref;
|
|
146
|
+
if (linked) {
|
|
147
|
+
if (status !== 'done' && status !== 'blocked')
|
|
148
|
+
return todoRefusal('linked_step_owned', 'This todo is a step view. Use next_step to start/resume its goal; complete_step records its outcome.');
|
|
149
|
+
const step = new GoalRepository(resolveWorkspaceRoot()).getPlan(linked.goal_id)?.steps.find(s => s.step_id === linked.step_id);
|
|
150
|
+
const { completeStep } = await import('./host-goal-engine.js');
|
|
151
|
+
const result = await completeStep(linked.goal_id, linked.step_id, { status, summary: note || `Todo ${node_id} ${status}`, evidence: [{ ref: `host:todo:${node_id}`, kind: 'note', detail: note }] }, { agent: hostAgent(agent, extra.sessionId), attempt: step?.attempt ?? 0 });
|
|
152
|
+
return { isError: !!result.isError, structuredContent: { ...result }, content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
153
|
+
}
|
|
154
|
+
const transition = await transitionTodoNodeSafe(node_id, status);
|
|
155
|
+
if (!transition.ok) {
|
|
156
|
+
const reason = transition.unresolved_dependencies?.length ? "todo_dependencies_unmet" : transition.allowed ? "todo_transition_invalid" : "unknown_todo";
|
|
157
|
+
return todoRefusal(reason, [transition.error ?? "TODO transition failed.", transition.allowed?.length ? `Allowed next states: ${transition.allowed.join(", ")}.` : "", transition.unresolved_dependencies?.length ? `Waiting on: ${transition.unresolved_dependencies.join(", ")}.` : ""].filter(Boolean).join(" "));
|
|
158
|
+
}
|
|
159
|
+
const previous = transition.from ?? status;
|
|
160
|
+
const category = previous === "done" && status !== "done"
|
|
161
|
+
? "regression"
|
|
162
|
+
: "major_update";
|
|
163
|
+
const runLedger = await appendRunLedgerEntrySafe({
|
|
164
|
+
tool: "update_todo",
|
|
165
|
+
category,
|
|
166
|
+
message: `Transitioned TODO node ${node_id}: ${previous} -> ${status}`,
|
|
167
|
+
artifacts: [`${ACE_TASKS_ROOT_REL}/todo.md`, "agent-state/todo-state.json"],
|
|
168
|
+
metadata: {
|
|
169
|
+
mode: "transition",
|
|
170
|
+
node_id,
|
|
171
|
+
todo_id: node_id,
|
|
172
|
+
from: previous,
|
|
173
|
+
to: status,
|
|
174
|
+
note: note ?? "",
|
|
179
175
|
},
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
});
|
|
177
|
+
const kanban = refreshKanbanArtifacts("tool:update_todo");
|
|
178
|
+
const counts = kanban.counts;
|
|
179
|
+
return {
|
|
180
|
+
structuredContent: { ...transition },
|
|
181
|
+
content: [
|
|
182
|
+
{
|
|
183
|
+
type: "text",
|
|
184
|
+
text: [
|
|
185
|
+
`✅ TODO transition applied: ${node_id}`,
|
|
186
|
+
`Transition: ${previous} -> ${status}`,
|
|
187
|
+
`TODO state: ${transition.path}`,
|
|
188
|
+
`TODO markdown: ${transition.todo_path}`,
|
|
189
|
+
importNotes(transition),
|
|
190
|
+
`Run ledger: ${runLedger.path} (${runLedger.entry.id})`,
|
|
191
|
+
formatKanbanRefresh(kanban),
|
|
192
|
+
`Kanban counts: backlog=${counts.backlog}, blocked=${counts.blocked}, in_progress=${counts.in_progress}, gated=${counts.gated}, done=${counts.done}`,
|
|
193
|
+
].join("\n"),
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return todoRefusal("todo_arguments_missing", "Provide append_title, new_content, delete_id, or node_id with status.");
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
return todoRefusal("todo_write_failed", `Could not save the todo change: ${error instanceof Error ? error.message : String(error)}`);
|
|
182
202
|
}
|
|
183
|
-
return {
|
|
184
|
-
content: [
|
|
185
|
-
{
|
|
186
|
-
type: "text",
|
|
187
|
-
text: "❌ Provide either `new_content` (full replace) or `node_id` + `status` (transition mode).",
|
|
188
|
-
},
|
|
189
|
-
],
|
|
190
|
-
};
|
|
191
203
|
});
|
|
192
204
|
server.tool("get_run_ledger", "Read run-ledger milestone/regression history", {
|
|
193
205
|
limit: z
|
|
@@ -137,6 +137,14 @@ export declare function appendVericifyProcessPostSafe(input: {
|
|
|
137
137
|
post?: VericifyProcessPost;
|
|
138
138
|
error?: string;
|
|
139
139
|
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Compatibility sink for ACE-generated summaries. Native Vericify owns process
|
|
142
|
+
* capture; these duplicate posts are disabled unless an operator explicitly
|
|
143
|
+
* requests the legacy recorder. Manual APIs above remain available unchanged.
|
|
144
|
+
*/
|
|
145
|
+
export declare function appendAutomaticVericifyProcessPostSafe(input: Parameters<typeof appendVericifyProcessPostSafe>[0]): Promise<Awaited<ReturnType<typeof appendVericifyProcessPostSafe>> & {
|
|
146
|
+
skipped?: boolean;
|
|
147
|
+
}>;
|
|
140
148
|
export declare function buildVericifyBridgeSnapshot(): VericifyBridgeSnapshot;
|
|
141
149
|
export declare function refreshVericifyBridgeSnapshot(): {
|
|
142
150
|
ok: boolean;
|
package/dist/vericify-bridge.js
CHANGED
|
@@ -95,11 +95,17 @@ function parseBridgeSnapshot(raw) {
|
|
|
95
95
|
function readBridgeConfig() {
|
|
96
96
|
const config = readRuntimeProfile().observability.vericify_bridge ?? {
|
|
97
97
|
enabled: false,
|
|
98
|
+
legacy_auto_posts: false,
|
|
99
|
+
native: { enabled: false },
|
|
98
100
|
bridge_path: VERICIFY_BRIDGE_SNAPSHOT_REL_PATH,
|
|
99
101
|
process_post_path: VERICIFY_PROCESS_POST_LOG_REL_PATH,
|
|
100
102
|
};
|
|
101
103
|
return {
|
|
102
104
|
enabled: Boolean(config.enabled),
|
|
105
|
+
// Older profiles only carried `enabled`, which controls bridge reads and
|
|
106
|
+
// explicit manual APIs. It does not opt into a second automatic recorder.
|
|
107
|
+
legacy_auto_posts: config.legacy_auto_posts === true,
|
|
108
|
+
native_enabled: config.native?.enabled === true,
|
|
103
109
|
bridge_path: config.bridge_path || VERICIFY_BRIDGE_SNAPSHOT_REL_PATH,
|
|
104
110
|
process_post_path: config.process_post_path || VERICIFY_PROCESS_POST_LOG_REL_PATH,
|
|
105
111
|
};
|
|
@@ -426,6 +432,18 @@ export async function appendVericifyProcessPostSafe(input) {
|
|
|
426
432
|
};
|
|
427
433
|
}
|
|
428
434
|
}
|
|
435
|
+
/**
|
|
436
|
+
* Compatibility sink for ACE-generated summaries. Native Vericify owns process
|
|
437
|
+
* capture; these duplicate posts are disabled unless an operator explicitly
|
|
438
|
+
* requests the legacy recorder. Manual APIs above remain available unchanged.
|
|
439
|
+
*/
|
|
440
|
+
export async function appendAutomaticVericifyProcessPostSafe(input) {
|
|
441
|
+
const config = readBridgeConfig();
|
|
442
|
+
if (!config.enabled || !config.legacy_auto_posts || config.native_enabled) {
|
|
443
|
+
return { ok: true, skipped: true, path: processPostLogPath() };
|
|
444
|
+
}
|
|
445
|
+
return appendVericifyProcessPostSafe(input);
|
|
446
|
+
}
|
|
429
447
|
function buildActiveRunRefs() {
|
|
430
448
|
const executorRegistryPath = "agent-state/runtime-executor-sessions.json";
|
|
431
449
|
const raw = readConfiguredText(executorRegistryPath);
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import { createNativeObservationAdapter } from "./vericify-native.js";
|
|
1
2
|
export declare function getVericifyContextPacket(input?: {
|
|
2
3
|
workspaceRoot?: string;
|
|
3
4
|
runId?: string;
|
|
5
|
+
mode?: "configured" | "legacy";
|
|
4
6
|
}): Promise<Record<string, unknown>>;
|
|
5
7
|
export declare function getVericifyDelta(input: {
|
|
6
8
|
since: string;
|
|
7
9
|
workspaceRoot?: string;
|
|
8
10
|
runId?: string;
|
|
11
|
+
mode?: "configured" | "legacy";
|
|
9
12
|
}): Promise<Record<string, unknown>>;
|
|
13
|
+
export declare function configuredObservationAdapter(workspaceRoot: string): ReturnType<typeof createNativeObservationAdapter> | undefined;
|
|
10
14
|
//# sourceMappingURL=vericify-context.d.ts.map
|
package/dist/vericify-context.js
CHANGED
|
@@ -2,7 +2,9 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { dirname, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
|
-
import { resolveWorkspaceRoot } from "./helpers.js";
|
|
5
|
+
import { resolveWorkspaceRoot, withWorkspaceRoot } from "./helpers.js";
|
|
6
|
+
import { readRuntimeProfile } from "./runtime-profile.js";
|
|
7
|
+
import { createNativeObservationAdapter, getNativeVericifyContext } from "./vericify-native.js";
|
|
6
8
|
const requireFromModule = createRequire(import.meta.url);
|
|
7
9
|
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
8
10
|
function tryResolveVericifyApi(searchFrom) {
|
|
@@ -47,8 +49,8 @@ function resolveVericifyApiPath(workspaceRoot) {
|
|
|
47
49
|
"or set VERICIFY_API_PATH to an installed `vericify/api` entry file.",
|
|
48
50
|
].join(" "));
|
|
49
51
|
}
|
|
50
|
-
async function loadVericifyApi(workspaceRoot) {
|
|
51
|
-
const apiPath = resolveVericifyApiPath(workspaceRoot);
|
|
52
|
+
async function loadVericifyApi(workspaceRoot, explicitPath) {
|
|
53
|
+
const apiPath = explicitPath ? resolve(explicitPath) : resolveVericifyApiPath(workspaceRoot);
|
|
52
54
|
const loaded = await import(pathToFileURL(apiPath).href);
|
|
53
55
|
if (typeof loaded.loadWorkspaceState !== "function" ||
|
|
54
56
|
typeof loaded.buildCompactPacket !== "function" ||
|
|
@@ -62,7 +64,12 @@ export async function getVericifyContextPacket(input) {
|
|
|
62
64
|
const workspaceRoot = input?.workspaceRoot
|
|
63
65
|
? resolve(input.workspaceRoot)
|
|
64
66
|
: resolveWorkspaceRoot();
|
|
65
|
-
const
|
|
67
|
+
const configured = input?.mode === "configured" ? configuredVericify(workspaceRoot) : undefined;
|
|
68
|
+
if (configured?.native?.enabled)
|
|
69
|
+
return { ...(await getNativeVericifyContext({ config: configured.native, workspaceRoot })) };
|
|
70
|
+
if (input?.mode === "configured" && !configured?.apiPath)
|
|
71
|
+
return { status: "unavailable", reason_code: "vericify_not_configured", records: [] };
|
|
72
|
+
const api = await loadVericifyApi(workspaceRoot, configured?.apiPath);
|
|
66
73
|
const workspaceState = api.loadWorkspaceState(workspaceRoot);
|
|
67
74
|
const projected = api.projectWorkspaceState(workspaceState);
|
|
68
75
|
return api.buildCompactPacket(projected, {
|
|
@@ -73,7 +80,12 @@ export async function getVericifyDelta(input) {
|
|
|
73
80
|
const workspaceRoot = input.workspaceRoot
|
|
74
81
|
? resolve(input.workspaceRoot)
|
|
75
82
|
: resolveWorkspaceRoot();
|
|
76
|
-
const
|
|
83
|
+
const configured = input.mode === "configured" ? configuredVericify(workspaceRoot) : undefined;
|
|
84
|
+
if (configured?.native?.enabled)
|
|
85
|
+
return { ...(await getNativeVericifyContext({ config: configured.native, workspaceRoot, since: input.since })) };
|
|
86
|
+
if (input.mode === "configured" && !configured?.apiPath)
|
|
87
|
+
return { status: "unavailable", reason_code: "vericify_not_configured", records: [] };
|
|
88
|
+
const api = await loadVericifyApi(workspaceRoot, configured?.apiPath);
|
|
77
89
|
const workspaceState = api.loadWorkspaceState(workspaceRoot);
|
|
78
90
|
const projected = api.projectWorkspaceState(workspaceState);
|
|
79
91
|
return api.buildCompactDelta(projected, {
|
|
@@ -81,4 +93,13 @@ export async function getVericifyDelta(input) {
|
|
|
81
93
|
since: input.since,
|
|
82
94
|
});
|
|
83
95
|
}
|
|
96
|
+
/** Explicit public configuration; programmatic legacy helpers above retain historical discovery. */
|
|
97
|
+
function configuredVericify(workspaceRoot) {
|
|
98
|
+
const bridge = withWorkspaceRoot(workspaceRoot, () => readRuntimeProfile().observability.vericify_bridge);
|
|
99
|
+
return { native: bridge?.native, apiPath: bridge?.api_path || process.env.VERICIFY_API_PATH?.trim() };
|
|
100
|
+
}
|
|
101
|
+
export function configuredObservationAdapter(workspaceRoot) {
|
|
102
|
+
const config = configuredVericify(workspaceRoot).native;
|
|
103
|
+
return config?.enabled ? createNativeObservationAdapter(config, workspaceRoot) : undefined;
|
|
104
|
+
}
|
|
84
105
|
//# sourceMappingURL=vericify-context.js.map
|