@arcbridge/mcp-server 0.1.6 → 0.2.1
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 +3 -2
- package/dist/index.js +222 -153
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -40,8 +40,8 @@ function registerInitProject(server, ctx) {
|
|
|
40
40
|
"Initialize ArcBridge in a project directory. Creates .arcbridge/ with arc42 documentation, phase plan, agent roles, SQLite database, and platform-specific configs.",
|
|
41
41
|
{
|
|
42
42
|
name: z.string().min(1).describe("Project name"),
|
|
43
|
-
template: z.enum(["nextjs-app-router", "react-vite", "api-service", "dotnet-webapi"]).default("nextjs-app-router").describe(
|
|
44
|
-
"Project template: nextjs-app-router (Next.js with App Router, SSR/SSG), react-vite (React SPA with Vite, client-only), api-service (Node.js API with Express/Fastify/Hono), dotnet-webapi (ASP.NET Core Web API, C#)"
|
|
43
|
+
template: z.enum(["nextjs-app-router", "react-vite", "api-service", "dotnet-webapi", "unity-game"]).default("nextjs-app-router").describe(
|
|
44
|
+
"Project template: nextjs-app-router (Next.js with App Router, SSR/SSG), react-vite (React SPA with Vite, client-only), api-service (Node.js API with Express/Fastify/Hono), dotnet-webapi (ASP.NET Core Web API, C#), unity-game (Unity game project, C#, code-heavy)"
|
|
45
45
|
),
|
|
46
46
|
features: z.array(z.enum(["auth", "database", "api"])).default([]).describe("Features to scaffold"),
|
|
47
47
|
quality_priorities: z.array(z.string()).default(["security", "performance", "accessibility", "maintainability"]).describe("Quality priorities in order"),
|
|
@@ -189,15 +189,17 @@ Use \`arcbridge_get_project_status\` to see the current state.`
|
|
|
189
189
|
...allWarnings.map((w) => `- ${w}`)
|
|
190
190
|
] : [],
|
|
191
191
|
"",
|
|
192
|
-
"## Next Steps \u2014
|
|
192
|
+
"## Next Steps \u2014 TAILOR FIRST, BUILD SECOND",
|
|
193
193
|
"",
|
|
194
|
-
"**Do not start implementing yet.**
|
|
194
|
+
"**Do not start implementing yet.** The generated building blocks, quality scenarios, and phase tasks are a generic starting template. Tailor them to this project first:",
|
|
195
195
|
"",
|
|
196
196
|
"1. **Activate the architect role** \u2014 run `arcbridge_activate_role` with role `architect`",
|
|
197
197
|
"2. **Review the spec** \u2014 read `.arcbridge/spec.md` (if provided) and understand the full scope",
|
|
198
|
-
"3. **
|
|
199
|
-
"4. **
|
|
200
|
-
"5. **
|
|
198
|
+
"3. **Tailor building blocks** \u2014 edit `.arcbridge/arc42/05-building-blocks.md`: delete blocks that don't apply, add blocks for your real modules, and declare `interfaces` between blocks (drift detection depends on this)",
|
|
199
|
+
"4. **Tailor quality scenarios** \u2014 edit `.arcbridge/arc42/10-quality-scenarios.yaml`: delete irrelevant scenarios, add ones that match your actual requirements",
|
|
200
|
+
"5. **Tailor phase tasks** \u2014 Phase 0-1 tasks are ready to use. Phase 2+ tasks are examples only \u2014 **delete them** (edit `.arcbridge/plan/tasks/<phase>.yaml` or use `arcbridge_delete_task`) and create real tasks from the project's requirements using `arcbridge_create_task`. Add more phases with `arcbridge_create_phase` if needed.",
|
|
201
|
+
"6. **Reindex** \u2014 run `arcbridge_reindex` to pick up your changes",
|
|
202
|
+
"7. **Then start building** \u2014 use `arcbridge_get_current_tasks` to see what to do next",
|
|
201
203
|
"",
|
|
202
204
|
"Use `arcbridge_get_project_status` to see the full project status."
|
|
203
205
|
];
|
|
@@ -1073,40 +1075,62 @@ If you need a new block, add it to \`.arcbridge/arc42/05-building-blocks.md\` an
|
|
|
1073
1075
|
|
|
1074
1076
|
// src/tools/delete-task.ts
|
|
1075
1077
|
import { z as z10 } from "zod";
|
|
1076
|
-
import { deleteTaskFromYaml } from "@arcbridge/core";
|
|
1078
|
+
import { deleteTaskFromYaml, refreshFromDocs as refreshFromDocs4 } from "@arcbridge/core";
|
|
1077
1079
|
function registerDeleteTask(server, ctx) {
|
|
1078
1080
|
server.tool(
|
|
1079
1081
|
"arcbridge_delete_task",
|
|
1080
|
-
"Delete
|
|
1082
|
+
"Delete one or more tasks permanently. Use this to remove example/template tasks or duplicates. Pass task_ids (array) for batch deletion, or task_id (string) for a single task. For tasks that were planned but are no longer relevant, prefer `arcbridge_update_task` with status 'cancelled' instead \u2014 this preserves the decision trail.",
|
|
1081
1083
|
{
|
|
1082
1084
|
target_dir: z10.string().describe("Absolute path to the project directory"),
|
|
1083
|
-
task_id: z10.string().describe("
|
|
1085
|
+
task_id: z10.string().optional().describe("Single task ID to delete (deprecated \u2014 use task_ids)"),
|
|
1086
|
+
task_ids: z10.array(z10.string()).optional().describe("Task IDs to delete (preferred)")
|
|
1084
1087
|
},
|
|
1085
1088
|
async (params) => {
|
|
1086
1089
|
const db = ensureDb(ctx, params.target_dir);
|
|
1087
1090
|
if (!db) return notInitialized();
|
|
1088
|
-
const
|
|
1089
|
-
if (
|
|
1090
|
-
return textResult(
|
|
1091
|
-
|
|
1092
|
-
|
|
1091
|
+
const ids = params.task_ids ?? (params.task_id ? [params.task_id] : []);
|
|
1092
|
+
if (ids.length === 0) {
|
|
1093
|
+
return textResult("Provide `task_ids` (array) or `task_id` (string) to delete.");
|
|
1094
|
+
}
|
|
1095
|
+
const results = [];
|
|
1096
|
+
const warnings = [];
|
|
1097
|
+
for (const id of ids) {
|
|
1098
|
+
const task = db.prepare("SELECT id, title, phase_id FROM tasks WHERE id = ?").get(id);
|
|
1099
|
+
if (!task) {
|
|
1100
|
+
warnings.push(`Task '${id}' not found \u2014 skipped`);
|
|
1101
|
+
continue;
|
|
1102
|
+
}
|
|
1103
|
+
const yamlResult = deleteTaskFromYaml(params.target_dir, task.phase_id, id);
|
|
1104
|
+
if (yamlResult.success === false) {
|
|
1105
|
+
warnings.push(`${task.id}: ${yamlResult.warning ?? "YAML delete failed"}`);
|
|
1106
|
+
} else {
|
|
1107
|
+
results.push(`- **${task.id}**: "${task.title}"`);
|
|
1108
|
+
if (yamlResult.warning) {
|
|
1109
|
+
warnings.push(`${task.id}: ${yamlResult.warning}`);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1093
1112
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
const msg = `Task **${task.id}** deleted: "${task.title}"`;
|
|
1097
|
-
if (yamlResult.warning) {
|
|
1098
|
-
return textResult(`${msg}
|
|
1099
|
-
|
|
1100
|
-
**Warning:** ${yamlResult.warning}`);
|
|
1113
|
+
if (results.length > 0) {
|
|
1114
|
+
refreshFromDocs4(db, params.target_dir);
|
|
1101
1115
|
}
|
|
1102
|
-
|
|
1116
|
+
const lines = [];
|
|
1117
|
+
if (results.length > 0) {
|
|
1118
|
+
lines.push(`Deleted ${results.length} task${results.length === 1 ? "" : "s"}:`, "", ...results);
|
|
1119
|
+
}
|
|
1120
|
+
if (warnings.length > 0) {
|
|
1121
|
+
lines.push("", "**Warnings:**", ...warnings.map((w) => `- ${w}`));
|
|
1122
|
+
}
|
|
1123
|
+
if (results.length === 0 && warnings.length > 0) {
|
|
1124
|
+
lines.unshift("No tasks were deleted.");
|
|
1125
|
+
}
|
|
1126
|
+
return textResult(lines.join("\n"));
|
|
1103
1127
|
}
|
|
1104
1128
|
);
|
|
1105
1129
|
}
|
|
1106
1130
|
|
|
1107
1131
|
// src/tools/create-phase.ts
|
|
1108
1132
|
import { z as z11 } from "zod";
|
|
1109
|
-
import { addPhaseToYaml, refreshFromDocs as
|
|
1133
|
+
import { addPhaseToYaml, refreshFromDocs as refreshFromDocs5 } from "@arcbridge/core";
|
|
1110
1134
|
function registerCreatePhase(server, ctx) {
|
|
1111
1135
|
server.tool(
|
|
1112
1136
|
"arcbridge_create_phase",
|
|
@@ -1121,7 +1145,7 @@ function registerCreatePhase(server, ctx) {
|
|
|
1121
1145
|
async (params) => {
|
|
1122
1146
|
const db = ensureDb(ctx, params.target_dir);
|
|
1123
1147
|
if (!db) return notInitialized();
|
|
1124
|
-
|
|
1148
|
+
refreshFromDocs5(db, params.target_dir);
|
|
1125
1149
|
const maxPhase = db.prepare("SELECT MAX(phase_number) as max FROM phases").get();
|
|
1126
1150
|
const phaseNumber = params.phase_number ?? (maxPhase.max ?? -1) + 1;
|
|
1127
1151
|
const existing = db.prepare("SELECT id FROM phases WHERE phase_number = ?").get(phaseNumber);
|
|
@@ -1144,7 +1168,7 @@ function registerCreatePhase(server, ctx) {
|
|
|
1144
1168
|
`Failed to create phase: ${yamlResult.warning ?? "YAML update failed"}`
|
|
1145
1169
|
);
|
|
1146
1170
|
}
|
|
1147
|
-
|
|
1171
|
+
refreshFromDocs5(db, params.target_dir);
|
|
1148
1172
|
const lines = [
|
|
1149
1173
|
`Phase created: **${phaseId}**`,
|
|
1150
1174
|
"",
|
|
@@ -1168,16 +1192,60 @@ function registerCreatePhase(server, ctx) {
|
|
|
1168
1192
|
);
|
|
1169
1193
|
}
|
|
1170
1194
|
|
|
1171
|
-
// src/tools/
|
|
1195
|
+
// src/tools/delete-phase.ts
|
|
1172
1196
|
import { z as z12 } from "zod";
|
|
1197
|
+
import { deletePhaseFromYaml, refreshFromDocs as refreshFromDocs6 } from "@arcbridge/core";
|
|
1198
|
+
function registerDeletePhase(server, ctx) {
|
|
1199
|
+
server.tool(
|
|
1200
|
+
"arcbridge_delete_phase",
|
|
1201
|
+
"Delete a phase and all its tasks permanently. Use this to remove template phases that don't apply to this project. Phases with status 'in-progress' or 'done' cannot be deleted \u2014 change their status first if you really need to remove them.",
|
|
1202
|
+
{
|
|
1203
|
+
target_dir: z12.string().describe("Absolute path to the project directory"),
|
|
1204
|
+
phase_id: z12.string().describe("Phase ID to delete")
|
|
1205
|
+
},
|
|
1206
|
+
async (params) => {
|
|
1207
|
+
const db = ensureDb(ctx, params.target_dir);
|
|
1208
|
+
if (!db) return notInitialized();
|
|
1209
|
+
const phase = db.prepare("SELECT id, name, phase_number, status FROM phases WHERE id = ?").get(params.phase_id);
|
|
1210
|
+
if (!phase) {
|
|
1211
|
+
return textResult(
|
|
1212
|
+
`Phase '${params.phase_id}' not found. Use \`arcbridge_get_phase_plan\` to see available phases.`
|
|
1213
|
+
);
|
|
1214
|
+
}
|
|
1215
|
+
if (phase.status !== "planned") {
|
|
1216
|
+
return textResult(
|
|
1217
|
+
`Cannot delete phase **${phase.id}** (status: ${phase.status}). Only phases with status 'planned' can be deleted.`
|
|
1218
|
+
);
|
|
1219
|
+
}
|
|
1220
|
+
const taskCount = db.prepare("SELECT COUNT(*) as count FROM tasks WHERE phase_id = ?").get(params.phase_id);
|
|
1221
|
+
const yamlResult = deletePhaseFromYaml(params.target_dir, params.phase_id);
|
|
1222
|
+
if (!yamlResult.success) {
|
|
1223
|
+
return textResult(
|
|
1224
|
+
`Failed to delete phase: ${yamlResult.warning ?? "Unknown error"}`
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1227
|
+
refreshFromDocs6(db, params.target_dir);
|
|
1228
|
+
const lines = [
|
|
1229
|
+
`Phase **${phase.id}** deleted: "${phase.name}" (phase ${phase.phase_number})`
|
|
1230
|
+
];
|
|
1231
|
+
if (taskCount.count > 0) {
|
|
1232
|
+
lines.push(`${taskCount.count} task${taskCount.count === 1 ? "" : "s"} removed.`);
|
|
1233
|
+
}
|
|
1234
|
+
return textResult(lines.join("\n"));
|
|
1235
|
+
}
|
|
1236
|
+
);
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
// src/tools/get-relevant-adrs.ts
|
|
1240
|
+
import { z as z13 } from "zod";
|
|
1173
1241
|
function registerGetRelevantAdrs(server, ctx) {
|
|
1174
1242
|
server.tool(
|
|
1175
1243
|
"arcbridge_get_relevant_adrs",
|
|
1176
1244
|
"Get architectural decision records (ADRs) relevant to a specific file path or building block.",
|
|
1177
1245
|
{
|
|
1178
|
-
target_dir:
|
|
1179
|
-
file_path:
|
|
1180
|
-
building_block:
|
|
1246
|
+
target_dir: z13.string().describe("Absolute path to the project directory"),
|
|
1247
|
+
file_path: z13.string().optional().describe("File path to find relevant ADRs for"),
|
|
1248
|
+
building_block: z13.string().optional().describe("Building block ID to find relevant ADRs for")
|
|
1181
1249
|
},
|
|
1182
1250
|
async (params) => {
|
|
1183
1251
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -1261,24 +1329,24 @@ function formatAdrs(adrs, title) {
|
|
|
1261
1329
|
}
|
|
1262
1330
|
|
|
1263
1331
|
// src/tools/reindex.ts
|
|
1264
|
-
import { z as
|
|
1265
|
-
import { indexProject as indexProject2, refreshFromDocs as
|
|
1332
|
+
import { z as z14 } from "zod";
|
|
1333
|
+
import { indexProject as indexProject2, refreshFromDocs as refreshFromDocs7 } from "@arcbridge/core";
|
|
1266
1334
|
function registerReindex(server, ctx) {
|
|
1267
1335
|
server.tool(
|
|
1268
1336
|
"arcbridge_reindex",
|
|
1269
1337
|
"Re-index the project: refreshes architecture docs from arc42/YAML files, then reindexes code symbols (TypeScript & C#/.NET). This is the first step of the sync pipeline \u2014 use it to pick up manual doc edits and code changes.",
|
|
1270
1338
|
{
|
|
1271
|
-
target_dir:
|
|
1272
|
-
tsconfig_path:
|
|
1273
|
-
service:
|
|
1274
|
-
language:
|
|
1339
|
+
target_dir: z14.string().describe("Absolute path to the project directory"),
|
|
1340
|
+
tsconfig_path: z14.string().optional().describe("Override tsconfig.json path (default: auto-detect). Only used for TypeScript projects."),
|
|
1341
|
+
service: z14.string().optional().describe("Service name for monorepo projects (default: 'main')"),
|
|
1342
|
+
language: z14.enum(["typescript", "csharp", "auto"]).optional().describe("Project language. 'auto' detects from project files (default: 'auto')")
|
|
1275
1343
|
},
|
|
1276
1344
|
async (params) => {
|
|
1277
1345
|
const start = Date.now();
|
|
1278
1346
|
const db = ensureDb(ctx, params.target_dir);
|
|
1279
1347
|
if (!db) return notInitialized();
|
|
1280
1348
|
try {
|
|
1281
|
-
const docWarnings =
|
|
1349
|
+
const docWarnings = refreshFromDocs7(db, params.target_dir);
|
|
1282
1350
|
const result = await indexProject2(db, {
|
|
1283
1351
|
projectRoot: params.target_dir,
|
|
1284
1352
|
tsconfigPath: params.tsconfig_path,
|
|
@@ -1317,16 +1385,16 @@ function registerReindex(server, ctx) {
|
|
|
1317
1385
|
}
|
|
1318
1386
|
|
|
1319
1387
|
// src/tools/search-symbols.ts
|
|
1320
|
-
import { z as
|
|
1388
|
+
import { z as z15 } from "zod";
|
|
1321
1389
|
function registerSearchSymbols(server, ctx) {
|
|
1322
1390
|
server.tool(
|
|
1323
1391
|
"arcbridge_search_symbols",
|
|
1324
1392
|
"Search code symbols by name, kind, file path, or building block. Supports TypeScript and C#. Returns matching symbols with type signatures.",
|
|
1325
1393
|
{
|
|
1326
|
-
target_dir:
|
|
1327
|
-
query:
|
|
1328
|
-
service:
|
|
1329
|
-
kind:
|
|
1394
|
+
target_dir: z15.string().describe("Absolute path to the project directory"),
|
|
1395
|
+
query: z15.string().optional().describe("Search term to match against symbol names"),
|
|
1396
|
+
service: z15.string().optional().describe("Filter by service name (for multi-project solutions). Omit to search all services."),
|
|
1397
|
+
kind: z15.enum([
|
|
1330
1398
|
"function",
|
|
1331
1399
|
"class",
|
|
1332
1400
|
"type",
|
|
@@ -1338,10 +1406,10 @@ function registerSearchSymbols(server, ctx) {
|
|
|
1338
1406
|
"hook",
|
|
1339
1407
|
"context"
|
|
1340
1408
|
]).optional().describe("Filter by symbol kind"),
|
|
1341
|
-
file_path:
|
|
1342
|
-
is_exported:
|
|
1343
|
-
building_block:
|
|
1344
|
-
limit:
|
|
1409
|
+
file_path: z15.string().optional().describe("Filter by file path (prefix match)"),
|
|
1410
|
+
is_exported: z15.boolean().optional().describe("Filter by export status"),
|
|
1411
|
+
building_block: z15.string().optional().describe("Filter by building block ID (matches against code_paths)"),
|
|
1412
|
+
limit: z15.number().int().min(1).max(200).default(50).describe("Maximum results to return (default: 50)")
|
|
1345
1413
|
},
|
|
1346
1414
|
async (params) => {
|
|
1347
1415
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -1428,7 +1496,7 @@ function registerSearchSymbols(server, ctx) {
|
|
|
1428
1496
|
}
|
|
1429
1497
|
|
|
1430
1498
|
// src/tools/get-symbol.ts
|
|
1431
|
-
import { z as
|
|
1499
|
+
import { z as z16 } from "zod";
|
|
1432
1500
|
import { readFileSync, existsSync as existsSync3 } from "fs";
|
|
1433
1501
|
import { join as join3 } from "path";
|
|
1434
1502
|
function registerGetSymbol(server, ctx) {
|
|
@@ -1436,11 +1504,11 @@ function registerGetSymbol(server, ctx) {
|
|
|
1436
1504
|
"arcbridge_get_symbol",
|
|
1437
1505
|
"Get detailed information about a specific TypeScript symbol including its source code, type signature, and relationships.",
|
|
1438
1506
|
{
|
|
1439
|
-
target_dir:
|
|
1440
|
-
symbol_id:
|
|
1507
|
+
target_dir: z16.string().describe("Absolute path to the project directory"),
|
|
1508
|
+
symbol_id: z16.string().describe(
|
|
1441
1509
|
"Symbol ID (e.g. 'src/utils.ts::formatName#function')"
|
|
1442
1510
|
),
|
|
1443
|
-
include_source:
|
|
1511
|
+
include_source: z16.boolean().default(true).describe("Include source code snippet (default: true)")
|
|
1444
1512
|
},
|
|
1445
1513
|
async (params) => {
|
|
1446
1514
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -1538,21 +1606,21 @@ Use \`arcbridge_search_symbols\` to find symbols by name.`
|
|
|
1538
1606
|
}
|
|
1539
1607
|
|
|
1540
1608
|
// src/tools/get-dependency-graph.ts
|
|
1541
|
-
import { z as
|
|
1609
|
+
import { z as z17 } from "zod";
|
|
1542
1610
|
function registerGetDependencyGraph(server, ctx) {
|
|
1543
1611
|
server.tool(
|
|
1544
1612
|
"arcbridge_get_dependency_graph",
|
|
1545
1613
|
"Get the dependency graph for a module or file. Shows imports, calls, type usage, and inheritance relationships between symbols.",
|
|
1546
1614
|
{
|
|
1547
|
-
target_dir:
|
|
1548
|
-
module:
|
|
1615
|
+
target_dir: z17.string().describe("Absolute path to the project directory"),
|
|
1616
|
+
module: z17.string().describe(
|
|
1549
1617
|
"Module path relative to project root (e.g. 'src/lib/auth')"
|
|
1550
1618
|
),
|
|
1551
|
-
direction:
|
|
1619
|
+
direction: z17.enum(["dependencies", "dependents", "both"]).default("both").describe(
|
|
1552
1620
|
"Graph direction: 'dependencies' (what this module uses), 'dependents' (what uses this module), or 'both'"
|
|
1553
1621
|
),
|
|
1554
|
-
depth:
|
|
1555
|
-
service:
|
|
1622
|
+
depth: z17.number().int().min(1).max(5).default(1).describe("How many levels to traverse (default: 1, max: 5)"),
|
|
1623
|
+
service: z17.string().optional().describe("Filter by service name (for multi-project solutions). Omit to search all services.")
|
|
1556
1624
|
},
|
|
1557
1625
|
async (params) => {
|
|
1558
1626
|
const maybeDb = ensureDb(ctx, params.target_dir);
|
|
@@ -1699,16 +1767,16 @@ function formatEdges(edges, modulePath, direction) {
|
|
|
1699
1767
|
}
|
|
1700
1768
|
|
|
1701
1769
|
// src/tools/get-component-graph.ts
|
|
1702
|
-
import { z as
|
|
1770
|
+
import { z as z18 } from "zod";
|
|
1703
1771
|
function registerGetComponentGraph(server, ctx) {
|
|
1704
1772
|
server.tool(
|
|
1705
1773
|
"arcbridge_get_component_graph",
|
|
1706
1774
|
"Get the React component graph: component hierarchy, props, state, context usage, and server/client boundaries.",
|
|
1707
1775
|
{
|
|
1708
|
-
target_dir:
|
|
1709
|
-
file_path:
|
|
1710
|
-
client_only:
|
|
1711
|
-
with_state:
|
|
1776
|
+
target_dir: z18.string().describe("Absolute path to the project directory"),
|
|
1777
|
+
file_path: z18.string().optional().describe("Filter to components in a specific file or directory prefix"),
|
|
1778
|
+
client_only: z18.boolean().optional().describe("Only show client components ('use client')"),
|
|
1779
|
+
with_state: z18.boolean().optional().describe("Only show components that use state (useState/useReducer)")
|
|
1712
1780
|
},
|
|
1713
1781
|
async (params) => {
|
|
1714
1782
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -1812,16 +1880,16 @@ function registerGetComponentGraph(server, ctx) {
|
|
|
1812
1880
|
}
|
|
1813
1881
|
|
|
1814
1882
|
// src/tools/get-route-map.ts
|
|
1815
|
-
import { z as
|
|
1883
|
+
import { z as z19 } from "zod";
|
|
1816
1884
|
function registerGetRouteMap(server, ctx) {
|
|
1817
1885
|
server.tool(
|
|
1818
1886
|
"arcbridge_get_route_map",
|
|
1819
1887
|
"Get the route map: pages, layouts, API routes, and their hierarchy. Works with Next.js, ASP.NET controllers, and minimal APIs.",
|
|
1820
1888
|
{
|
|
1821
|
-
target_dir:
|
|
1822
|
-
kind:
|
|
1823
|
-
route_prefix:
|
|
1824
|
-
service:
|
|
1889
|
+
target_dir: z19.string().describe("Absolute path to the project directory"),
|
|
1890
|
+
kind: z19.enum(["page", "layout", "loading", "error", "not-found", "api-route", "middleware"]).optional().describe("Filter by route kind"),
|
|
1891
|
+
route_prefix: z19.string().optional().describe("Filter by route path prefix (e.g. '/dashboard' or '/api/orders')"),
|
|
1892
|
+
service: z19.string().optional().describe("Filter by service name (for multi-project solutions). Omit to show all services.")
|
|
1825
1893
|
},
|
|
1826
1894
|
async (params) => {
|
|
1827
1895
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -1897,13 +1965,13 @@ function registerGetRouteMap(server, ctx) {
|
|
|
1897
1965
|
}
|
|
1898
1966
|
|
|
1899
1967
|
// src/tools/get-boundary-analysis.ts
|
|
1900
|
-
import { z as
|
|
1968
|
+
import { z as z20 } from "zod";
|
|
1901
1969
|
function registerGetBoundaryAnalysis(server, ctx) {
|
|
1902
1970
|
server.tool(
|
|
1903
1971
|
"arcbridge_get_boundary_analysis",
|
|
1904
1972
|
"Analyze server/client boundaries in a Next.js project. Identifies client components, server components, server actions, and potential boundary violations.",
|
|
1905
1973
|
{
|
|
1906
|
-
target_dir:
|
|
1974
|
+
target_dir: z20.string().describe("Absolute path to the project directory")
|
|
1907
1975
|
},
|
|
1908
1976
|
async (params) => {
|
|
1909
1977
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -2007,15 +2075,15 @@ function registerGetBoundaryAnalysis(server, ctx) {
|
|
|
2007
2075
|
}
|
|
2008
2076
|
|
|
2009
2077
|
// src/tools/check-drift.ts
|
|
2010
|
-
import { z as
|
|
2078
|
+
import { z as z21 } from "zod";
|
|
2011
2079
|
import { detectDrift, writeDriftLog } from "@arcbridge/core";
|
|
2012
2080
|
function registerCheckDrift(server, ctx) {
|
|
2013
2081
|
server.tool(
|
|
2014
2082
|
"arcbridge_check_drift",
|
|
2015
2083
|
"Detect architecture drift: undocumented modules, missing code paths, cross-block dependency violations, and stale ADR references.",
|
|
2016
2084
|
{
|
|
2017
|
-
target_dir:
|
|
2018
|
-
persist:
|
|
2085
|
+
target_dir: z21.string().describe("Absolute path to the project directory"),
|
|
2086
|
+
persist: z21.boolean().default(true).describe("Write findings to drift_log table (default: true)")
|
|
2019
2087
|
},
|
|
2020
2088
|
async (params) => {
|
|
2021
2089
|
const start = Date.now();
|
|
@@ -2087,16 +2155,16 @@ function registerCheckDrift(server, ctx) {
|
|
|
2087
2155
|
}
|
|
2088
2156
|
|
|
2089
2157
|
// src/tools/get-guidance.ts
|
|
2090
|
-
import { z as
|
|
2158
|
+
import { z as z22 } from "zod";
|
|
2091
2159
|
import { loadConfig as loadConfig3 } from "@arcbridge/core";
|
|
2092
2160
|
function registerGetGuidance(server, ctx) {
|
|
2093
2161
|
server.tool(
|
|
2094
2162
|
"arcbridge_get_guidance",
|
|
2095
2163
|
"Get context-aware architectural guidance for a code change. Surfaces relevant quality scenarios, patterns, constraints, and questions to consider.",
|
|
2096
2164
|
{
|
|
2097
|
-
target_dir:
|
|
2098
|
-
file_path:
|
|
2099
|
-
action:
|
|
2165
|
+
target_dir: z22.string().describe("Absolute path to the project directory"),
|
|
2166
|
+
file_path: z22.string().optional().describe("File path you're working on (to determine building block and context)"),
|
|
2167
|
+
action: z22.enum([
|
|
2100
2168
|
"adding-component",
|
|
2101
2169
|
"adding-api-route",
|
|
2102
2170
|
"adding-hook",
|
|
@@ -2294,14 +2362,14 @@ function getActionGuidance(action, projectType) {
|
|
|
2294
2362
|
}
|
|
2295
2363
|
|
|
2296
2364
|
// src/tools/get-open-questions.ts
|
|
2297
|
-
import { z as
|
|
2365
|
+
import { z as z23 } from "zod";
|
|
2298
2366
|
function registerGetOpenQuestions(server, ctx) {
|
|
2299
2367
|
server.tool(
|
|
2300
2368
|
"arcbridge_get_open_questions",
|
|
2301
2369
|
"Surface architectural gaps: untested quality scenarios, building blocks without boundaries, unresolved drift, and tasks missing acceptance criteria.",
|
|
2302
2370
|
{
|
|
2303
|
-
target_dir:
|
|
2304
|
-
scope:
|
|
2371
|
+
target_dir: z23.string().describe("Absolute path to the project directory"),
|
|
2372
|
+
scope: z23.string().optional().describe("Focus scope: 'current-phase', 'building-block:<id>', or omit for project-wide")
|
|
2305
2373
|
},
|
|
2306
2374
|
async (params) => {
|
|
2307
2375
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -2411,7 +2479,7 @@ function registerGetOpenQuestions(server, ctx) {
|
|
|
2411
2479
|
}
|
|
2412
2480
|
|
|
2413
2481
|
// src/tools/propose-arc42-update.ts
|
|
2414
|
-
import { z as
|
|
2482
|
+
import { z as z24 } from "zod";
|
|
2415
2483
|
import {
|
|
2416
2484
|
resolveRef,
|
|
2417
2485
|
getChangedFiles,
|
|
@@ -2423,9 +2491,9 @@ function registerProposeArc42Update(server, ctx) {
|
|
|
2423
2491
|
"arcbridge_propose_arc42_update",
|
|
2424
2492
|
"Analyze code changes since a reference point and generate specific, actionable proposals for updating arc42 documentation.",
|
|
2425
2493
|
{
|
|
2426
|
-
target_dir:
|
|
2427
|
-
changes_since:
|
|
2428
|
-
update_sync_point:
|
|
2494
|
+
target_dir: z24.string().describe("Absolute path to the project directory"),
|
|
2495
|
+
changes_since: z24.string().default("last-sync").describe("Reference point: 'last-commit', 'last-sync', 'last-phase', or a git ref"),
|
|
2496
|
+
update_sync_point: z24.boolean().default(false).describe("Update the stored sync commit to HEAD after generating proposals")
|
|
2429
2497
|
},
|
|
2430
2498
|
async (params) => {
|
|
2431
2499
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -2613,7 +2681,7 @@ function findCrossBlockConsumers(db, symbolId, sourceBlockId, blocks) {
|
|
|
2613
2681
|
}
|
|
2614
2682
|
|
|
2615
2683
|
// src/tools/get-practice-review.ts
|
|
2616
|
-
import { z as
|
|
2684
|
+
import { z as z25 } from "zod";
|
|
2617
2685
|
import {
|
|
2618
2686
|
resolveRef as resolveRef2,
|
|
2619
2687
|
getChangedFiles as getChangedFiles2,
|
|
@@ -2625,8 +2693,8 @@ function registerGetPracticeReview(server, ctx) {
|
|
|
2625
2693
|
"arcbridge_get_practice_review",
|
|
2626
2694
|
"Structured, practice-aware review of recent code changes across 5 dimensions: Architecture, Security, Testing, Documentation, and Complexity.",
|
|
2627
2695
|
{
|
|
2628
|
-
target_dir:
|
|
2629
|
-
since:
|
|
2696
|
+
target_dir: z25.string().describe("Absolute path to the project directory"),
|
|
2697
|
+
since: z25.string().default("last-commit").describe("Reference point: 'last-commit', 'last-session', or 'last-phase'")
|
|
2630
2698
|
},
|
|
2631
2699
|
async (params) => {
|
|
2632
2700
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -2942,7 +3010,7 @@ function reviewComplexity(db, changedFiles, findings) {
|
|
|
2942
3010
|
}
|
|
2943
3011
|
|
|
2944
3012
|
// src/tools/complete-phase.ts
|
|
2945
|
-
import { z as
|
|
3013
|
+
import { z as z26 } from "zod";
|
|
2946
3014
|
import {
|
|
2947
3015
|
detectDrift as detectDrift3,
|
|
2948
3016
|
writeDriftLog as writeDriftLog2,
|
|
@@ -2952,7 +3020,7 @@ import {
|
|
|
2952
3020
|
applyInferences,
|
|
2953
3021
|
verifyScenarios,
|
|
2954
3022
|
loadConfig as loadConfig4,
|
|
2955
|
-
refreshFromDocs as
|
|
3023
|
+
refreshFromDocs as refreshFromDocs8,
|
|
2956
3024
|
syncPhaseToYaml,
|
|
2957
3025
|
transaction
|
|
2958
3026
|
} from "@arcbridge/core";
|
|
@@ -2961,17 +3029,17 @@ function registerCompletePhase(server, ctx) {
|
|
|
2961
3029
|
"arcbridge_complete_phase",
|
|
2962
3030
|
"Attempt to complete a phase by validating all gates: tasks done, no critical drift, quality scenarios passing. Transitions the phase to 'complete' if all gates pass.",
|
|
2963
3031
|
{
|
|
2964
|
-
target_dir:
|
|
2965
|
-
phase_id:
|
|
2966
|
-
notes:
|
|
2967
|
-
auto_infer:
|
|
2968
|
-
run_tests:
|
|
3032
|
+
target_dir: z26.string().describe("Absolute path to the project directory"),
|
|
3033
|
+
phase_id: z26.string().optional().describe("Phase ID to complete (defaults to current in-progress phase)"),
|
|
3034
|
+
notes: z26.string().optional().describe("Optional notes about this phase completion"),
|
|
3035
|
+
auto_infer: z26.boolean().default(true).describe("Automatically infer task statuses from code state before checking gates"),
|
|
3036
|
+
run_tests: z26.boolean().default(false).describe("Run linked tests for quality scenarios before checking the quality gate")
|
|
2969
3037
|
},
|
|
2970
3038
|
async (params) => {
|
|
2971
3039
|
const start = Date.now();
|
|
2972
3040
|
const db = ensureDb(ctx, params.target_dir);
|
|
2973
3041
|
if (!db) return notInitialized();
|
|
2974
|
-
|
|
3042
|
+
refreshFromDocs8(db, params.target_dir);
|
|
2975
3043
|
let phase;
|
|
2976
3044
|
if (params.phase_id) {
|
|
2977
3045
|
phase = db.prepare("SELECT id, name, phase_number, status, gate_status FROM phases WHERE id = ?").get(params.phase_id);
|
|
@@ -3180,18 +3248,18 @@ function registerCompletePhase(server, ctx) {
|
|
|
3180
3248
|
}
|
|
3181
3249
|
|
|
3182
3250
|
// src/tools/activate-role.ts
|
|
3183
|
-
import { z as
|
|
3251
|
+
import { z as z27 } from "zod";
|
|
3184
3252
|
import { loadRole, loadRoles } from "@arcbridge/core";
|
|
3185
3253
|
function registerActivateRole(server, ctx) {
|
|
3186
3254
|
server.tool(
|
|
3187
3255
|
"arcbridge_activate_role",
|
|
3188
3256
|
"Activate an agent role: loads the role's system prompt, required tools, quality focus, and pre-loaded architectural context.",
|
|
3189
3257
|
{
|
|
3190
|
-
target_dir:
|
|
3191
|
-
role:
|
|
3258
|
+
target_dir: z27.string().describe("Absolute path to the project directory"),
|
|
3259
|
+
role: z27.string().describe(
|
|
3192
3260
|
"Role ID to activate (e.g., 'architect', 'implementer', 'security-reviewer')"
|
|
3193
3261
|
),
|
|
3194
|
-
building_block:
|
|
3262
|
+
building_block: z27.string().optional().describe("Focus on a specific building block (for implementer/code-reviewer roles)")
|
|
3195
3263
|
},
|
|
3196
3264
|
async (params) => {
|
|
3197
3265
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -3493,18 +3561,18 @@ function getRoleDefinition(roleId) {
|
|
|
3493
3561
|
}
|
|
3494
3562
|
|
|
3495
3563
|
// src/tools/verify-scenarios.ts
|
|
3496
|
-
import { z as
|
|
3564
|
+
import { z as z28 } from "zod";
|
|
3497
3565
|
import { verifyScenarios as verifyScenarios2, loadConfig as loadConfig5 } from "@arcbridge/core";
|
|
3498
3566
|
function registerVerifyScenarios(server, ctx) {
|
|
3499
3567
|
server.tool(
|
|
3500
3568
|
"arcbridge_verify_scenarios",
|
|
3501
3569
|
"Run linked tests for quality scenarios and update their pass/fail status. Only runs scenarios with verification='automatic' or 'semi-automatic' and non-empty linked_tests.",
|
|
3502
3570
|
{
|
|
3503
|
-
target_dir:
|
|
3504
|
-
scenario_ids:
|
|
3571
|
+
target_dir: z28.string().describe("Absolute path to the project directory"),
|
|
3572
|
+
scenario_ids: z28.array(z28.string()).optional().describe(
|
|
3505
3573
|
"Specific scenario IDs to verify (e.g., ['SEC-01', 'PERF-01']). If omitted, verifies all automatic scenarios."
|
|
3506
3574
|
),
|
|
3507
|
-
test_command:
|
|
3575
|
+
test_command: z28.string().optional().describe(
|
|
3508
3576
|
"Override the test command from config (e.g., 'npx jest'). File paths are appended as arguments."
|
|
3509
3577
|
)
|
|
3510
3578
|
},
|
|
@@ -3571,7 +3639,7 @@ function registerVerifyScenarios(server, ctx) {
|
|
|
3571
3639
|
}
|
|
3572
3640
|
|
|
3573
3641
|
// src/tools/run-role-check.ts
|
|
3574
|
-
import { z as
|
|
3642
|
+
import { z as z29 } from "zod";
|
|
3575
3643
|
import {
|
|
3576
3644
|
loadRole as loadRole2,
|
|
3577
3645
|
loadRoles as loadRoles2,
|
|
@@ -3586,11 +3654,11 @@ function registerRunRoleCheck(server, ctx) {
|
|
|
3586
3654
|
"arcbridge_run_role_check",
|
|
3587
3655
|
"Run a role-specific architectural analysis: resolves the role and executes relevant checks (drift, quality scenarios, boundaries, changed files) based on the role's focus areas.",
|
|
3588
3656
|
{
|
|
3589
|
-
target_dir:
|
|
3590
|
-
role:
|
|
3657
|
+
target_dir: z29.string().describe("Absolute path to the project directory"),
|
|
3658
|
+
role: z29.string().describe(
|
|
3591
3659
|
"Role ID to run checks for (e.g., 'security-reviewer', 'quality-guardian', 'architect', 'phase-manager', 'code-reviewer')"
|
|
3592
3660
|
),
|
|
3593
|
-
scope:
|
|
3661
|
+
scope: z29.enum(SCOPE_VALUES).default("current-phase").describe(
|
|
3594
3662
|
"Scope of analysis: 'last-commit' (recent changes), 'current-phase' (since phase start), 'full-project' (everything)"
|
|
3595
3663
|
)
|
|
3596
3664
|
},
|
|
@@ -4011,17 +4079,17 @@ function runCustomRoleCheck(db, lines, roleDef) {
|
|
|
4011
4079
|
}
|
|
4012
4080
|
|
|
4013
4081
|
// src/tools/update-scenario-status.ts
|
|
4014
|
-
import { z as
|
|
4082
|
+
import { z as z30 } from "zod";
|
|
4015
4083
|
import { syncScenarioToYaml, transaction as transaction2 } from "@arcbridge/core";
|
|
4016
4084
|
function registerUpdateScenarioStatus(server, ctx) {
|
|
4017
4085
|
server.tool(
|
|
4018
4086
|
"arcbridge_update_scenario_status",
|
|
4019
4087
|
"Update a quality scenario's status and optionally link test files. Use this to mark scenarios as passing/failing after manual verification, or to link test files so `arcbridge_verify_scenarios` can run them automatically.",
|
|
4020
4088
|
{
|
|
4021
|
-
target_dir:
|
|
4022
|
-
scenario_id:
|
|
4023
|
-
status:
|
|
4024
|
-
linked_tests:
|
|
4089
|
+
target_dir: z30.string().describe("Absolute path to the project directory"),
|
|
4090
|
+
scenario_id: z30.string().describe("Quality scenario ID (e.g., 'SEC-01', 'PERF-01')"),
|
|
4091
|
+
status: z30.enum(["passing", "failing", "untested", "partial"]).describe("New status for the scenario"),
|
|
4092
|
+
linked_tests: z30.array(z30.string()).optional().describe(
|
|
4025
4093
|
"Test file paths to link to this scenario (e.g., ['src/__tests__/auth.test.ts']). Once linked, `arcbridge_verify_scenarios` can run them automatically. Also sets verification to 'semi-automatic' if currently 'manual'."
|
|
4026
4094
|
)
|
|
4027
4095
|
},
|
|
@@ -4102,33 +4170,33 @@ ${invalid.map((p) => ` - ${p}`).join("\n")}`
|
|
|
4102
4170
|
}
|
|
4103
4171
|
|
|
4104
4172
|
// src/tools/record-activity.ts
|
|
4105
|
-
import { z as
|
|
4173
|
+
import { z as z31 } from "zod";
|
|
4106
4174
|
import { insertActivity as insertActivity2, getSessionTotals } from "@arcbridge/core";
|
|
4107
4175
|
function registerRecordActivity(server, ctx) {
|
|
4108
4176
|
server.tool(
|
|
4109
4177
|
"arcbridge_record_activity",
|
|
4110
4178
|
"Record agent activity \u2014 model, tokens, cost, duration, and optional quality snapshot. Use this to track what work was done and measure agent performance.",
|
|
4111
4179
|
{
|
|
4112
|
-
target_dir:
|
|
4113
|
-
tool_name:
|
|
4114
|
-
action:
|
|
4115
|
-
model:
|
|
4116
|
-
agent_role:
|
|
4117
|
-
task_id:
|
|
4118
|
-
phase_id:
|
|
4119
|
-
input_tokens:
|
|
4120
|
-
output_tokens:
|
|
4121
|
-
total_tokens:
|
|
4122
|
-
cost_usd:
|
|
4123
|
-
duration_ms:
|
|
4124
|
-
drift_count:
|
|
4125
|
-
drift_errors:
|
|
4126
|
-
test_pass_count:
|
|
4127
|
-
test_fail_count:
|
|
4128
|
-
lint_clean:
|
|
4129
|
-
typecheck_clean:
|
|
4130
|
-
notes:
|
|
4131
|
-
metadata:
|
|
4180
|
+
target_dir: z31.string().describe("Absolute path to the project directory"),
|
|
4181
|
+
tool_name: z31.string().describe("Name of the tool or action performed (e.g., 'arcbridge_update_task', 'code_edit')"),
|
|
4182
|
+
action: z31.string().optional().describe("Human-readable label (e.g., 'implement login form')"),
|
|
4183
|
+
model: z31.string().optional().describe("Model identifier (e.g., 'claude-sonnet-4-20250514')"),
|
|
4184
|
+
agent_role: z31.string().optional().describe("Active ArcBridge role (e.g., 'implementer')"),
|
|
4185
|
+
task_id: z31.string().optional().describe("Associated task ID"),
|
|
4186
|
+
phase_id: z31.string().optional().describe("Associated phase ID"),
|
|
4187
|
+
input_tokens: z31.number().int().nonnegative().optional().describe("Input/prompt tokens"),
|
|
4188
|
+
output_tokens: z31.number().int().nonnegative().optional().describe("Output/completion tokens"),
|
|
4189
|
+
total_tokens: z31.number().int().nonnegative().optional().describe("Total tokens (auto-computed if input+output given)"),
|
|
4190
|
+
cost_usd: z31.number().nonnegative().optional().describe("Estimated cost in USD"),
|
|
4191
|
+
duration_ms: z31.number().int().nonnegative().optional().describe("Wall-clock duration in ms"),
|
|
4192
|
+
drift_count: z31.number().int().nonnegative().optional().describe("Current drift count"),
|
|
4193
|
+
drift_errors: z31.number().int().nonnegative().optional().describe("Current drift errors"),
|
|
4194
|
+
test_pass_count: z31.number().int().nonnegative().optional().describe("Passing tests"),
|
|
4195
|
+
test_fail_count: z31.number().int().nonnegative().optional().describe("Failing tests"),
|
|
4196
|
+
lint_clean: z31.boolean().optional().describe("Whether lint passes cleanly"),
|
|
4197
|
+
typecheck_clean: z31.boolean().optional().describe("Whether typecheck passes cleanly"),
|
|
4198
|
+
notes: z31.string().optional().describe("Free-form notes"),
|
|
4199
|
+
metadata: z31.record(z31.unknown()).optional().describe("Additional key-value metadata")
|
|
4132
4200
|
},
|
|
4133
4201
|
async (params) => {
|
|
4134
4202
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -4183,23 +4251,23 @@ function registerRecordActivity(server, ctx) {
|
|
|
4183
4251
|
}
|
|
4184
4252
|
|
|
4185
4253
|
// src/tools/get-metrics.ts
|
|
4186
|
-
import { z as
|
|
4254
|
+
import { z as z32 } from "zod";
|
|
4187
4255
|
import { queryMetrics } from "@arcbridge/core";
|
|
4188
4256
|
function registerGetMetrics(server, ctx) {
|
|
4189
4257
|
server.tool(
|
|
4190
4258
|
"arcbridge_get_metrics",
|
|
4191
4259
|
"Query agent activity metrics \u2014 filter by model, task, phase, or time range. Group by model/task/phase/tool/day for aggregated views.",
|
|
4192
4260
|
{
|
|
4193
|
-
target_dir:
|
|
4194
|
-
task_id:
|
|
4195
|
-
phase_id:
|
|
4196
|
-
model:
|
|
4197
|
-
agent_role:
|
|
4198
|
-
tool_name:
|
|
4199
|
-
since:
|
|
4200
|
-
until:
|
|
4201
|
-
group_by:
|
|
4202
|
-
limit:
|
|
4261
|
+
target_dir: z32.string().describe("Absolute path to the project directory"),
|
|
4262
|
+
task_id: z32.string().optional().describe("Filter by task ID"),
|
|
4263
|
+
phase_id: z32.string().optional().describe("Filter by phase ID"),
|
|
4264
|
+
model: z32.string().optional().describe("Filter by model name"),
|
|
4265
|
+
agent_role: z32.string().optional().describe("Filter by agent role"),
|
|
4266
|
+
tool_name: z32.string().optional().describe("Filter by tool name"),
|
|
4267
|
+
since: z32.string().optional().describe("ISO 8601 timestamp \u2014 activity after this time"),
|
|
4268
|
+
until: z32.string().optional().describe("ISO 8601 timestamp \u2014 activity before this time"),
|
|
4269
|
+
group_by: z32.enum(["model", "task", "phase", "tool", "day", "none"]).default("none").describe("Group results for aggregation"),
|
|
4270
|
+
limit: z32.number().int().min(1).max(500).default(50).describe("Max rows in detail view (group_by=none)")
|
|
4203
4271
|
},
|
|
4204
4272
|
async (params) => {
|
|
4205
4273
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -4282,23 +4350,23 @@ function mdCell(val) {
|
|
|
4282
4350
|
}
|
|
4283
4351
|
|
|
4284
4352
|
// src/tools/export-metrics.ts
|
|
4285
|
-
import { z as
|
|
4353
|
+
import { z as z33 } from "zod";
|
|
4286
4354
|
import { exportMetrics } from "@arcbridge/core";
|
|
4287
4355
|
function registerExportMetrics(server, ctx) {
|
|
4288
4356
|
server.tool(
|
|
4289
4357
|
"arcbridge_export_metrics",
|
|
4290
4358
|
"Export agent activity metrics to a file (JSON, CSV, or Markdown) in .arcbridge/metrics/ for git commits or reporting.",
|
|
4291
4359
|
{
|
|
4292
|
-
target_dir:
|
|
4293
|
-
format:
|
|
4294
|
-
task_id:
|
|
4295
|
-
phase_id:
|
|
4296
|
-
model:
|
|
4297
|
-
agent_role:
|
|
4298
|
-
tool_name:
|
|
4299
|
-
since:
|
|
4300
|
-
until:
|
|
4301
|
-
max_rows:
|
|
4360
|
+
target_dir: z33.string().describe("Absolute path to the project directory"),
|
|
4361
|
+
format: z33.enum(["json", "csv", "markdown"]).default("json").describe("Export format"),
|
|
4362
|
+
task_id: z33.string().optional().describe("Filter by task ID"),
|
|
4363
|
+
phase_id: z33.string().optional().describe("Filter by phase ID"),
|
|
4364
|
+
model: z33.string().optional().describe("Filter by model name"),
|
|
4365
|
+
agent_role: z33.string().optional().describe("Filter by agent role"),
|
|
4366
|
+
tool_name: z33.string().optional().describe("Filter by tool name"),
|
|
4367
|
+
since: z33.string().optional().describe("ISO 8601 \u2014 activity after this time"),
|
|
4368
|
+
until: z33.string().optional().describe("ISO 8601 \u2014 activity before this time"),
|
|
4369
|
+
max_rows: z33.number().int().min(1).default(1e5).describe("Maximum rows to export (default: 100,000)")
|
|
4302
4370
|
},
|
|
4303
4371
|
async (params) => {
|
|
4304
4372
|
const db = ensureDb(ctx, params.target_dir);
|
|
@@ -4348,6 +4416,7 @@ function createArcBridgeServer() {
|
|
|
4348
4416
|
registerCreateTask(server, ctx);
|
|
4349
4417
|
registerDeleteTask(server, ctx);
|
|
4350
4418
|
registerCreatePhase(server, ctx);
|
|
4419
|
+
registerDeletePhase(server, ctx);
|
|
4351
4420
|
registerReindex(server, ctx);
|
|
4352
4421
|
registerSearchSymbols(server, ctx);
|
|
4353
4422
|
registerGetSymbol(server, ctx);
|