ace-swarm 2.0.5 → 2.0.7
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 +17 -0
- package/assets/.agents/skills/landing-review-watcher/SKILL.md +68 -0
- package/assets/.agents/skills/problem-triage/SKILL.md +57 -0
- package/assets/.agents/skills/problem-triage/agents/openai.yaml +3 -0
- package/assets/.agents/skills/skill-auditor/SKILL.md +52 -0
- package/assets/.github/hooks/ace-copilot.json +68 -0
- package/assets/agent-state/ACE_WORKFLOW.md +66 -0
- package/assets/agent-state/INTERFACE_REGISTRY.md +50 -0
- package/assets/agent-state/MODULES/gates/gate-typescript-public-surface.json +7 -0
- package/assets/agent-state/MODULES/registry.json +10 -2
- package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +210 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +290 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_TOOL_SPEC_REGISTRY.schema.json +144 -0
- package/assets/agent-state/MODULES/schemas/TRACKER_SNAPSHOT.schema.json +134 -0
- package/assets/agent-state/MODULES/schemas/VERICIFY_BRIDGE_SNAPSHOT.schema.json +157 -0
- package/assets/agent-state/MODULES/schemas/VERICIFY_PROCESS_POST_LOG.schema.json +92 -0
- package/assets/agent-state/MODULES/schemas/WORKSPACE_SESSION_REGISTRY.schema.json +133 -0
- package/assets/agent-state/SKILL_CATALOG.md +48 -0
- package/assets/agent-state/runtime-executor-sessions.json +5 -0
- package/assets/agent-state/runtime-tool-specs.json +5 -0
- package/assets/agent-state/runtime-workspaces.json +5 -0
- package/assets/agent-state/tracker-snapshot.json +7 -0
- package/assets/agent-state/vericify/ace-bridge.json +60 -0
- package/assets/agent-state/vericify/process-posts.json +5 -0
- package/assets/scripts/bootstrap-workspace.sh +5 -0
- package/assets/scripts/copilot-hook-dispatch.mjs +267 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +312 -2
- package/dist/helpers.js.map +1 -1
- package/dist/problem-triage.d.ts +23 -0
- package/dist/problem-triage.d.ts.map +1 -0
- package/dist/problem-triage.js +429 -0
- package/dist/problem-triage.js.map +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +46 -0
- package/dist/prompts.js.map +1 -1
- package/dist/public-surface.d.ts +30 -0
- package/dist/public-surface.d.ts.map +1 -0
- package/dist/public-surface.js +310 -0
- package/dist/public-surface.js.map +1 -0
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +148 -0
- package/dist/resources.js.map +1 -1
- package/dist/runtime-command.d.ts +18 -0
- package/dist/runtime-command.d.ts.map +1 -0
- package/dist/runtime-command.js +76 -0
- package/dist/runtime-command.js.map +1 -0
- package/dist/runtime-executor.d.ts +104 -0
- package/dist/runtime-executor.d.ts.map +1 -0
- package/dist/runtime-executor.js +774 -0
- package/dist/runtime-executor.js.map +1 -0
- package/dist/runtime-profile.d.ts +98 -0
- package/dist/runtime-profile.d.ts.map +1 -0
- package/dist/runtime-profile.js +441 -0
- package/dist/runtime-profile.js.map +1 -0
- package/dist/runtime-tool-specs.d.ts +68 -0
- package/dist/runtime-tool-specs.d.ts.map +1 -0
- package/dist/runtime-tool-specs.js +424 -0
- package/dist/runtime-tool-specs.js.map +1 -0
- package/dist/schemas.d.ts +6 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +305 -0
- package/dist/schemas.js.map +1 -1
- package/dist/shared.d.ts +36 -3
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +36 -3
- package/dist/shared.js.map +1 -1
- package/dist/skill-auditor.d.ts +26 -0
- package/dist/skill-auditor.d.ts.map +1 -0
- package/dist/skill-auditor.js +184 -0
- package/dist/skill-auditor.js.map +1 -0
- package/dist/skill-catalog.d.ts +60 -0
- package/dist/skill-catalog.d.ts.map +1 -0
- package/dist/skill-catalog.js +263 -0
- package/dist/skill-catalog.js.map +1 -0
- package/dist/status-events.d.ts.map +1 -1
- package/dist/status-events.js +51 -8
- package/dist/status-events.js.map +1 -1
- package/dist/tools-agent.d.ts.map +1 -1
- package/dist/tools-agent.js +869 -0
- package/dist/tools-agent.js.map +1 -1
- package/dist/tools-files.d.ts.map +1 -1
- package/dist/tools-files.js +212 -1
- package/dist/tools-files.js.map +1 -1
- package/dist/tools-framework.d.ts.map +1 -1
- package/dist/tools-framework.js +86 -0
- package/dist/tools-framework.js.map +1 -1
- package/dist/tools-skills.d.ts +3 -0
- package/dist/tools-skills.d.ts.map +1 -0
- package/dist/tools-skills.js +104 -0
- package/dist/tools-skills.js.map +1 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +2 -0
- package/dist/tools.js.map +1 -1
- package/dist/tracker-adapters.d.ts +74 -0
- package/dist/tracker-adapters.d.ts.map +1 -0
- package/dist/tracker-adapters.js +777 -0
- package/dist/tracker-adapters.js.map +1 -0
- package/dist/tracker-sync.d.ts +10 -0
- package/dist/tracker-sync.d.ts.map +1 -0
- package/dist/tracker-sync.js +84 -0
- package/dist/tracker-sync.js.map +1 -0
- package/dist/vericify-bridge.d.ts +142 -0
- package/dist/vericify-bridge.d.ts.map +1 -0
- package/dist/vericify-bridge.js +481 -0
- package/dist/vericify-bridge.js.map +1 -0
- package/dist/workspace-manager.d.ts +103 -0
- package/dist/workspace-manager.d.ts.map +1 -0
- package/dist/workspace-manager.js +526 -0
- package/dist/workspace-manager.js.map +1 -0
- package/package.json +1 -1
package/dist/tools-agent.js
CHANGED
|
@@ -3,7 +3,38 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { ALL_AGENTS, COMPOSABLE_AGENTS, SWARM_AGENTS, SWARM_SUBAGENT_MAP, classifyPathSource, getAgentInstructionPath, getAgentManifestPath, getKernelArtifactPath, isSwarmRole, listAvailableSkills, readAgentInstructions, readAgentManifest, readKernelArtifact, readSkillInstructions, readTaskArtifact, resolveWritableTaskPath, safeWrite, } from "./helpers.js";
|
|
6
|
+
import { loadRuntimeProfile, readRuntimePromptTemplate, readRuntimeProfileState, validateRuntimeProfileContent, } from "./runtime-profile.js";
|
|
7
|
+
import { getUnattendedSession, listUnattendedSessions, startUnattendedSession, stopUnattendedSession, validateRuntimeExecutorSessionRegistryContent, waitForUnattendedSession, } from "./runtime-executor.js";
|
|
8
|
+
import { executeRuntimeTool, listRuntimeToolSpecs, loadRuntimeToolRegistry, validateRuntimeToolRegistryContent, } from "./runtime-tool-specs.js";
|
|
9
|
+
import { createWorkspaceSession, listWorkspaceSessions, removeWorkspaceSession, resolveRuntimeWorkspaceRoot, validateManagedWorkspacePath, } from "./workspace-manager.js";
|
|
10
|
+
import { getTrackerAdapter, listTrackerAdapterKinds, loadTrackerSnapshot, validateTrackerSnapshotContent, } from "./tracker-adapters.js";
|
|
11
|
+
import { refreshTrackerSnapshot } from "./tracker-sync.js";
|
|
12
|
+
import { appendVericifyProcessPost, loadVericifyBridgeSnapshot, loadVericifyProcessPostLog, refreshVericifyBridgeSnapshot, validateVericifyBridgeSnapshotContent, validateVericifyProcessPostLogContent, } from "./vericify-bridge.js";
|
|
6
13
|
import { getRoleTitle, ROLE_ENUM, KERNEL_KEY_ENUM, ROLE_TITLES } from "./shared.js";
|
|
14
|
+
function parseOptionalJsonObject(raw) {
|
|
15
|
+
if (!raw)
|
|
16
|
+
return {};
|
|
17
|
+
try {
|
|
18
|
+
const parsed = JSON.parse(raw);
|
|
19
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// fall through
|
|
25
|
+
}
|
|
26
|
+
return { raw_json: raw };
|
|
27
|
+
}
|
|
28
|
+
function parseUnknownJson(raw) {
|
|
29
|
+
if (typeof raw !== "string" || raw.trim().length === 0)
|
|
30
|
+
return {};
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(raw);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { raw };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
7
38
|
export function registerAgentTools(server) {
|
|
8
39
|
// ── Agent Instructions & Manifests ────────────────────────────────
|
|
9
40
|
server.tool("get_agent_instructions", "Load the full instruction file for a specific ACE agent role", {
|
|
@@ -116,6 +147,844 @@ export function registerAgentTools(server) {
|
|
|
116
147
|
],
|
|
117
148
|
};
|
|
118
149
|
});
|
|
150
|
+
server.tool("get_runtime_profile", "Load the active ACE runtime profile and prompt template state", {
|
|
151
|
+
path: z
|
|
152
|
+
.string()
|
|
153
|
+
.optional()
|
|
154
|
+
.describe("Optional workspace-relative path to inspect instead of the canonical runtime profile"),
|
|
155
|
+
}, async ({ path }) => {
|
|
156
|
+
const current = loadRuntimeProfile(path);
|
|
157
|
+
const active = readRuntimeProfileState();
|
|
158
|
+
return {
|
|
159
|
+
content: [
|
|
160
|
+
{
|
|
161
|
+
type: "text",
|
|
162
|
+
text: [
|
|
163
|
+
"# ACE Runtime Profile",
|
|
164
|
+
"",
|
|
165
|
+
`Current load: ${current.ok ? "valid" : "INVALID"}`,
|
|
166
|
+
`Current source: ${current.source}`,
|
|
167
|
+
`Current path: ${current.path}`,
|
|
168
|
+
current.ok
|
|
169
|
+
? `Current cache: ${current.cache_hit ? "hit" : "miss"}`
|
|
170
|
+
: "",
|
|
171
|
+
!current.ok && current.errors.length > 0
|
|
172
|
+
? ["## Current Errors", ...current.errors.map((error) => `- ${error}`)].join("\n")
|
|
173
|
+
: "",
|
|
174
|
+
"",
|
|
175
|
+
`Active source: ${active.source}`,
|
|
176
|
+
`Active path: ${active.path}`,
|
|
177
|
+
"",
|
|
178
|
+
"## Active Profile",
|
|
179
|
+
"```json",
|
|
180
|
+
JSON.stringify(active.profile, null, 2),
|
|
181
|
+
"```",
|
|
182
|
+
"",
|
|
183
|
+
"## Active Prompt Template",
|
|
184
|
+
"```md",
|
|
185
|
+
readRuntimePromptTemplate(),
|
|
186
|
+
"```",
|
|
187
|
+
]
|
|
188
|
+
.filter(Boolean)
|
|
189
|
+
.join("\n"),
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
};
|
|
193
|
+
});
|
|
194
|
+
server.tool("validate_runtime_profile", "Validate ACE runtime profile markdown content or the current ACE_WORKFLOW.md file", {
|
|
195
|
+
content: z
|
|
196
|
+
.string()
|
|
197
|
+
.optional()
|
|
198
|
+
.describe("Raw ACE_WORKFLOW.md content. If omitted, validate the selected file path."),
|
|
199
|
+
path: z
|
|
200
|
+
.string()
|
|
201
|
+
.optional()
|
|
202
|
+
.describe("Optional workspace-relative path to validate when content is omitted."),
|
|
203
|
+
}, async ({ content, path }) => {
|
|
204
|
+
const validation = typeof content === "string"
|
|
205
|
+
? validateRuntimeProfileContent(content)
|
|
206
|
+
: loadRuntimeProfile(path);
|
|
207
|
+
return {
|
|
208
|
+
content: [
|
|
209
|
+
{
|
|
210
|
+
type: "text",
|
|
211
|
+
text: validation.ok
|
|
212
|
+
? `✅ Runtime profile is valid (${validation.schema})`
|
|
213
|
+
: [
|
|
214
|
+
"❌ Runtime profile failed validation.",
|
|
215
|
+
`Schema: ${validation.schema}`,
|
|
216
|
+
...validation.errors.map((error) => `- ${error}`),
|
|
217
|
+
].join("\n"),
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
};
|
|
221
|
+
});
|
|
222
|
+
server.tool("get_runtime_tool_specs", "Load the active runtime-configured external tool spec registry", {
|
|
223
|
+
path: z
|
|
224
|
+
.string()
|
|
225
|
+
.optional()
|
|
226
|
+
.describe("Optional workspace-relative path to inspect instead of the configured runtime tool registry"),
|
|
227
|
+
}, async ({ path }) => {
|
|
228
|
+
const result = loadRuntimeToolRegistry(path);
|
|
229
|
+
return {
|
|
230
|
+
content: [
|
|
231
|
+
{
|
|
232
|
+
type: "text",
|
|
233
|
+
text: result.ok
|
|
234
|
+
? JSON.stringify({
|
|
235
|
+
schema: result.schema,
|
|
236
|
+
path: result.path,
|
|
237
|
+
source: result.source,
|
|
238
|
+
registry: result.registry,
|
|
239
|
+
}, null, 2)
|
|
240
|
+
: [
|
|
241
|
+
"❌ Runtime tool registry failed validation.",
|
|
242
|
+
`Schema: ${result.schema}`,
|
|
243
|
+
`Path: ${result.path}`,
|
|
244
|
+
...((result.errors ?? []).map((error) => `- ${error}`)),
|
|
245
|
+
].join("\n"),
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
};
|
|
249
|
+
});
|
|
250
|
+
server.tool("validate_runtime_tool_specs", "Validate runtime-tool-specs.json content or the active runtime tool registry file", {
|
|
251
|
+
content: z
|
|
252
|
+
.string()
|
|
253
|
+
.optional()
|
|
254
|
+
.describe("Raw runtime-tool-specs.json content. If omitted, validate the selected file path."),
|
|
255
|
+
path: z
|
|
256
|
+
.string()
|
|
257
|
+
.optional()
|
|
258
|
+
.describe("Optional workspace-relative path to validate when content is omitted."),
|
|
259
|
+
}, async ({ content, path }) => {
|
|
260
|
+
const validation = typeof content === "string"
|
|
261
|
+
? validateRuntimeToolRegistryContent(content)
|
|
262
|
+
: loadRuntimeToolRegistry(path);
|
|
263
|
+
return {
|
|
264
|
+
content: [
|
|
265
|
+
{
|
|
266
|
+
type: "text",
|
|
267
|
+
text: validation.ok
|
|
268
|
+
? `✅ Runtime tool registry is valid (${validation.schema})`
|
|
269
|
+
: [
|
|
270
|
+
"❌ Runtime tool registry failed validation.",
|
|
271
|
+
`Schema: ${validation.schema}`,
|
|
272
|
+
...((validation.errors ?? []).map((error) => `- ${error}`)),
|
|
273
|
+
].join("\n"),
|
|
274
|
+
},
|
|
275
|
+
],
|
|
276
|
+
};
|
|
277
|
+
});
|
|
278
|
+
server.tool("list_runtime_tool_specs", "List runtime-configured external tool specs", {}, async () => ({
|
|
279
|
+
content: [
|
|
280
|
+
{
|
|
281
|
+
type: "text",
|
|
282
|
+
text: JSON.stringify(listRuntimeToolSpecs().map((tool) => ({
|
|
283
|
+
name: tool.name,
|
|
284
|
+
description: tool.description,
|
|
285
|
+
executor: {
|
|
286
|
+
command: tool.executor.command,
|
|
287
|
+
cwd: tool.executor.cwd ?? null,
|
|
288
|
+
timeout_ms: tool.executor.timeout_ms ?? null,
|
|
289
|
+
},
|
|
290
|
+
})), null, 2),
|
|
291
|
+
},
|
|
292
|
+
],
|
|
293
|
+
}));
|
|
294
|
+
server.tool("execute_runtime_tool", "Execute a runtime-configured external tool spec by name", {
|
|
295
|
+
name: z.string().describe("Runtime tool spec name"),
|
|
296
|
+
input_json: z
|
|
297
|
+
.string()
|
|
298
|
+
.optional()
|
|
299
|
+
.describe("JSON payload validated against the tool input schema"),
|
|
300
|
+
workspace_path: z
|
|
301
|
+
.string()
|
|
302
|
+
.optional()
|
|
303
|
+
.describe("Optional workspace/session path used as the execution root"),
|
|
304
|
+
session_id: z
|
|
305
|
+
.string()
|
|
306
|
+
.optional()
|
|
307
|
+
.describe("Optional unattended session id for provenance"),
|
|
308
|
+
turn_number: z
|
|
309
|
+
.number()
|
|
310
|
+
.int()
|
|
311
|
+
.positive()
|
|
312
|
+
.optional()
|
|
313
|
+
.describe("Optional unattended session turn number for provenance"),
|
|
314
|
+
}, async ({ name, input_json, workspace_path, session_id, turn_number }) => {
|
|
315
|
+
const result = await executeRuntimeTool(name, parseUnknownJson(input_json), {
|
|
316
|
+
workspace_path,
|
|
317
|
+
session_id,
|
|
318
|
+
turn_number,
|
|
319
|
+
});
|
|
320
|
+
return {
|
|
321
|
+
content: [
|
|
322
|
+
{
|
|
323
|
+
type: "text",
|
|
324
|
+
text: JSON.stringify(result, null, 2),
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
};
|
|
328
|
+
});
|
|
329
|
+
server.tool("list_unattended_sessions", "List unattended ACE runtime executor sessions", {}, async () => ({
|
|
330
|
+
content: [
|
|
331
|
+
{
|
|
332
|
+
type: "text",
|
|
333
|
+
text: JSON.stringify(listUnattendedSessions(), null, 2),
|
|
334
|
+
},
|
|
335
|
+
],
|
|
336
|
+
}));
|
|
337
|
+
server.tool("get_unattended_session", "Get a single unattended ACE runtime executor session by id", {
|
|
338
|
+
session_id: z.string().describe("Unattended session id"),
|
|
339
|
+
}, async ({ session_id }) => ({
|
|
340
|
+
content: [
|
|
341
|
+
{
|
|
342
|
+
type: "text",
|
|
343
|
+
text: JSON.stringify(getUnattendedSession(session_id) ?? {
|
|
344
|
+
error: `Unknown unattended session: ${session_id}`,
|
|
345
|
+
}, null, 2),
|
|
346
|
+
},
|
|
347
|
+
],
|
|
348
|
+
}));
|
|
349
|
+
server.tool("validate_unattended_session_registry", "Validate runtime-executor-sessions.json content or the active unattended session registry file", {
|
|
350
|
+
content: z
|
|
351
|
+
.string()
|
|
352
|
+
.optional()
|
|
353
|
+
.describe("Raw runtime-executor-sessions.json content. If omitted, validate the active registry file."),
|
|
354
|
+
}, async ({ content }) => {
|
|
355
|
+
const validation = typeof content === "string"
|
|
356
|
+
? validateRuntimeExecutorSessionRegistryContent(content)
|
|
357
|
+
: validateRuntimeExecutorSessionRegistryContent(JSON.stringify(listUnattendedSessions(), null, 2));
|
|
358
|
+
return {
|
|
359
|
+
content: [
|
|
360
|
+
{
|
|
361
|
+
type: "text",
|
|
362
|
+
text: validation.ok
|
|
363
|
+
? `✅ Unattended session registry is valid (${validation.schema})`
|
|
364
|
+
: [
|
|
365
|
+
"❌ Unattended session registry failed validation.",
|
|
366
|
+
`Schema: ${validation.schema}`,
|
|
367
|
+
...((validation.errors ?? []).map((error) => `- ${error}`)),
|
|
368
|
+
].join("\n"),
|
|
369
|
+
},
|
|
370
|
+
],
|
|
371
|
+
};
|
|
372
|
+
});
|
|
373
|
+
server.tool("start_unattended_session", "Start a managed unattended execution session using ACE_WORKFLOW.md", {
|
|
374
|
+
task: z.string().describe("Primary objective or task for the unattended session"),
|
|
375
|
+
context_json: z
|
|
376
|
+
.string()
|
|
377
|
+
.optional()
|
|
378
|
+
.describe("Optional JSON object merged into the turn request context"),
|
|
379
|
+
workspace_name: z
|
|
380
|
+
.string()
|
|
381
|
+
.optional()
|
|
382
|
+
.describe("Optional logical workspace name for the managed session"),
|
|
383
|
+
workspace_path: z
|
|
384
|
+
.string()
|
|
385
|
+
.optional()
|
|
386
|
+
.describe("Optional explicit managed workspace path"),
|
|
387
|
+
objective_id: z.string().optional().describe("Optional linked objective id"),
|
|
388
|
+
tracker_item_id: z.string().optional().describe("Optional linked tracker item id"),
|
|
389
|
+
max_turns: z
|
|
390
|
+
.number()
|
|
391
|
+
.int()
|
|
392
|
+
.positive()
|
|
393
|
+
.optional()
|
|
394
|
+
.describe("Optional max-turn override"),
|
|
395
|
+
turn_timeout_ms: z
|
|
396
|
+
.number()
|
|
397
|
+
.int()
|
|
398
|
+
.positive()
|
|
399
|
+
.optional()
|
|
400
|
+
.describe("Optional per-turn timeout override in milliseconds"),
|
|
401
|
+
auto_cleanup: z
|
|
402
|
+
.boolean()
|
|
403
|
+
.optional()
|
|
404
|
+
.describe("If false, keep the managed workspace session after completion"),
|
|
405
|
+
}, async ({ task, context_json, workspace_name, workspace_path, objective_id, tracker_item_id, max_turns, turn_timeout_ms, auto_cleanup, }) => {
|
|
406
|
+
const result = await startUnattendedSession({
|
|
407
|
+
task,
|
|
408
|
+
context: parseOptionalJsonObject(context_json),
|
|
409
|
+
workspace_name,
|
|
410
|
+
workspace_path,
|
|
411
|
+
objective_id,
|
|
412
|
+
tracker_item_id,
|
|
413
|
+
max_turns,
|
|
414
|
+
turn_timeout_ms,
|
|
415
|
+
auto_cleanup,
|
|
416
|
+
});
|
|
417
|
+
return {
|
|
418
|
+
content: [
|
|
419
|
+
{
|
|
420
|
+
type: "text",
|
|
421
|
+
text: result.ok
|
|
422
|
+
? [
|
|
423
|
+
"✅ Unattended session started",
|
|
424
|
+
`Registry: ${result.registry_path}`,
|
|
425
|
+
"```json",
|
|
426
|
+
JSON.stringify(result.session, null, 2),
|
|
427
|
+
"```",
|
|
428
|
+
].join("\n")
|
|
429
|
+
: [
|
|
430
|
+
"❌ Unattended session failed to start",
|
|
431
|
+
result.error ?? "Unknown error",
|
|
432
|
+
].join("\n"),
|
|
433
|
+
},
|
|
434
|
+
],
|
|
435
|
+
};
|
|
436
|
+
});
|
|
437
|
+
server.tool("wait_for_unattended_session", "Wait for an unattended runtime session to reach a terminal state", {
|
|
438
|
+
session_id: z.string().describe("Unattended session id"),
|
|
439
|
+
timeout_ms: z
|
|
440
|
+
.number()
|
|
441
|
+
.int()
|
|
442
|
+
.positive()
|
|
443
|
+
.optional()
|
|
444
|
+
.describe("How long to wait before timing out"),
|
|
445
|
+
}, async ({ session_id, timeout_ms }) => {
|
|
446
|
+
const result = await waitForUnattendedSession(session_id, timeout_ms);
|
|
447
|
+
return {
|
|
448
|
+
content: [
|
|
449
|
+
{
|
|
450
|
+
type: "text",
|
|
451
|
+
text: JSON.stringify(result, null, 2),
|
|
452
|
+
},
|
|
453
|
+
],
|
|
454
|
+
};
|
|
455
|
+
});
|
|
456
|
+
server.tool("stop_unattended_session", "Stop an active unattended runtime session", {
|
|
457
|
+
session_id: z.string().describe("Unattended session id"),
|
|
458
|
+
}, async ({ session_id }) => {
|
|
459
|
+
const result = await stopUnattendedSession(session_id);
|
|
460
|
+
return {
|
|
461
|
+
content: [
|
|
462
|
+
{
|
|
463
|
+
type: "text",
|
|
464
|
+
text: JSON.stringify(result, null, 2),
|
|
465
|
+
},
|
|
466
|
+
],
|
|
467
|
+
};
|
|
468
|
+
});
|
|
469
|
+
server.tool("get_vericify_bridge", "Load the optional Vericify sidecar bridge snapshot derived from ACE runtime artifacts", {}, async () => {
|
|
470
|
+
const result = loadVericifyBridgeSnapshot();
|
|
471
|
+
return {
|
|
472
|
+
content: [
|
|
473
|
+
{
|
|
474
|
+
type: "text",
|
|
475
|
+
text: result.ok
|
|
476
|
+
? JSON.stringify({
|
|
477
|
+
schema: result.schema,
|
|
478
|
+
path: result.path,
|
|
479
|
+
snapshot: result.snapshot,
|
|
480
|
+
}, null, 2)
|
|
481
|
+
: [
|
|
482
|
+
"❌ Vericify bridge snapshot failed validation.",
|
|
483
|
+
`Schema: ${result.schema}`,
|
|
484
|
+
`Path: ${result.path}`,
|
|
485
|
+
...((result.errors ?? []).map((error) => `- ${error}`)),
|
|
486
|
+
].join("\n"),
|
|
487
|
+
},
|
|
488
|
+
],
|
|
489
|
+
};
|
|
490
|
+
});
|
|
491
|
+
server.tool("refresh_vericify_bridge", "Refresh the optional Vericify sidecar bridge snapshot from current ACE runtime artifacts", {}, async () => {
|
|
492
|
+
const result = refreshVericifyBridgeSnapshot();
|
|
493
|
+
return {
|
|
494
|
+
content: [
|
|
495
|
+
{
|
|
496
|
+
type: "text",
|
|
497
|
+
text: result.ok
|
|
498
|
+
? [
|
|
499
|
+
"✅ Vericify bridge refreshed",
|
|
500
|
+
`Path: ${result.path}`,
|
|
501
|
+
"```json",
|
|
502
|
+
JSON.stringify(result.snapshot, null, 2),
|
|
503
|
+
"```",
|
|
504
|
+
].join("\n")
|
|
505
|
+
: [
|
|
506
|
+
"❌ Vericify bridge refresh failed",
|
|
507
|
+
`Path: ${result.path}`,
|
|
508
|
+
result.error ?? "Unknown error",
|
|
509
|
+
].join("\n"),
|
|
510
|
+
},
|
|
511
|
+
],
|
|
512
|
+
};
|
|
513
|
+
});
|
|
514
|
+
server.tool("validate_vericify_bridge", "Validate the Vericify bridge snapshot content or active file", {
|
|
515
|
+
content: z
|
|
516
|
+
.string()
|
|
517
|
+
.optional()
|
|
518
|
+
.describe("Raw Vericify bridge snapshot JSON. If omitted, validate the active bridge file."),
|
|
519
|
+
}, async ({ content }) => {
|
|
520
|
+
const validation = typeof content === "string"
|
|
521
|
+
? validateVericifyBridgeSnapshotContent(content)
|
|
522
|
+
: loadVericifyBridgeSnapshot();
|
|
523
|
+
return {
|
|
524
|
+
content: [
|
|
525
|
+
{
|
|
526
|
+
type: "text",
|
|
527
|
+
text: validation.ok
|
|
528
|
+
? `✅ Vericify bridge snapshot is valid (${validation.schema})`
|
|
529
|
+
: [
|
|
530
|
+
"❌ Vericify bridge snapshot failed validation.",
|
|
531
|
+
`Schema: ${validation.schema}`,
|
|
532
|
+
...((validation.errors ?? []).map((error) => `- ${error}`)),
|
|
533
|
+
].join("\n"),
|
|
534
|
+
},
|
|
535
|
+
],
|
|
536
|
+
};
|
|
537
|
+
});
|
|
538
|
+
server.tool("get_vericify_process_posts", "Load the optional Vericify sidecar process-post log maintained by ACE", {}, async () => {
|
|
539
|
+
const result = loadVericifyProcessPostLog();
|
|
540
|
+
return {
|
|
541
|
+
content: [
|
|
542
|
+
{
|
|
543
|
+
type: "text",
|
|
544
|
+
text: result.ok
|
|
545
|
+
? JSON.stringify({
|
|
546
|
+
schema: result.schema,
|
|
547
|
+
path: result.path,
|
|
548
|
+
log: result.log,
|
|
549
|
+
}, null, 2)
|
|
550
|
+
: [
|
|
551
|
+
"❌ Vericify process post log failed validation.",
|
|
552
|
+
`Schema: ${result.schema}`,
|
|
553
|
+
`Path: ${result.path}`,
|
|
554
|
+
...((result.errors ?? []).map((error) => `- ${error}`)),
|
|
555
|
+
].join("\n"),
|
|
556
|
+
},
|
|
557
|
+
],
|
|
558
|
+
};
|
|
559
|
+
});
|
|
560
|
+
server.tool("append_vericify_process_post", "Append a structured process post to the optional Vericify sidecar log without requiring Vericify to be installed", {
|
|
561
|
+
run_id: z.string().describe("Vericify run id"),
|
|
562
|
+
branch_id: z.string().optional().describe("Optional Vericify branch id"),
|
|
563
|
+
lane_id: z.string().optional().describe("Optional Vericify lane id"),
|
|
564
|
+
agent_id: z.string().describe("Posting agent/module id"),
|
|
565
|
+
kind: z
|
|
566
|
+
.enum(["intent", "progress", "blocker", "handoff_note", "completion"])
|
|
567
|
+
.describe("Structured process post kind"),
|
|
568
|
+
summary: z.string().describe("Short operator-facing summary"),
|
|
569
|
+
tool_refs: z
|
|
570
|
+
.array(z.string())
|
|
571
|
+
.optional()
|
|
572
|
+
.describe("Optional tool references attached to the process post"),
|
|
573
|
+
evidence_refs: z
|
|
574
|
+
.array(z.string())
|
|
575
|
+
.optional()
|
|
576
|
+
.describe("Optional evidence references attached to the process post"),
|
|
577
|
+
checkpoint_ref: z.string().optional().describe("Optional checkpoint id"),
|
|
578
|
+
}, async ({ run_id, branch_id, lane_id, agent_id, kind, summary, tool_refs, evidence_refs, checkpoint_ref }) => {
|
|
579
|
+
const result = await appendVericifyProcessPost({
|
|
580
|
+
run_id,
|
|
581
|
+
branch_id,
|
|
582
|
+
lane_id,
|
|
583
|
+
agent_id,
|
|
584
|
+
kind,
|
|
585
|
+
summary,
|
|
586
|
+
tool_refs,
|
|
587
|
+
evidence_refs,
|
|
588
|
+
checkpoint_ref,
|
|
589
|
+
});
|
|
590
|
+
return {
|
|
591
|
+
content: [
|
|
592
|
+
{
|
|
593
|
+
type: "text",
|
|
594
|
+
text: [
|
|
595
|
+
"✅ Vericify process post appended",
|
|
596
|
+
`Path: ${result.path}`,
|
|
597
|
+
"```json",
|
|
598
|
+
JSON.stringify(result.post, null, 2),
|
|
599
|
+
"```",
|
|
600
|
+
].join("\n"),
|
|
601
|
+
},
|
|
602
|
+
],
|
|
603
|
+
};
|
|
604
|
+
});
|
|
605
|
+
server.tool("validate_vericify_process_post_log", "Validate the Vericify process-post log content or active file", {
|
|
606
|
+
content: z
|
|
607
|
+
.string()
|
|
608
|
+
.optional()
|
|
609
|
+
.describe("Raw Vericify process-post log JSON. If omitted, validate the active log file."),
|
|
610
|
+
}, async ({ content }) => {
|
|
611
|
+
const validation = typeof content === "string"
|
|
612
|
+
? validateVericifyProcessPostLogContent(content)
|
|
613
|
+
: loadVericifyProcessPostLog();
|
|
614
|
+
return {
|
|
615
|
+
content: [
|
|
616
|
+
{
|
|
617
|
+
type: "text",
|
|
618
|
+
text: validation.ok
|
|
619
|
+
? `✅ Vericify process post log is valid (${validation.schema})`
|
|
620
|
+
: [
|
|
621
|
+
"❌ Vericify process post log failed validation.",
|
|
622
|
+
`Schema: ${validation.schema}`,
|
|
623
|
+
...((validation.errors ?? []).map((error) => `- ${error}`)),
|
|
624
|
+
].join("\n"),
|
|
625
|
+
},
|
|
626
|
+
],
|
|
627
|
+
};
|
|
628
|
+
});
|
|
629
|
+
server.tool("list_workspace_sessions", "List managed ACE workspace sessions from the runtime registry", {}, async () => ({
|
|
630
|
+
content: [
|
|
631
|
+
{
|
|
632
|
+
type: "text",
|
|
633
|
+
text: JSON.stringify(listWorkspaceSessions(), null, 2),
|
|
634
|
+
},
|
|
635
|
+
],
|
|
636
|
+
}));
|
|
637
|
+
server.tool("validate_managed_workspace_path", "Validate a target path against the configured managed workspace root and path-safety invariants", {
|
|
638
|
+
target: z.string().describe("Target workspace path or relative child path"),
|
|
639
|
+
root: z
|
|
640
|
+
.string()
|
|
641
|
+
.optional()
|
|
642
|
+
.describe("Optional root override. Defaults to the runtime profile workspace root."),
|
|
643
|
+
}, async ({ target, root }) => {
|
|
644
|
+
const resolvedRoot = resolveRuntimeWorkspaceRoot(root);
|
|
645
|
+
const validation = validateManagedWorkspacePath(resolvedRoot, target);
|
|
646
|
+
return {
|
|
647
|
+
content: [
|
|
648
|
+
{
|
|
649
|
+
type: "text",
|
|
650
|
+
text: JSON.stringify(validation, null, 2),
|
|
651
|
+
},
|
|
652
|
+
],
|
|
653
|
+
};
|
|
654
|
+
});
|
|
655
|
+
server.tool("create_workspace_session", "Create a managed ACE workspace session under the configured runtime root", {
|
|
656
|
+
workspace_name: z
|
|
657
|
+
.string()
|
|
658
|
+
.optional()
|
|
659
|
+
.describe("Logical workspace name used to derive the managed directory name"),
|
|
660
|
+
workspace_path: z
|
|
661
|
+
.string()
|
|
662
|
+
.optional()
|
|
663
|
+
.describe("Optional explicit target path. Relative paths are resolved under the managed root."),
|
|
664
|
+
source: z
|
|
665
|
+
.enum(["manual", "executor", "test"])
|
|
666
|
+
.describe("How this workspace session was created"),
|
|
667
|
+
objective_id: z.string().optional().describe("Optional linked objective id"),
|
|
668
|
+
tracker_item_id: z.string().optional().describe("Optional linked tracker item id"),
|
|
669
|
+
root: z
|
|
670
|
+
.string()
|
|
671
|
+
.optional()
|
|
672
|
+
.describe("Optional root override. Defaults to the runtime profile workspace root."),
|
|
673
|
+
hooks_timeout_ms: z
|
|
674
|
+
.number()
|
|
675
|
+
.int()
|
|
676
|
+
.positive()
|
|
677
|
+
.optional()
|
|
678
|
+
.describe("Optional hook timeout override in milliseconds"),
|
|
679
|
+
}, async ({ workspace_name, workspace_path, source, objective_id, tracker_item_id, root, hooks_timeout_ms, }) => {
|
|
680
|
+
const result = createWorkspaceSession({
|
|
681
|
+
workspace_name,
|
|
682
|
+
workspace_path,
|
|
683
|
+
source,
|
|
684
|
+
objective_id,
|
|
685
|
+
tracker_item_id,
|
|
686
|
+
root,
|
|
687
|
+
hooks_timeout_ms,
|
|
688
|
+
});
|
|
689
|
+
return {
|
|
690
|
+
content: [
|
|
691
|
+
{
|
|
692
|
+
type: "text",
|
|
693
|
+
text: result.ok
|
|
694
|
+
? [
|
|
695
|
+
"✅ Workspace session created",
|
|
696
|
+
`Registry: ${result.registry_path}`,
|
|
697
|
+
"```json",
|
|
698
|
+
JSON.stringify(result.session, null, 2),
|
|
699
|
+
"```",
|
|
700
|
+
].join("\n")
|
|
701
|
+
: [
|
|
702
|
+
"❌ Workspace session create failed",
|
|
703
|
+
result.error ?? "Unknown error",
|
|
704
|
+
result.validation ? "```json" : "",
|
|
705
|
+
result.validation ? JSON.stringify(result.validation, null, 2) : "",
|
|
706
|
+
result.validation ? "```" : "",
|
|
707
|
+
]
|
|
708
|
+
.filter(Boolean)
|
|
709
|
+
.join("\n"),
|
|
710
|
+
},
|
|
711
|
+
],
|
|
712
|
+
};
|
|
713
|
+
});
|
|
714
|
+
server.tool("remove_workspace_session", "Remove or archive a managed ACE workspace session using the runtime retention policy", {
|
|
715
|
+
session_id: z.string().optional().describe("Managed workspace session id"),
|
|
716
|
+
workspace_path: z
|
|
717
|
+
.string()
|
|
718
|
+
.optional()
|
|
719
|
+
.describe("Managed workspace path when removing by path instead of session id"),
|
|
720
|
+
root: z
|
|
721
|
+
.string()
|
|
722
|
+
.optional()
|
|
723
|
+
.describe("Optional root override. Defaults to the runtime profile workspace root."),
|
|
724
|
+
hooks_timeout_ms: z
|
|
725
|
+
.number()
|
|
726
|
+
.int()
|
|
727
|
+
.positive()
|
|
728
|
+
.optional()
|
|
729
|
+
.describe("Optional hook timeout override in milliseconds"),
|
|
730
|
+
}, async ({ session_id, workspace_path, root, hooks_timeout_ms }) => {
|
|
731
|
+
const result = removeWorkspaceSession({
|
|
732
|
+
session_id,
|
|
733
|
+
workspace_path,
|
|
734
|
+
root,
|
|
735
|
+
hooks_timeout_ms,
|
|
736
|
+
});
|
|
737
|
+
return {
|
|
738
|
+
content: [
|
|
739
|
+
{
|
|
740
|
+
type: "text",
|
|
741
|
+
text: result.ok
|
|
742
|
+
? [
|
|
743
|
+
"✅ Workspace session updated",
|
|
744
|
+
`Registry: ${result.registry_path}`,
|
|
745
|
+
"```json",
|
|
746
|
+
JSON.stringify(result.session, null, 2),
|
|
747
|
+
"```",
|
|
748
|
+
].join("\n")
|
|
749
|
+
: [
|
|
750
|
+
"❌ Workspace session removal failed",
|
|
751
|
+
result.error ?? "Unknown error",
|
|
752
|
+
result.validation ? "```json" : "",
|
|
753
|
+
result.validation ? JSON.stringify(result.validation, null, 2) : "",
|
|
754
|
+
result.validation ? "```" : "",
|
|
755
|
+
]
|
|
756
|
+
.filter(Boolean)
|
|
757
|
+
.join("\n"),
|
|
758
|
+
},
|
|
759
|
+
],
|
|
760
|
+
};
|
|
761
|
+
});
|
|
762
|
+
server.tool("get_tracker_snapshot", "Load the active normalized ACE tracker snapshot", {
|
|
763
|
+
path: z
|
|
764
|
+
.string()
|
|
765
|
+
.optional()
|
|
766
|
+
.describe("Optional workspace-relative path override for a tracker snapshot file."),
|
|
767
|
+
}, async ({ path }) => {
|
|
768
|
+
const result = loadTrackerSnapshot(path);
|
|
769
|
+
return {
|
|
770
|
+
content: [
|
|
771
|
+
{
|
|
772
|
+
type: "text",
|
|
773
|
+
text: result.ok
|
|
774
|
+
? JSON.stringify({
|
|
775
|
+
schema: result.schema,
|
|
776
|
+
path: result.path,
|
|
777
|
+
source: result.source,
|
|
778
|
+
snapshot: result.snapshot,
|
|
779
|
+
}, null, 2)
|
|
780
|
+
: [
|
|
781
|
+
"❌ Tracker snapshot failed validation.",
|
|
782
|
+
`Schema: ${result.schema}`,
|
|
783
|
+
`Path: ${result.path}`,
|
|
784
|
+
...((result.errors ?? []).map((error) => `- ${error}`)),
|
|
785
|
+
].join("\n"),
|
|
786
|
+
},
|
|
787
|
+
],
|
|
788
|
+
};
|
|
789
|
+
});
|
|
790
|
+
server.tool("validate_tracker_snapshot", "Validate tracker-snapshot.json content or the active snapshot file", {
|
|
791
|
+
content: z
|
|
792
|
+
.string()
|
|
793
|
+
.optional()
|
|
794
|
+
.describe("Raw tracker snapshot JSON content. If omitted, validate the selected file path."),
|
|
795
|
+
path: z
|
|
796
|
+
.string()
|
|
797
|
+
.optional()
|
|
798
|
+
.describe("Optional workspace-relative path to validate when content is omitted."),
|
|
799
|
+
}, async ({ content, path }) => {
|
|
800
|
+
const validation = typeof content === "string"
|
|
801
|
+
? validateTrackerSnapshotContent(content)
|
|
802
|
+
: loadTrackerSnapshot(path);
|
|
803
|
+
return {
|
|
804
|
+
content: [
|
|
805
|
+
{
|
|
806
|
+
type: "text",
|
|
807
|
+
text: validation.ok
|
|
808
|
+
? `✅ Tracker snapshot is valid (${validation.schema})`
|
|
809
|
+
: [
|
|
810
|
+
"❌ Tracker snapshot failed validation.",
|
|
811
|
+
`Schema: ${validation.schema}`,
|
|
812
|
+
...((validation.errors ?? []).map((error) => `- ${error}`)),
|
|
813
|
+
].join("\n"),
|
|
814
|
+
},
|
|
815
|
+
],
|
|
816
|
+
};
|
|
817
|
+
});
|
|
818
|
+
server.tool("list_tracker_adapter_kinds", "List available ACE tracker adapter kinds", {}, async () => ({
|
|
819
|
+
content: [
|
|
820
|
+
{
|
|
821
|
+
type: "text",
|
|
822
|
+
text: JSON.stringify(listTrackerAdapterKinds(), null, 2),
|
|
823
|
+
},
|
|
824
|
+
],
|
|
825
|
+
}));
|
|
826
|
+
server.tool("get_tracker_adapter_health", "Run the active or selected tracker adapter health check", {
|
|
827
|
+
kind: z
|
|
828
|
+
.string()
|
|
829
|
+
.optional()
|
|
830
|
+
.describe("Optional tracker adapter kind override (none, memory, external)"),
|
|
831
|
+
}, async ({ kind }) => {
|
|
832
|
+
try {
|
|
833
|
+
const adapter = getTrackerAdapter(kind);
|
|
834
|
+
const health = adapter.healthCheck
|
|
835
|
+
? await adapter.healthCheck()
|
|
836
|
+
: { ok: true, detail: "No health check implemented." };
|
|
837
|
+
return {
|
|
838
|
+
content: [
|
|
839
|
+
{
|
|
840
|
+
type: "text",
|
|
841
|
+
text: JSON.stringify({
|
|
842
|
+
kind: adapter.kind,
|
|
843
|
+
...health,
|
|
844
|
+
}, null, 2),
|
|
845
|
+
},
|
|
846
|
+
],
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
catch (error) {
|
|
850
|
+
return {
|
|
851
|
+
content: [
|
|
852
|
+
{
|
|
853
|
+
type: "text",
|
|
854
|
+
text: `❌ ${error instanceof Error ? error.message : String(error)}`,
|
|
855
|
+
},
|
|
856
|
+
],
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
server.tool("list_tracker_items", "List normalized tracker items through the active or selected tracker adapter", {
|
|
861
|
+
kind: z
|
|
862
|
+
.string()
|
|
863
|
+
.optional()
|
|
864
|
+
.describe("Optional tracker adapter kind override (none, memory, external)"),
|
|
865
|
+
ids: z.array(z.string()).optional().describe("Optional item ids or external ids to include"),
|
|
866
|
+
states: z.array(z.string()).optional().describe("Optional allowed item states"),
|
|
867
|
+
labels: z.array(z.string()).optional().describe("Optional required labels"),
|
|
868
|
+
assignee: z.string().optional().describe("Optional assignee filter"),
|
|
869
|
+
query: z
|
|
870
|
+
.string()
|
|
871
|
+
.optional()
|
|
872
|
+
.describe("Optional case-insensitive title/body substring filter"),
|
|
873
|
+
}, async ({ kind, ids, states, labels, assignee, query }) => {
|
|
874
|
+
const adapter = getTrackerAdapter(kind);
|
|
875
|
+
const items = adapter.listActiveItems
|
|
876
|
+
? await adapter.listActiveItems({
|
|
877
|
+
ids,
|
|
878
|
+
states,
|
|
879
|
+
labels,
|
|
880
|
+
assignee,
|
|
881
|
+
query,
|
|
882
|
+
})
|
|
883
|
+
: [];
|
|
884
|
+
return {
|
|
885
|
+
content: [
|
|
886
|
+
{
|
|
887
|
+
type: "text",
|
|
888
|
+
text: JSON.stringify(items, null, 2),
|
|
889
|
+
},
|
|
890
|
+
],
|
|
891
|
+
};
|
|
892
|
+
});
|
|
893
|
+
server.tool("create_tracker_comment", "Create a tracker comment through the active or selected adapter", {
|
|
894
|
+
item_id: z.string().describe("Normalized tracker item id"),
|
|
895
|
+
body: z.string().describe("Comment body"),
|
|
896
|
+
kind: z
|
|
897
|
+
.string()
|
|
898
|
+
.optional()
|
|
899
|
+
.describe("Optional tracker adapter kind override (none, memory, external)"),
|
|
900
|
+
}, async ({ item_id, body, kind }) => {
|
|
901
|
+
const adapter = getTrackerAdapter(kind);
|
|
902
|
+
const result = adapter.createComment
|
|
903
|
+
? await adapter.createComment(item_id, body)
|
|
904
|
+
: { ok: false, error: `Tracker adapter '${adapter.kind}' does not support comments.` };
|
|
905
|
+
return {
|
|
906
|
+
content: [
|
|
907
|
+
{
|
|
908
|
+
type: "text",
|
|
909
|
+
text: result.ok
|
|
910
|
+
? [
|
|
911
|
+
"✅ Tracker comment created",
|
|
912
|
+
`Adapter: ${adapter.kind}`,
|
|
913
|
+
result.comment_id ? `Comment ID: ${result.comment_id}` : "",
|
|
914
|
+
]
|
|
915
|
+
.filter(Boolean)
|
|
916
|
+
.join("\n")
|
|
917
|
+
: [
|
|
918
|
+
"❌ Tracker comment failed",
|
|
919
|
+
`Adapter: ${adapter.kind}`,
|
|
920
|
+
result.error ?? "Unknown error",
|
|
921
|
+
].join("\n"),
|
|
922
|
+
},
|
|
923
|
+
],
|
|
924
|
+
};
|
|
925
|
+
});
|
|
926
|
+
server.tool("update_tracker_item_state", "Update a tracker item state through the active or selected adapter", {
|
|
927
|
+
item_id: z.string().describe("Normalized tracker item id"),
|
|
928
|
+
state: z.string().describe("New tracker state"),
|
|
929
|
+
kind: z
|
|
930
|
+
.string()
|
|
931
|
+
.optional()
|
|
932
|
+
.describe("Optional tracker adapter kind override (none, memory, external)"),
|
|
933
|
+
}, async ({ item_id, state, kind }) => {
|
|
934
|
+
const adapter = getTrackerAdapter(kind);
|
|
935
|
+
const result = adapter.updateItemState
|
|
936
|
+
? await adapter.updateItemState(item_id, state)
|
|
937
|
+
: { ok: false, error: `Tracker adapter '${adapter.kind}' does not support state updates.` };
|
|
938
|
+
return {
|
|
939
|
+
content: [
|
|
940
|
+
{
|
|
941
|
+
type: "text",
|
|
942
|
+
text: result.ok
|
|
943
|
+
? [
|
|
944
|
+
"✅ Tracker state updated",
|
|
945
|
+
`Adapter: ${adapter.kind}`,
|
|
946
|
+
`Item: ${item_id}`,
|
|
947
|
+
`State: ${state}`,
|
|
948
|
+
].join("\n")
|
|
949
|
+
: [
|
|
950
|
+
"❌ Tracker state update failed",
|
|
951
|
+
`Adapter: ${adapter.kind}`,
|
|
952
|
+
result.error ?? "Unknown error",
|
|
953
|
+
].join("\n"),
|
|
954
|
+
},
|
|
955
|
+
],
|
|
956
|
+
};
|
|
957
|
+
});
|
|
958
|
+
server.tool("refresh_tracker_snapshot", "Refresh tracker-snapshot.json through the active or selected tracker adapter", {
|
|
959
|
+
kind: z
|
|
960
|
+
.string()
|
|
961
|
+
.optional()
|
|
962
|
+
.describe("Optional tracker adapter kind override (none, memory, external)"),
|
|
963
|
+
}, async ({ kind }) => {
|
|
964
|
+
const result = await refreshTrackerSnapshot(kind);
|
|
965
|
+
return {
|
|
966
|
+
content: [
|
|
967
|
+
{
|
|
968
|
+
type: "text",
|
|
969
|
+
text: result.ok
|
|
970
|
+
? [
|
|
971
|
+
"✅ Tracker snapshot refreshed",
|
|
972
|
+
`Adapter: ${result.adapter_kind}`,
|
|
973
|
+
`Path: ${result.snapshot_path}`,
|
|
974
|
+
"```json",
|
|
975
|
+
JSON.stringify(result.snapshot, null, 2),
|
|
976
|
+
"```",
|
|
977
|
+
].join("\n")
|
|
978
|
+
: [
|
|
979
|
+
"❌ Tracker snapshot refresh failed",
|
|
980
|
+
`Adapter: ${result.adapter_kind}`,
|
|
981
|
+
`Path: ${result.snapshot_path}`,
|
|
982
|
+
result.error ?? "Unknown error",
|
|
983
|
+
].join("\n"),
|
|
984
|
+
},
|
|
985
|
+
],
|
|
986
|
+
};
|
|
987
|
+
});
|
|
119
988
|
// ── Skills ────────────────────────────────────────────────────────
|
|
120
989
|
server.tool("list_skills", "List all discoverable ACE skills with source paths", {}, async () => {
|
|
121
990
|
const skills = listAvailableSkills();
|