ccjk 12.2.0 → 12.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/dist/chunks/cli-hook.mjs +827 -25
- package/dist/chunks/package.mjs +1 -1
- package/dist/cli.mjs +0 -0
- package/package.json +65 -62
package/dist/chunks/cli-hook.mjs
CHANGED
|
@@ -3,13 +3,13 @@ import { a as getGlobalStateManager, g as getGlobalConvoyManager, S as SessionIn
|
|
|
3
3
|
import { n as nanoid } from '../shared/ccjk.BoApaI4j.mjs';
|
|
4
4
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
5
5
|
import { j as join } from '../shared/ccjk.bQ7Dh1g4.mjs';
|
|
6
|
+
import process__default from 'node:process';
|
|
6
7
|
import 'node:child_process';
|
|
7
8
|
import 'node:fs/promises';
|
|
8
9
|
import 'node:os';
|
|
9
10
|
import 'node:path';
|
|
10
11
|
import './main.mjs';
|
|
11
12
|
import 'module';
|
|
12
|
-
import 'node:process';
|
|
13
13
|
import 'node:stream';
|
|
14
14
|
import 'node:readline';
|
|
15
15
|
import 'node:crypto';
|
|
@@ -992,6 +992,418 @@ function getGlobalMayorAgent(config) {
|
|
|
992
992
|
return globalMayorAgent;
|
|
993
993
|
}
|
|
994
994
|
|
|
995
|
+
class MetricsCollector {
|
|
996
|
+
metrics = /* @__PURE__ */ new Map();
|
|
997
|
+
taskMetrics = /* @__PURE__ */ new Map();
|
|
998
|
+
performanceMetrics = /* @__PURE__ */ new Map();
|
|
999
|
+
maxRecords;
|
|
1000
|
+
retentionPeriod;
|
|
1001
|
+
constructor(options = {}) {
|
|
1002
|
+
this.maxRecords = options.maxRecords ?? 1e3;
|
|
1003
|
+
this.retentionPeriod = options.retentionPeriod ?? 36e5;
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Record a metric value
|
|
1007
|
+
*/
|
|
1008
|
+
recordMetric(agentId, metricName, value, metadata) {
|
|
1009
|
+
if (!this.metrics.has(agentId)) {
|
|
1010
|
+
this.metrics.set(agentId, /* @__PURE__ */ new Map());
|
|
1011
|
+
}
|
|
1012
|
+
const agentMetrics = this.metrics.get(agentId);
|
|
1013
|
+
if (!agentMetrics.has(metricName)) {
|
|
1014
|
+
agentMetrics.set(metricName, []);
|
|
1015
|
+
}
|
|
1016
|
+
const records = agentMetrics.get(metricName);
|
|
1017
|
+
records.push({
|
|
1018
|
+
timestamp: Date.now(),
|
|
1019
|
+
value,
|
|
1020
|
+
metadata
|
|
1021
|
+
});
|
|
1022
|
+
this.trimRecords(records);
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Record CPU usage
|
|
1026
|
+
*/
|
|
1027
|
+
recordCpuUsage(agentId, usage) {
|
|
1028
|
+
this.recordMetric(agentId, "cpu_usage", usage);
|
|
1029
|
+
this.updatePerformanceMetrics(agentId, { cpuUsage: usage });
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Record memory usage
|
|
1033
|
+
*/
|
|
1034
|
+
recordMemoryUsage(agentId, usage) {
|
|
1035
|
+
this.recordMetric(agentId, "memory_usage", usage);
|
|
1036
|
+
this.updatePerformanceMetrics(agentId, { memoryUsage: usage });
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Record response time
|
|
1040
|
+
*/
|
|
1041
|
+
recordResponseTime(agentId, responseTime) {
|
|
1042
|
+
this.recordMetric(agentId, "response_time", responseTime);
|
|
1043
|
+
this.updatePerformanceMetrics(agentId, { responseTime });
|
|
1044
|
+
}
|
|
1045
|
+
/**
|
|
1046
|
+
* Record task completion
|
|
1047
|
+
*/
|
|
1048
|
+
recordTaskCompletion(agentId, success, duration) {
|
|
1049
|
+
if (!this.taskMetrics.has(agentId)) {
|
|
1050
|
+
this.taskMetrics.set(agentId, {
|
|
1051
|
+
totalTasks: 0,
|
|
1052
|
+
completedTasks: 0,
|
|
1053
|
+
failedTasks: 0,
|
|
1054
|
+
avgDuration: 0,
|
|
1055
|
+
successRate: 0
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
const metrics = this.taskMetrics.get(agentId);
|
|
1059
|
+
metrics.totalTasks++;
|
|
1060
|
+
if (success) {
|
|
1061
|
+
metrics.completedTasks++;
|
|
1062
|
+
} else {
|
|
1063
|
+
metrics.failedTasks++;
|
|
1064
|
+
}
|
|
1065
|
+
metrics.avgDuration = (metrics.avgDuration * (metrics.totalTasks - 1) + duration) / metrics.totalTasks;
|
|
1066
|
+
metrics.successRate = metrics.completedTasks / metrics.totalTasks;
|
|
1067
|
+
this.recordMetric(agentId, "task_duration", duration, { success });
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Record error
|
|
1071
|
+
*/
|
|
1072
|
+
recordError(agentId, errorType, errorMessage) {
|
|
1073
|
+
this.recordMetric(agentId, "error", 1, { errorType, errorMessage });
|
|
1074
|
+
this.updatePerformanceMetrics(agentId, { errorCount: 1 });
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Get agent metrics
|
|
1078
|
+
*/
|
|
1079
|
+
getAgentMetrics(agentId) {
|
|
1080
|
+
const taskMetrics = this.taskMetrics.get(agentId);
|
|
1081
|
+
const cpuRecords = this.getMetricRecords(agentId, "cpu_usage");
|
|
1082
|
+
const memoryRecords = this.getMetricRecords(agentId, "memory_usage");
|
|
1083
|
+
const responseTimeRecords = this.getMetricRecords(agentId, "response_time");
|
|
1084
|
+
const cpuUsage = cpuRecords.length > 0 ? cpuRecords[cpuRecords.length - 1].value : 0;
|
|
1085
|
+
const memoryUsage = memoryRecords.length > 0 ? memoryRecords[memoryRecords.length - 1].value : 0;
|
|
1086
|
+
this.calculateAverage(responseTimeRecords.map((r) => r.value));
|
|
1087
|
+
taskMetrics ? taskMetrics.failedTasks / taskMetrics.totalTasks : 0;
|
|
1088
|
+
return {
|
|
1089
|
+
tasksExecuted: taskMetrics?.totalTasks ?? 0,
|
|
1090
|
+
tasksSucceeded: taskMetrics?.completedTasks ?? 0,
|
|
1091
|
+
tasksFailed: taskMetrics?.failedTasks ?? 0,
|
|
1092
|
+
avgTaskDuration: taskMetrics?.avgDuration ?? 0,
|
|
1093
|
+
successRate: taskMetrics?.successRate ?? 0,
|
|
1094
|
+
totalExecutionTime: taskMetrics?.avgDuration ?? 0,
|
|
1095
|
+
avgConfidence: 0.8,
|
|
1096
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1097
|
+
cpuUsage,
|
|
1098
|
+
memoryUsage
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
* Get metric snapshot
|
|
1103
|
+
*/
|
|
1104
|
+
getMetricSnapshot(agentId, metricName, timeRange) {
|
|
1105
|
+
const records = this.getMetricRecords(agentId, metricName, timeRange);
|
|
1106
|
+
const values = records.map((r) => r.value);
|
|
1107
|
+
if (values.length === 0) {
|
|
1108
|
+
return {
|
|
1109
|
+
metricName,
|
|
1110
|
+
agentId,
|
|
1111
|
+
timestamp: Date.now(),
|
|
1112
|
+
current: 0,
|
|
1113
|
+
min: 0,
|
|
1114
|
+
max: 0,
|
|
1115
|
+
avg: 0,
|
|
1116
|
+
count: 0
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
return {
|
|
1120
|
+
metricName,
|
|
1121
|
+
agentId,
|
|
1122
|
+
timestamp: Date.now(),
|
|
1123
|
+
current: values[values.length - 1],
|
|
1124
|
+
min: Math.min(...values),
|
|
1125
|
+
max: Math.max(...values),
|
|
1126
|
+
avg: this.calculateAverage(values),
|
|
1127
|
+
count: values.length
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Get aggregated metrics
|
|
1132
|
+
*/
|
|
1133
|
+
getAggregatedMetrics(agentId, metricName, timeRange) {
|
|
1134
|
+
const records = this.getMetricRecords(agentId, metricName, timeRange);
|
|
1135
|
+
const values = records.map((r) => r.value).sort((a, b) => a - b);
|
|
1136
|
+
if (values.length === 0) {
|
|
1137
|
+
return {
|
|
1138
|
+
min: 0,
|
|
1139
|
+
max: 0,
|
|
1140
|
+
avg: 0,
|
|
1141
|
+
median: 0,
|
|
1142
|
+
p95: 0,
|
|
1143
|
+
p99: 0,
|
|
1144
|
+
count: 0
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
return {
|
|
1148
|
+
min: values[0],
|
|
1149
|
+
max: values[values.length - 1],
|
|
1150
|
+
avg: this.calculateAverage(values),
|
|
1151
|
+
median: this.calculatePercentile(values, 50),
|
|
1152
|
+
p95: this.calculatePercentile(values, 95),
|
|
1153
|
+
p99: this.calculatePercentile(values, 99),
|
|
1154
|
+
count: values.length
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* Get task metrics
|
|
1159
|
+
*/
|
|
1160
|
+
getTaskMetrics(agentId) {
|
|
1161
|
+
return this.taskMetrics.get(agentId);
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Get performance metrics
|
|
1165
|
+
*/
|
|
1166
|
+
getPerformanceMetrics(agentId) {
|
|
1167
|
+
return this.performanceMetrics.get(agentId);
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Get all agents with metrics
|
|
1171
|
+
*/
|
|
1172
|
+
getAllAgents() {
|
|
1173
|
+
return Array.from(this.metrics.keys());
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Clear metrics for an agent
|
|
1177
|
+
*/
|
|
1178
|
+
clearAgentMetrics(agentId) {
|
|
1179
|
+
this.metrics.delete(agentId);
|
|
1180
|
+
this.taskMetrics.delete(agentId);
|
|
1181
|
+
this.performanceMetrics.delete(agentId);
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Clear all metrics
|
|
1185
|
+
*/
|
|
1186
|
+
clearAll() {
|
|
1187
|
+
this.metrics.clear();
|
|
1188
|
+
this.taskMetrics.clear();
|
|
1189
|
+
this.performanceMetrics.clear();
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Export metrics to JSON
|
|
1193
|
+
*/
|
|
1194
|
+
exportMetrics(agentId) {
|
|
1195
|
+
if (agentId) {
|
|
1196
|
+
return {
|
|
1197
|
+
agentId,
|
|
1198
|
+
metrics: this.getAgentMetrics(agentId),
|
|
1199
|
+
taskMetrics: this.getTaskMetrics(agentId),
|
|
1200
|
+
performanceMetrics: this.getPerformanceMetrics(agentId),
|
|
1201
|
+
timestamp: Date.now()
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
const allMetrics = {};
|
|
1205
|
+
for (const id of this.getAllAgents()) {
|
|
1206
|
+
allMetrics[id] = {
|
|
1207
|
+
metrics: this.getAgentMetrics(id),
|
|
1208
|
+
taskMetrics: this.getTaskMetrics(id),
|
|
1209
|
+
performanceMetrics: this.getPerformanceMetrics(id)
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
return {
|
|
1213
|
+
agents: allMetrics,
|
|
1214
|
+
timestamp: Date.now()
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Get metric records
|
|
1219
|
+
*/
|
|
1220
|
+
getMetricRecords(agentId, metricName, timeRange) {
|
|
1221
|
+
const agentMetrics = this.metrics.get(agentId);
|
|
1222
|
+
if (!agentMetrics) {
|
|
1223
|
+
return [];
|
|
1224
|
+
}
|
|
1225
|
+
const records = agentMetrics.get(metricName) ?? [];
|
|
1226
|
+
if (timeRange) {
|
|
1227
|
+
const cutoff = Date.now() - timeRange;
|
|
1228
|
+
return records.filter((r) => r.timestamp >= cutoff);
|
|
1229
|
+
}
|
|
1230
|
+
return records;
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Update performance metrics
|
|
1234
|
+
*/
|
|
1235
|
+
updatePerformanceMetrics(agentId, update) {
|
|
1236
|
+
if (!this.performanceMetrics.has(agentId)) {
|
|
1237
|
+
this.performanceMetrics.set(agentId, {
|
|
1238
|
+
cpuUsage: 0,
|
|
1239
|
+
memoryUsage: 0,
|
|
1240
|
+
responseTime: 0,
|
|
1241
|
+
errorCount: 0,
|
|
1242
|
+
requestCount: 0,
|
|
1243
|
+
timestamp: Date.now()
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
const metrics = this.performanceMetrics.get(agentId);
|
|
1247
|
+
if (update.cpuUsage !== void 0) {
|
|
1248
|
+
metrics.cpuUsage = update.cpuUsage;
|
|
1249
|
+
}
|
|
1250
|
+
if (update.memoryUsage !== void 0) {
|
|
1251
|
+
metrics.memoryUsage = update.memoryUsage;
|
|
1252
|
+
}
|
|
1253
|
+
if (update.responseTime !== void 0) {
|
|
1254
|
+
metrics.requestCount++;
|
|
1255
|
+
metrics.responseTime = (metrics.responseTime * (metrics.requestCount - 1) + update.responseTime) / metrics.requestCount;
|
|
1256
|
+
}
|
|
1257
|
+
if (update.errorCount !== void 0) {
|
|
1258
|
+
metrics.errorCount += update.errorCount;
|
|
1259
|
+
}
|
|
1260
|
+
metrics.timestamp = Date.now();
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Trim old records
|
|
1264
|
+
*/
|
|
1265
|
+
trimRecords(records) {
|
|
1266
|
+
const cutoff = Date.now() - this.retentionPeriod;
|
|
1267
|
+
while (records.length > 0 && records[0].timestamp < cutoff) {
|
|
1268
|
+
records.shift();
|
|
1269
|
+
}
|
|
1270
|
+
while (records.length > this.maxRecords) {
|
|
1271
|
+
records.shift();
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Calculate average
|
|
1276
|
+
*/
|
|
1277
|
+
calculateAverage(values) {
|
|
1278
|
+
if (values.length === 0) {
|
|
1279
|
+
return 0;
|
|
1280
|
+
}
|
|
1281
|
+
return values.reduce((sum, val) => sum + val, 0) / values.length;
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* Calculate percentile
|
|
1285
|
+
*/
|
|
1286
|
+
calculatePercentile(sortedValues, percentile) {
|
|
1287
|
+
if (sortedValues.length === 0) {
|
|
1288
|
+
return 0;
|
|
1289
|
+
}
|
|
1290
|
+
const index = Math.ceil(percentile / 100 * sortedValues.length) - 1;
|
|
1291
|
+
return sortedValues[Math.max(0, index)];
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
let globalMetricsCollector;
|
|
1295
|
+
function getMetricsCollector(options) {
|
|
1296
|
+
if (!globalMetricsCollector) {
|
|
1297
|
+
globalMetricsCollector = new MetricsCollector(options);
|
|
1298
|
+
}
|
|
1299
|
+
return globalMetricsCollector;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
const promptUserQuestion = async (question) => {
|
|
1303
|
+
if (!process__default.stdin.isTTY || !process__default.stdout.isTTY) {
|
|
1304
|
+
return null;
|
|
1305
|
+
}
|
|
1306
|
+
try {
|
|
1307
|
+
const inquirer = (await import('./index3.mjs').then(function (n) { return n.c; })).default;
|
|
1308
|
+
const choices = question.options.map((option) => ({
|
|
1309
|
+
name: option.description ? `${option.label} \u2014 ${option.description}` : option.label,
|
|
1310
|
+
value: option.value
|
|
1311
|
+
}));
|
|
1312
|
+
const defaultIndex = typeof question.defaultValue === "string" ? Math.max(0, choices.findIndex((choice) => choice.value === question.defaultValue)) : 0;
|
|
1313
|
+
const { selected } = await inquirer.prompt([
|
|
1314
|
+
{
|
|
1315
|
+
type: "list",
|
|
1316
|
+
name: "selected",
|
|
1317
|
+
message: question.prompt,
|
|
1318
|
+
choices,
|
|
1319
|
+
default: defaultIndex
|
|
1320
|
+
}
|
|
1321
|
+
]);
|
|
1322
|
+
return {
|
|
1323
|
+
value: selected,
|
|
1324
|
+
source: "option"
|
|
1325
|
+
};
|
|
1326
|
+
} catch {
|
|
1327
|
+
return null;
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1330
|
+
|
|
1331
|
+
const DEFAULT_PHASE_SUMMARY = {
|
|
1332
|
+
calls: 0,
|
|
1333
|
+
failures: 0,
|
|
1334
|
+
successRate: 0,
|
|
1335
|
+
avgDurationMs: 0
|
|
1336
|
+
};
|
|
1337
|
+
class ExecutionTelemetry {
|
|
1338
|
+
constructor(maxEvents = 2e3) {
|
|
1339
|
+
this.maxEvents = maxEvents;
|
|
1340
|
+
}
|
|
1341
|
+
events = [];
|
|
1342
|
+
record(event) {
|
|
1343
|
+
const entry = {
|
|
1344
|
+
id: `te-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
1345
|
+
timestamp: Date.now(),
|
|
1346
|
+
...event
|
|
1347
|
+
};
|
|
1348
|
+
this.events.push(entry);
|
|
1349
|
+
if (this.events.length > this.maxEvents) {
|
|
1350
|
+
this.events.shift();
|
|
1351
|
+
}
|
|
1352
|
+
return entry;
|
|
1353
|
+
}
|
|
1354
|
+
getRecent(limit = 50) {
|
|
1355
|
+
if (limit <= 0) {
|
|
1356
|
+
return [];
|
|
1357
|
+
}
|
|
1358
|
+
return this.events.slice(-limit);
|
|
1359
|
+
}
|
|
1360
|
+
summarize() {
|
|
1361
|
+
const phaseStats = {
|
|
1362
|
+
execution: { ...DEFAULT_PHASE_SUMMARY },
|
|
1363
|
+
intent: { ...DEFAULT_PHASE_SUMMARY },
|
|
1364
|
+
elicitation: { ...DEFAULT_PHASE_SUMMARY },
|
|
1365
|
+
skill: { ...DEFAULT_PHASE_SUMMARY },
|
|
1366
|
+
agent: { ...DEFAULT_PHASE_SUMMARY },
|
|
1367
|
+
mcp: { ...DEFAULT_PHASE_SUMMARY },
|
|
1368
|
+
route: { ...DEFAULT_PHASE_SUMMARY }
|
|
1369
|
+
};
|
|
1370
|
+
let totalSuccess = 0;
|
|
1371
|
+
let durationCount = 0;
|
|
1372
|
+
let durationTotal = 0;
|
|
1373
|
+
for (const event of this.events) {
|
|
1374
|
+
const summary = phaseStats[event.phase];
|
|
1375
|
+
summary.calls++;
|
|
1376
|
+
if (!event.success) {
|
|
1377
|
+
summary.failures++;
|
|
1378
|
+
} else {
|
|
1379
|
+
totalSuccess++;
|
|
1380
|
+
}
|
|
1381
|
+
if (typeof event.durationMs === "number") {
|
|
1382
|
+
durationTotal += event.durationMs;
|
|
1383
|
+
durationCount++;
|
|
1384
|
+
summary.avgDurationMs = (summary.avgDurationMs * (summary.calls - 1) + event.durationMs) / summary.calls;
|
|
1385
|
+
}
|
|
1386
|
+
summary.successRate = summary.calls === 0 ? 0 : (summary.calls - summary.failures) / summary.calls;
|
|
1387
|
+
}
|
|
1388
|
+
return {
|
|
1389
|
+
totalEvents: this.events.length,
|
|
1390
|
+
overallSuccessRate: this.events.length === 0 ? 0 : totalSuccess / this.events.length,
|
|
1391
|
+
avgDurationMs: durationCount === 0 ? 0 : durationTotal / durationCount,
|
|
1392
|
+
phaseStats
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
clear() {
|
|
1396
|
+
this.events = [];
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
let globalExecutionTelemetry = null;
|
|
1400
|
+
function getGlobalExecutionTelemetry() {
|
|
1401
|
+
if (!globalExecutionTelemetry) {
|
|
1402
|
+
globalExecutionTelemetry = new ExecutionTelemetry();
|
|
1403
|
+
}
|
|
1404
|
+
return globalExecutionTelemetry;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
995
1407
|
class IntentRouter extends EventEmitter {
|
|
996
1408
|
config;
|
|
997
1409
|
// Keywords for intent detection
|
|
@@ -1385,15 +1797,78 @@ function getGlobalIntentRouter(config) {
|
|
|
1385
1797
|
return globalRouter$1;
|
|
1386
1798
|
}
|
|
1387
1799
|
|
|
1800
|
+
const MCP_TOOL_PROFILES = [
|
|
1801
|
+
{
|
|
1802
|
+
tool: "filesystem",
|
|
1803
|
+
keywords: ["file", "directory", "folder", "workspace", "path", "read", "write"],
|
|
1804
|
+
basePriority: 5,
|
|
1805
|
+
intentBoost: {
|
|
1806
|
+
feature: 2,
|
|
1807
|
+
refactor: 2,
|
|
1808
|
+
bug_fix: 2
|
|
1809
|
+
}
|
|
1810
|
+
},
|
|
1811
|
+
{
|
|
1812
|
+
tool: "github",
|
|
1813
|
+
keywords: ["github", "repository", "repo", "pr", "pull request", "issue", "commit"],
|
|
1814
|
+
basePriority: 4,
|
|
1815
|
+
intentBoost: {
|
|
1816
|
+
feature: 1,
|
|
1817
|
+
bug_fix: 1
|
|
1818
|
+
}
|
|
1819
|
+
},
|
|
1820
|
+
{
|
|
1821
|
+
tool: "web-search",
|
|
1822
|
+
keywords: ["search", "research", "web", "documentation", "docs", "latest", "reference"],
|
|
1823
|
+
basePriority: 3,
|
|
1824
|
+
intentBoost: {
|
|
1825
|
+
question: 2,
|
|
1826
|
+
plan: 1
|
|
1827
|
+
}
|
|
1828
|
+
},
|
|
1829
|
+
{
|
|
1830
|
+
tool: "context7",
|
|
1831
|
+
keywords: ["library", "framework", "package", "sdk", "api docs", "best practice"],
|
|
1832
|
+
basePriority: 4,
|
|
1833
|
+
intentBoost: {
|
|
1834
|
+
feature: 2,
|
|
1835
|
+
plan: 2,
|
|
1836
|
+
question: 1
|
|
1837
|
+
}
|
|
1838
|
+
},
|
|
1839
|
+
{
|
|
1840
|
+
tool: "ide",
|
|
1841
|
+
keywords: ["diagnostic", "error", "lint", "typecheck", "compile", "warning"],
|
|
1842
|
+
basePriority: 3,
|
|
1843
|
+
intentBoost: {
|
|
1844
|
+
bug_fix: 2,
|
|
1845
|
+
refactor: 1
|
|
1846
|
+
}
|
|
1847
|
+
},
|
|
1848
|
+
{
|
|
1849
|
+
tool: "playwright",
|
|
1850
|
+
keywords: ["browser", "webpage", "e2e", "ui test", "automation", "screenshot"],
|
|
1851
|
+
basePriority: 2,
|
|
1852
|
+
intentBoost: {
|
|
1853
|
+
feature: 1,
|
|
1854
|
+
bug_fix: 1
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
];
|
|
1388
1858
|
class AutoExecutor extends EventEmitter {
|
|
1389
1859
|
config;
|
|
1390
|
-
|
|
1860
|
+
metricsCollector = getMetricsCollector();
|
|
1391
1861
|
constructor(config = {}) {
|
|
1392
1862
|
super();
|
|
1393
1863
|
this.config = {
|
|
1394
1864
|
autoCreateSkills: config.autoCreateSkills !== void 0 ? config.autoCreateSkills : true,
|
|
1395
1865
|
autoCreateAgents: config.autoCreateAgents !== void 0 ? config.autoCreateAgents : true,
|
|
1396
1866
|
autoSelectMcp: config.autoSelectMcp !== void 0 ? config.autoSelectMcp : true,
|
|
1867
|
+
enableElicitation: config.enableElicitation !== void 0 ? config.enableElicitation : true,
|
|
1868
|
+
maxMcpTools: config.maxMcpTools !== void 0 ? Math.max(1, config.maxMcpTools) : 3,
|
|
1869
|
+
askUserQuestion: config.askUserQuestion || promptUserQuestion,
|
|
1870
|
+
intentRouter: config.intentRouter || getGlobalIntentRouter(),
|
|
1871
|
+
telemetry: config.telemetry || getGlobalExecutionTelemetry(),
|
|
1397
1872
|
verbose: config.verbose !== void 0 ? config.verbose : false
|
|
1398
1873
|
};
|
|
1399
1874
|
}
|
|
@@ -1401,36 +1876,141 @@ class AutoExecutor extends EventEmitter {
|
|
|
1401
1876
|
* Execute user request automatically
|
|
1402
1877
|
*/
|
|
1403
1878
|
async execute(userInput) {
|
|
1879
|
+
const executionId = `exec-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1880
|
+
const startedAt = Date.now();
|
|
1404
1881
|
this.emit("execution:started", { input: userInput });
|
|
1882
|
+
this.config.telemetry.record({
|
|
1883
|
+
executionId,
|
|
1884
|
+
phase: "execution",
|
|
1885
|
+
action: "start",
|
|
1886
|
+
success: true,
|
|
1887
|
+
metadata: {
|
|
1888
|
+
inputLength: userInput.length
|
|
1889
|
+
}
|
|
1890
|
+
});
|
|
1405
1891
|
try {
|
|
1406
|
-
const
|
|
1407
|
-
const
|
|
1892
|
+
const routeStart = Date.now();
|
|
1893
|
+
const routeResult = await this.config.intentRouter.route(userInput);
|
|
1894
|
+
this.config.telemetry.record({
|
|
1895
|
+
executionId,
|
|
1896
|
+
phase: "intent",
|
|
1897
|
+
action: "route",
|
|
1898
|
+
success: true,
|
|
1899
|
+
durationMs: Date.now() - routeStart,
|
|
1900
|
+
metadata: {
|
|
1901
|
+
initialRoute: routeResult.route,
|
|
1902
|
+
confidence: routeResult.intent.confidence,
|
|
1903
|
+
intentType: routeResult.intent.type,
|
|
1904
|
+
complexity: routeResult.intent.complexity
|
|
1905
|
+
}
|
|
1906
|
+
});
|
|
1907
|
+
const elicitationResult = await this.resolveRouteWithElicitation(
|
|
1908
|
+
routeResult.route,
|
|
1909
|
+
routeResult.intent,
|
|
1910
|
+
executionId
|
|
1911
|
+
);
|
|
1912
|
+
const route = elicitationResult.route;
|
|
1913
|
+
const intent = elicitationResult.intent;
|
|
1408
1914
|
this.log(`Intent analyzed: ${intent.type} (${intent.complexity})`);
|
|
1409
1915
|
this.log(`Suggested route: ${route}`);
|
|
1916
|
+
const skillDetectStart = Date.now();
|
|
1410
1917
|
const skillReq = await this.detectSkillRequirement(userInput, intent);
|
|
1918
|
+
this.config.telemetry.record({
|
|
1919
|
+
executionId,
|
|
1920
|
+
phase: "skill",
|
|
1921
|
+
action: "detect",
|
|
1922
|
+
success: true,
|
|
1923
|
+
durationMs: Date.now() - skillDetectStart,
|
|
1924
|
+
metadata: {
|
|
1925
|
+
needed: skillReq.needed,
|
|
1926
|
+
reason: skillReq.reason
|
|
1927
|
+
}
|
|
1928
|
+
});
|
|
1929
|
+
const agentDetectStart = Date.now();
|
|
1411
1930
|
const agentReq = await this.detectAgentRequirement(userInput, intent);
|
|
1931
|
+
this.config.telemetry.record({
|
|
1932
|
+
executionId,
|
|
1933
|
+
phase: "agent",
|
|
1934
|
+
action: "detect",
|
|
1935
|
+
success: true,
|
|
1936
|
+
durationMs: Date.now() - agentDetectStart,
|
|
1937
|
+
metadata: {
|
|
1938
|
+
needed: agentReq.needed,
|
|
1939
|
+
reason: agentReq.reason
|
|
1940
|
+
}
|
|
1941
|
+
});
|
|
1942
|
+
const mcpDetectStart = Date.now();
|
|
1412
1943
|
const mcpReq = await this.detectMcpRequirement(userInput, intent);
|
|
1944
|
+
this.config.telemetry.record({
|
|
1945
|
+
executionId,
|
|
1946
|
+
phase: "mcp",
|
|
1947
|
+
action: "detect",
|
|
1948
|
+
success: true,
|
|
1949
|
+
durationMs: Date.now() - mcpDetectStart,
|
|
1950
|
+
metadata: {
|
|
1951
|
+
needed: mcpReq.needed,
|
|
1952
|
+
selectedTools: mcpReq.tools,
|
|
1953
|
+
candidates: mcpReq.candidates,
|
|
1954
|
+
reason: mcpReq.reason
|
|
1955
|
+
}
|
|
1956
|
+
});
|
|
1413
1957
|
const agentsCreated = [];
|
|
1414
1958
|
const skillsCreated = [];
|
|
1415
1959
|
const mcpToolsUsed = [];
|
|
1416
1960
|
if (this.config.autoCreateSkills && skillReq.needed) {
|
|
1417
1961
|
this.log(`Auto-creating skill: ${skillReq.skillName}`);
|
|
1962
|
+
const skillCreateStart = Date.now();
|
|
1418
1963
|
const skillId = await this.autoCreateSkill(skillReq);
|
|
1419
1964
|
skillsCreated.push(skillId);
|
|
1965
|
+
this.config.telemetry.record({
|
|
1966
|
+
executionId,
|
|
1967
|
+
phase: "skill",
|
|
1968
|
+
action: "create",
|
|
1969
|
+
success: true,
|
|
1970
|
+
durationMs: Date.now() - skillCreateStart,
|
|
1971
|
+
metadata: {
|
|
1972
|
+
skillId,
|
|
1973
|
+
skillName: skillReq.skillName
|
|
1974
|
+
}
|
|
1975
|
+
});
|
|
1420
1976
|
this.emit("skill:created", { skillId, skillReq });
|
|
1421
1977
|
}
|
|
1422
1978
|
if (this.config.autoCreateAgents && agentReq.needed) {
|
|
1423
1979
|
this.log(`Auto-creating agent: ${agentReq.domain}`);
|
|
1980
|
+
const agentCreateStart = Date.now();
|
|
1424
1981
|
const agentId = await this.autoCreateAgent(agentReq);
|
|
1425
1982
|
agentsCreated.push(agentId);
|
|
1983
|
+
this.config.telemetry.record({
|
|
1984
|
+
executionId,
|
|
1985
|
+
phase: "agent",
|
|
1986
|
+
action: "create",
|
|
1987
|
+
success: true,
|
|
1988
|
+
durationMs: Date.now() - agentCreateStart,
|
|
1989
|
+
metadata: {
|
|
1990
|
+
agentId,
|
|
1991
|
+
agentType: agentReq.agentType,
|
|
1992
|
+
domain: agentReq.domain
|
|
1993
|
+
}
|
|
1994
|
+
});
|
|
1426
1995
|
this.emit("agent:created", { agentId, agentReq });
|
|
1427
1996
|
}
|
|
1428
1997
|
if (this.config.autoSelectMcp && mcpReq.needed) {
|
|
1429
1998
|
this.log(`Auto-selecting MCP tools: ${mcpReq.tools.join(", ")}`);
|
|
1430
1999
|
mcpToolsUsed.push(...mcpReq.tools);
|
|
2000
|
+
this.config.telemetry.record({
|
|
2001
|
+
executionId,
|
|
2002
|
+
phase: "mcp",
|
|
2003
|
+
action: "select",
|
|
2004
|
+
success: true,
|
|
2005
|
+
metadata: {
|
|
2006
|
+
tools: mcpReq.tools,
|
|
2007
|
+
candidates: mcpReq.candidates
|
|
2008
|
+
}
|
|
2009
|
+
});
|
|
1431
2010
|
this.emit("mcp:selected", { tools: mcpReq.tools, mcpReq });
|
|
1432
2011
|
}
|
|
1433
2012
|
let result;
|
|
2013
|
+
const routeExecutionStart = Date.now();
|
|
1434
2014
|
switch (route) {
|
|
1435
2015
|
case "mayor":
|
|
1436
2016
|
result = await this.executeMayor(userInput, intent, agentsCreated, skillsCreated, mcpToolsUsed);
|
|
@@ -1447,13 +2027,174 @@ class AutoExecutor extends EventEmitter {
|
|
|
1447
2027
|
default:
|
|
1448
2028
|
throw new Error(`Unknown route: ${route}`);
|
|
1449
2029
|
}
|
|
2030
|
+
const routeDuration = Date.now() - routeExecutionStart;
|
|
2031
|
+
this.config.telemetry.record({
|
|
2032
|
+
executionId,
|
|
2033
|
+
phase: "route",
|
|
2034
|
+
action: route,
|
|
2035
|
+
success: true,
|
|
2036
|
+
durationMs: routeDuration,
|
|
2037
|
+
metadata: {
|
|
2038
|
+
intentType: intent.type,
|
|
2039
|
+
complexity: intent.complexity
|
|
2040
|
+
}
|
|
2041
|
+
});
|
|
2042
|
+
const totalDuration = Date.now() - startedAt;
|
|
2043
|
+
this.metricsCollector.recordResponseTime("auto-executor", totalDuration);
|
|
2044
|
+
this.metricsCollector.recordTaskCompletion("auto-executor", true, totalDuration);
|
|
2045
|
+
this.config.telemetry.record({
|
|
2046
|
+
executionId,
|
|
2047
|
+
phase: "execution",
|
|
2048
|
+
action: "complete",
|
|
2049
|
+
success: true,
|
|
2050
|
+
durationMs: totalDuration,
|
|
2051
|
+
metadata: {
|
|
2052
|
+
route,
|
|
2053
|
+
agentsCreated: agentsCreated.length,
|
|
2054
|
+
skillsCreated: skillsCreated.length,
|
|
2055
|
+
mcpToolsUsed: mcpToolsUsed.length
|
|
2056
|
+
}
|
|
2057
|
+
});
|
|
2058
|
+
result.insights = this.buildExecutionInsights({
|
|
2059
|
+
initialRoute: routeResult.route,
|
|
2060
|
+
resolvedRoute: route,
|
|
2061
|
+
elicitationAsked: elicitationResult.elicitationAsked,
|
|
2062
|
+
userSelectedRoute: elicitationResult.userSelectedRoute,
|
|
2063
|
+
mcpReq,
|
|
2064
|
+
totalDurationMs: totalDuration,
|
|
2065
|
+
executionId
|
|
2066
|
+
});
|
|
1450
2067
|
this.emit("execution:completed", result);
|
|
1451
2068
|
return result;
|
|
1452
2069
|
} catch (error) {
|
|
2070
|
+
const totalDuration = Date.now() - startedAt;
|
|
2071
|
+
const errorMessage = this.getErrorMessage(error);
|
|
2072
|
+
this.metricsCollector.recordResponseTime("auto-executor", totalDuration);
|
|
2073
|
+
this.metricsCollector.recordTaskCompletion("auto-executor", false, totalDuration);
|
|
2074
|
+
this.metricsCollector.recordError("auto-executor", "execution_error", errorMessage);
|
|
2075
|
+
this.config.telemetry.record({
|
|
2076
|
+
executionId,
|
|
2077
|
+
phase: "execution",
|
|
2078
|
+
action: "complete",
|
|
2079
|
+
success: false,
|
|
2080
|
+
durationMs: totalDuration,
|
|
2081
|
+
metadata: {
|
|
2082
|
+
error: errorMessage
|
|
2083
|
+
}
|
|
2084
|
+
});
|
|
1453
2085
|
this.emit("execution:failed", { error, input: userInput });
|
|
1454
2086
|
throw error;
|
|
1455
2087
|
}
|
|
1456
2088
|
}
|
|
2089
|
+
/**
|
|
2090
|
+
* Resolve route with optional structured elicitation.
|
|
2091
|
+
* This keeps model autonomy but lets users disambiguate complex intent.
|
|
2092
|
+
*/
|
|
2093
|
+
async resolveRouteWithElicitation(suggestedRoute, intent, executionId) {
|
|
2094
|
+
if (!this.config.enableElicitation || !this.shouldAskRouteQuestion(intent)) {
|
|
2095
|
+
return {
|
|
2096
|
+
route: suggestedRoute,
|
|
2097
|
+
intent,
|
|
2098
|
+
elicitationAsked: false,
|
|
2099
|
+
userSelectedRoute: false
|
|
2100
|
+
};
|
|
2101
|
+
}
|
|
2102
|
+
const question = this.buildRouteQuestion(suggestedRoute, intent);
|
|
2103
|
+
const askStart = Date.now();
|
|
2104
|
+
const answer = await this.config.askUserQuestion(question);
|
|
2105
|
+
this.config.telemetry.record({
|
|
2106
|
+
executionId,
|
|
2107
|
+
phase: "elicitation",
|
|
2108
|
+
action: "route-choice",
|
|
2109
|
+
success: true,
|
|
2110
|
+
durationMs: Date.now() - askStart,
|
|
2111
|
+
metadata: {
|
|
2112
|
+
asked: true,
|
|
2113
|
+
suggestedRoute,
|
|
2114
|
+
answered: Boolean(answer),
|
|
2115
|
+
selected: answer?.value
|
|
2116
|
+
}
|
|
2117
|
+
});
|
|
2118
|
+
if (!answer) {
|
|
2119
|
+
return {
|
|
2120
|
+
route: suggestedRoute,
|
|
2121
|
+
intent,
|
|
2122
|
+
elicitationAsked: true,
|
|
2123
|
+
userSelectedRoute: false
|
|
2124
|
+
};
|
|
2125
|
+
}
|
|
2126
|
+
return this.applyRouteAnswer(suggestedRoute, intent, answer);
|
|
2127
|
+
}
|
|
2128
|
+
shouldAskRouteQuestion(intent) {
|
|
2129
|
+
if (intent.complexity === "trivial" || intent.complexity === "simple") {
|
|
2130
|
+
return false;
|
|
2131
|
+
}
|
|
2132
|
+
const lowConfidence = intent.confidence < 0.65;
|
|
2133
|
+
const multiRouteIndicators = intent.requiresPlanning && intent.requiresMultipleAgents;
|
|
2134
|
+
return lowConfidence || multiRouteIndicators;
|
|
2135
|
+
}
|
|
2136
|
+
buildRouteQuestion(suggestedRoute, intent) {
|
|
2137
|
+
const routeLabels = {
|
|
2138
|
+
direct: "Direct execution",
|
|
2139
|
+
feature: "Feature implementation",
|
|
2140
|
+
plan: "Plan first",
|
|
2141
|
+
mayor: "Multi-agent orchestration"
|
|
2142
|
+
};
|
|
2143
|
+
const options = [
|
|
2144
|
+
{
|
|
2145
|
+
value: suggestedRoute,
|
|
2146
|
+
label: `Use recommended: ${routeLabels[suggestedRoute]}`,
|
|
2147
|
+
description: `Best guess from intent analysis (confidence ${Math.round(intent.confidence * 100)}%)`
|
|
2148
|
+
},
|
|
2149
|
+
{
|
|
2150
|
+
value: "plan",
|
|
2151
|
+
label: routeLabels.plan,
|
|
2152
|
+
description: "Start with architecture and implementation plan"
|
|
2153
|
+
},
|
|
2154
|
+
{
|
|
2155
|
+
value: "feature",
|
|
2156
|
+
label: routeLabels.feature,
|
|
2157
|
+
description: "Implement directly with focused feature workflow"
|
|
2158
|
+
},
|
|
2159
|
+
{
|
|
2160
|
+
value: "direct",
|
|
2161
|
+
label: routeLabels.direct,
|
|
2162
|
+
description: "Run quickly without extra orchestration"
|
|
2163
|
+
},
|
|
2164
|
+
{
|
|
2165
|
+
value: "mayor",
|
|
2166
|
+
label: routeLabels.mayor,
|
|
2167
|
+
description: "Use specialized agents for decomposition and coordination"
|
|
2168
|
+
}
|
|
2169
|
+
].filter((option, index, arr) => arr.findIndex((x) => x.value === option.value) === index);
|
|
2170
|
+
return {
|
|
2171
|
+
id: "execution-route-choice",
|
|
2172
|
+
prompt: "How should I execute this request?",
|
|
2173
|
+
options,
|
|
2174
|
+
defaultValue: suggestedRoute
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2177
|
+
applyRouteAnswer(suggestedRoute, intent, answer) {
|
|
2178
|
+
const selectedRoute = ["direct", "feature", "plan", "mayor"].includes(answer.value) ? answer.value : suggestedRoute;
|
|
2179
|
+
if (selectedRoute === suggestedRoute) {
|
|
2180
|
+
return {
|
|
2181
|
+
route: suggestedRoute,
|
|
2182
|
+
intent,
|
|
2183
|
+
elicitationAsked: true,
|
|
2184
|
+
userSelectedRoute: false
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2187
|
+
return {
|
|
2188
|
+
route: selectedRoute,
|
|
2189
|
+
intent: {
|
|
2190
|
+
...intent,
|
|
2191
|
+
suggestedRoute: selectedRoute,
|
|
2192
|
+
reasoning: `${intent.reasoning} \u2022 User selected route: ${selectedRoute}`
|
|
2193
|
+
},
|
|
2194
|
+
elicitationAsked: true,
|
|
2195
|
+
userSelectedRoute: true
|
|
2196
|
+
};
|
|
2197
|
+
}
|
|
1457
2198
|
/**
|
|
1458
2199
|
* Detect if a new skill is needed
|
|
1459
2200
|
*/
|
|
@@ -1576,31 +2317,28 @@ class AutoExecutor extends EventEmitter {
|
|
|
1576
2317
|
/**
|
|
1577
2318
|
* Detect which MCP tools are needed
|
|
1578
2319
|
*/
|
|
1579
|
-
async detectMcpRequirement(input,
|
|
2320
|
+
async detectMcpRequirement(input, intent) {
|
|
1580
2321
|
const normalized = input.toLowerCase();
|
|
1581
|
-
const
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
}
|
|
1597
|
-
if (normalized.includes("diagnostic") || normalized.includes("error") || normalized.includes("lint")) {
|
|
1598
|
-
tools.push("ide");
|
|
1599
|
-
}
|
|
2322
|
+
const scoredTools = MCP_TOOL_PROFILES.map((profile) => {
|
|
2323
|
+
const matchedKeywords = profile.keywords.filter((keyword) => normalized.includes(keyword));
|
|
2324
|
+
if (matchedKeywords.length === 0) {
|
|
2325
|
+
return null;
|
|
2326
|
+
}
|
|
2327
|
+
const intentBoost = profile.intentBoost?.[intent.type] ?? 0;
|
|
2328
|
+
const complexityBoost = intent.complexity === "complex" || intent.complexity === "very_complex" ? 1 : 0;
|
|
2329
|
+
const score = profile.basePriority + matchedKeywords.length * 2 + intentBoost + complexityBoost;
|
|
2330
|
+
return {
|
|
2331
|
+
tool: profile.tool,
|
|
2332
|
+
score
|
|
2333
|
+
};
|
|
2334
|
+
}).filter((item) => item !== null).sort((a, b) => b.score - a.score);
|
|
2335
|
+
const candidates = scoredTools.map((item) => item.tool);
|
|
2336
|
+
const tools = scoredTools.slice(0, this.config.maxMcpTools).map((item) => item.tool);
|
|
1600
2337
|
return {
|
|
1601
2338
|
needed: tools.length > 0,
|
|
1602
2339
|
tools,
|
|
1603
|
-
|
|
2340
|
+
candidates,
|
|
2341
|
+
reason: tools.length > 0 ? candidates.length > tools.length ? `Selected top ${tools.length}/${candidates.length} MCP tools by capability score: ${tools.join(", ")}` : `Requires MCP tools: ${tools.join(", ")}` : "No MCP tools needed"
|
|
1604
2342
|
};
|
|
1605
2343
|
}
|
|
1606
2344
|
/**
|
|
@@ -1778,6 +2516,48 @@ class AutoExecutor extends EventEmitter {
|
|
|
1778
2516
|
details: { input }
|
|
1779
2517
|
};
|
|
1780
2518
|
}
|
|
2519
|
+
buildExecutionInsights(options) {
|
|
2520
|
+
return {
|
|
2521
|
+
decisionProfile: options.userSelectedRoute ? "user_guided" : "automatic",
|
|
2522
|
+
routeDecision: {
|
|
2523
|
+
initial: options.initialRoute,
|
|
2524
|
+
final: options.resolvedRoute,
|
|
2525
|
+
elicitationAsked: options.elicitationAsked,
|
|
2526
|
+
userSelectedRoute: options.userSelectedRoute
|
|
2527
|
+
},
|
|
2528
|
+
mcpSelection: {
|
|
2529
|
+
selected: options.mcpReq.tools,
|
|
2530
|
+
candidates: options.mcpReq.candidates,
|
|
2531
|
+
truncated: options.mcpReq.candidates.length > options.mcpReq.tools.length,
|
|
2532
|
+
reason: options.mcpReq.reason
|
|
2533
|
+
},
|
|
2534
|
+
telemetry: {
|
|
2535
|
+
totalDurationMs: options.totalDurationMs,
|
|
2536
|
+
eventCount: this.getExecutionTelemetryEventCount(options.executionId)
|
|
2537
|
+
}
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
getExecutionTelemetryEventCount(executionId) {
|
|
2541
|
+
return this.config.telemetry.getRecent(500).filter((event) => event.executionId === executionId).length;
|
|
2542
|
+
}
|
|
2543
|
+
/**
|
|
2544
|
+
* Get aggregated execution telemetry.
|
|
2545
|
+
*/
|
|
2546
|
+
getTelemetrySummary() {
|
|
2547
|
+
return this.config.telemetry.summarize();
|
|
2548
|
+
}
|
|
2549
|
+
/**
|
|
2550
|
+
* Get recent execution telemetry events.
|
|
2551
|
+
*/
|
|
2552
|
+
getTelemetryEvents(limit = 50) {
|
|
2553
|
+
return this.config.telemetry.getRecent(limit);
|
|
2554
|
+
}
|
|
2555
|
+
getErrorMessage(error) {
|
|
2556
|
+
if (error instanceof Error) {
|
|
2557
|
+
return error.message;
|
|
2558
|
+
}
|
|
2559
|
+
return String(error);
|
|
2560
|
+
}
|
|
1781
2561
|
/**
|
|
1782
2562
|
* Log message if verbose
|
|
1783
2563
|
*/
|
|
@@ -1960,6 +2740,7 @@ class CliInterceptor extends EventEmitter {
|
|
|
1960
2740
|
showIntentMessage(_input) {
|
|
1961
2741
|
console.log("\n\u{1F9E0} Analyzing your request...");
|
|
1962
2742
|
console.log(" System will automatically handle: skills, agents, MCP tools\n");
|
|
2743
|
+
console.log(" Smart mode: ambiguity checks + capability-ranked tool selection + telemetry\n");
|
|
1963
2744
|
}
|
|
1964
2745
|
/**
|
|
1965
2746
|
* Enable interceptor
|
|
@@ -2223,6 +3004,27 @@ ${"=".repeat(60)}`);
|
|
|
2223
3004
|
}
|
|
2224
3005
|
console.log();
|
|
2225
3006
|
}
|
|
3007
|
+
if (result.insights) {
|
|
3008
|
+
console.log("\u2728 Smart Upgrade Signals:");
|
|
3009
|
+
console.log(` Route decision: ${result.insights.routeDecision.initial} \u2192 ${result.insights.routeDecision.final}`);
|
|
3010
|
+
if (result.insights.routeDecision.userSelectedRoute) {
|
|
3011
|
+
console.log(" Mode: User-guided route disambiguation");
|
|
3012
|
+
} else if (result.insights.routeDecision.elicitationAsked) {
|
|
3013
|
+
console.log(" Mode: Asked for route preference (kept recommended)");
|
|
3014
|
+
} else {
|
|
3015
|
+
console.log(" Mode: Fully automatic route decision");
|
|
3016
|
+
}
|
|
3017
|
+
if (result.insights.mcpSelection.selected.length > 0) {
|
|
3018
|
+
if (result.insights.mcpSelection.truncated) {
|
|
3019
|
+
console.log(` MCP ranking: selected ${result.insights.mcpSelection.selected.length} of ${result.insights.mcpSelection.candidates.length} candidates`);
|
|
3020
|
+
}
|
|
3021
|
+
console.log(` MCP reason: ${result.insights.mcpSelection.reason}`);
|
|
3022
|
+
} else {
|
|
3023
|
+
console.log(" MCP reason: no external tools needed");
|
|
3024
|
+
}
|
|
3025
|
+
console.log(` Telemetry: ${result.insights.telemetry.eventCount} events, ${result.insights.telemetry.totalDurationMs}ms`);
|
|
3026
|
+
console.log();
|
|
3027
|
+
}
|
|
2226
3028
|
if (result.convoyId) {
|
|
2227
3029
|
console.log(`\u{1F4E6} Convoy: ${result.convoyId}`);
|
|
2228
3030
|
console.log();
|
package/dist/chunks/package.mjs
CHANGED
package/dist/cli.mjs
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccjk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "12.2.
|
|
4
|
+
"version": "12.2.1",
|
|
5
|
+
"packageManager": "pnpm@10.17.1",
|
|
5
6
|
"description": "CLI toolkit for Claude Code and Codex setup. Simplifies MCP service installation, API configuration, workflow management, and multi-provider support with guided interactive setup.",
|
|
6
7
|
"author": {
|
|
7
8
|
"name": "CCJK Team",
|
|
@@ -80,66 +81,6 @@
|
|
|
80
81
|
"engines": {
|
|
81
82
|
"node": ">=20"
|
|
82
83
|
},
|
|
83
|
-
"dependencies": {
|
|
84
|
-
"fdir": "^6.5.0",
|
|
85
|
-
"globby": "^14.1.0",
|
|
86
|
-
"ioredis": "^5.9.3",
|
|
87
|
-
"tar": "^7.5.9",
|
|
88
|
-
"tinyglobby": "^0.2.15",
|
|
89
|
-
"web-tree-sitter": "^0.26.5",
|
|
90
|
-
"better-sqlite3": "^12.6.2"
|
|
91
|
-
},
|
|
92
|
-
"devDependencies": {
|
|
93
|
-
"@antfu/eslint-config": "^5.4.1",
|
|
94
|
-
"@types/better-sqlite3": "^7.6.13",
|
|
95
|
-
"@types/fs-extra": "^11.0.4",
|
|
96
|
-
"@types/inquirer": "^9.0.9",
|
|
97
|
-
"@types/node": "^22.18.6",
|
|
98
|
-
"@types/semver": "^7.7.1",
|
|
99
|
-
"@types/uuid": "^11.0.0",
|
|
100
|
-
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
101
|
-
"@typescript-eslint/parser": "^6.0.0",
|
|
102
|
-
"@vitest/coverage-v8": "^3.2.4",
|
|
103
|
-
"@vitest/ui": "^3.2.4",
|
|
104
|
-
"concurrently": "^9.2.1",
|
|
105
|
-
"eslint": "^9.36.0",
|
|
106
|
-
"eslint-plugin-format": "^1.4.0",
|
|
107
|
-
"husky": "^9.1.7",
|
|
108
|
-
"lint-staged": "^16.2.7",
|
|
109
|
-
"pkgroll": "^2.26.3",
|
|
110
|
-
"prettier": "^3.8.1",
|
|
111
|
-
"shx": "^0.4.0",
|
|
112
|
-
"tsx": "^4.21.0",
|
|
113
|
-
"typescript": "^5.9.3",
|
|
114
|
-
"unbuild": "^3.6.1",
|
|
115
|
-
"vitest": "^3.2.4",
|
|
116
|
-
"@anthropic-ai/sdk": "^0.52.0",
|
|
117
|
-
"ansis": "^4.2.0",
|
|
118
|
-
"cac": "^6.7.14",
|
|
119
|
-
"chokidar": "^4.0.3",
|
|
120
|
-
"consola": "^3.4.2",
|
|
121
|
-
"dayjs": "^1.11.19",
|
|
122
|
-
"find-up-simple": "^1.0.1",
|
|
123
|
-
"fs-extra": "^11.3.3",
|
|
124
|
-
"gray-matter": "^4.0.3",
|
|
125
|
-
"handlebars": "^4.7.8",
|
|
126
|
-
"i18next": "^25.8.13",
|
|
127
|
-
"i18next-fs-backend": "^2.6.1",
|
|
128
|
-
"inquirer": "^12.9.6",
|
|
129
|
-
"inquirer-toggle": "^1.0.1",
|
|
130
|
-
"lowdb": "^7.0.1",
|
|
131
|
-
"nanoid": "^5.1.6",
|
|
132
|
-
"ofetch": "^1.5.1",
|
|
133
|
-
"ohash": "^1.1.4",
|
|
134
|
-
"ora": "^8.2.0",
|
|
135
|
-
"pathe": "^2.0.3",
|
|
136
|
-
"semver": "^7.7.4",
|
|
137
|
-
"smol-toml": "^1.6.0",
|
|
138
|
-
"tinyexec": "^1.0.2",
|
|
139
|
-
"trash": "^10.1.0",
|
|
140
|
-
"tweetnacl": "^1.0.3",
|
|
141
|
-
"uuid": "^11.1.0"
|
|
142
|
-
},
|
|
143
84
|
"scripts": {
|
|
144
85
|
"dev": "tsx ./src/cli.ts",
|
|
145
86
|
"build": "unbuild",
|
|
@@ -147,6 +88,7 @@
|
|
|
147
88
|
"typecheck": "tsc --noEmit",
|
|
148
89
|
"release:verify": "node scripts/release-verify.mjs",
|
|
149
90
|
"release:verify:full": "node scripts/release-verify.mjs --with-tests",
|
|
91
|
+
"prepublishOnly": "node scripts/validate-prepublish.mjs && pnpm contract:check && pnpm build && pnpm test:run",
|
|
150
92
|
"lint": "eslint",
|
|
151
93
|
"lint:fix": "eslint --fix",
|
|
152
94
|
"test": "vitest",
|
|
@@ -168,6 +110,7 @@
|
|
|
168
110
|
"test:integration:run": "NODE_ENV=test vitest run --config vitest.integration.config.ts",
|
|
169
111
|
"test:integration:ui": "NODE_ENV=test vitest --config vitest.integration.config.ts --ui",
|
|
170
112
|
"test:integration:coverage": "NODE_ENV=test vitest run --config vitest.integration.config.ts --coverage",
|
|
113
|
+
"prepare": "husky",
|
|
171
114
|
"format": "prettier --write src/**/*.ts",
|
|
172
115
|
"prepublish:fix": "node scripts/fix-package-catalog.mjs",
|
|
173
116
|
"cleanup": "node scripts/cleanup.js",
|
|
@@ -202,5 +145,65 @@
|
|
|
202
145
|
"i18n:check": "tsx scripts/check-i18n.ts",
|
|
203
146
|
"i18n:report": "tsx scripts/check-i18n.ts --report",
|
|
204
147
|
"contract:check": "node scripts/check-remote-contract.mjs"
|
|
148
|
+
},
|
|
149
|
+
"dependencies": {
|
|
150
|
+
"fdir": "^6.5.0",
|
|
151
|
+
"globby": "^14.1.0",
|
|
152
|
+
"ioredis": "^5.9.3",
|
|
153
|
+
"tar": "^7.5.9",
|
|
154
|
+
"tinyglobby": "^0.2.15",
|
|
155
|
+
"web-tree-sitter": "^0.26.5",
|
|
156
|
+
"better-sqlite3": "^12.6.2"
|
|
157
|
+
},
|
|
158
|
+
"devDependencies": {
|
|
159
|
+
"@antfu/eslint-config": "^5.4.1",
|
|
160
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
161
|
+
"@types/fs-extra": "^11.0.4",
|
|
162
|
+
"@types/inquirer": "^9.0.9",
|
|
163
|
+
"@types/node": "^22.18.6",
|
|
164
|
+
"@types/semver": "^7.7.1",
|
|
165
|
+
"@types/uuid": "^11.0.0",
|
|
166
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
167
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
168
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
169
|
+
"@vitest/ui": "^3.2.4",
|
|
170
|
+
"concurrently": "^9.2.1",
|
|
171
|
+
"eslint": "^9.36.0",
|
|
172
|
+
"eslint-plugin-format": "^1.4.0",
|
|
173
|
+
"husky": "^9.1.7",
|
|
174
|
+
"lint-staged": "^16.2.7",
|
|
175
|
+
"pkgroll": "^2.26.3",
|
|
176
|
+
"prettier": "^3.8.1",
|
|
177
|
+
"shx": "^0.4.0",
|
|
178
|
+
"tsx": "^4.21.0",
|
|
179
|
+
"typescript": "^5.9.3",
|
|
180
|
+
"unbuild": "^3.6.1",
|
|
181
|
+
"vitest": "^3.2.4",
|
|
182
|
+
"@anthropic-ai/sdk": "^0.52.0",
|
|
183
|
+
"ansis": "^4.2.0",
|
|
184
|
+
"cac": "^6.7.14",
|
|
185
|
+
"chokidar": "^4.0.3",
|
|
186
|
+
"consola": "^3.4.2",
|
|
187
|
+
"dayjs": "^1.11.19",
|
|
188
|
+
"find-up-simple": "^1.0.1",
|
|
189
|
+
"fs-extra": "^11.3.3",
|
|
190
|
+
"gray-matter": "^4.0.3",
|
|
191
|
+
"handlebars": "^4.7.8",
|
|
192
|
+
"i18next": "^25.8.13",
|
|
193
|
+
"i18next-fs-backend": "^2.6.1",
|
|
194
|
+
"inquirer": "^12.9.6",
|
|
195
|
+
"inquirer-toggle": "^1.0.1",
|
|
196
|
+
"lowdb": "^7.0.1",
|
|
197
|
+
"nanoid": "^5.1.6",
|
|
198
|
+
"ofetch": "^1.5.1",
|
|
199
|
+
"ohash": "^1.1.4",
|
|
200
|
+
"ora": "^8.2.0",
|
|
201
|
+
"pathe": "^2.0.3",
|
|
202
|
+
"semver": "^7.7.4",
|
|
203
|
+
"smol-toml": "^1.6.0",
|
|
204
|
+
"tinyexec": "^1.0.2",
|
|
205
|
+
"trash": "^10.1.0",
|
|
206
|
+
"tweetnacl": "^1.0.3",
|
|
207
|
+
"uuid": "^11.1.0"
|
|
205
208
|
}
|
|
206
|
-
}
|
|
209
|
+
}
|