appduct 0.13.0 → 0.14.0
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/bin.js +61 -4
- package/dist/cli/result-types.d.ts +8 -1
- package/dist/cli/routes/daemon/index.js +58 -1
- package/dist/cli/routes/daemon/run.js +152 -22
- package/dist/cli/routes/daemon/start.js +58 -1
- package/dist/cli/routes/daemon/status.js +58 -1
- package/dist/cli/routes/daemon/stop.js +58 -1
- package/dist/cli/routes/doctor.js +58 -1
- package/dist/cli/routes/events/index.d.ts +0 -3
- package/dist/cli/routes/events/index.js +60 -2
- package/dist/cli/routes/events/ls.d.ts +5 -0
- package/dist/cli/routes/events/ls.js +1798 -0
- package/dist/cli/routes/events/since.js +58 -1
- package/dist/cli/routes/events/tail.js +58 -1
- package/dist/cli/routes/init.js +58 -1
- package/dist/cli/routes/keygen.js +58 -1
- package/dist/cli/routes/mcp.js +108 -1
- package/dist/cli/routes/sessions/index.js +58 -1
- package/dist/cli/routes/sessions/link.js +58 -1
- package/dist/cli/routes/sessions/ls.js +58 -1
- package/dist/cli/routes/sessions/revoke.js +58 -1
- package/dist/cli/routes/tools/call.js +58 -1
- package/dist/cli/routes/tools/describe.js +58 -1
- package/dist/cli/routes/tools/index.js +58 -1
- package/dist/cli/routes/tools/ls.js +58 -1
- package/dist/commands/events-ls.d.ts +21 -0
- package/dist/daemon/calls.d.ts +3 -1
- package/dist/daemon/event-bus.d.ts +10 -0
- package/dist/daemon/registry.d.ts +20 -12
- package/dist/daemon/rpc-errors.d.ts +3 -0
- package/dist/daemon/sessions.d.ts +4 -2
- package/dist/index.js +61 -4
- package/dist/mcp/app-tools.d.ts +19 -0
- package/dist/mcp/events-tool.d.ts +39 -0
- package/package.json +2 -2
|
@@ -1079,6 +1079,7 @@ var handleEventsCommand = async (options, context) => {
|
|
|
1079
1079
|
import pc from "picocolors";
|
|
1080
1080
|
import {
|
|
1081
1081
|
formatAgentWebSocketUrl,
|
|
1082
|
+
renderEventSignature,
|
|
1082
1083
|
renderToolSignature,
|
|
1083
1084
|
summarizeToolDescription
|
|
1084
1085
|
} from "@appduct/shared";
|
|
@@ -1179,6 +1180,13 @@ var formatDevice = (device) => {
|
|
|
1179
1180
|
const label = parts.length > 0 ? parts.join(" ") : "unknown device";
|
|
1180
1181
|
return device.os ? `${label} (${device.os})` : label;
|
|
1181
1182
|
};
|
|
1183
|
+
var SUSPEND_REASON_LABELS = {
|
|
1184
|
+
app_backgrounded: "app in background",
|
|
1185
|
+
connection_lost: "connection lost"
|
|
1186
|
+
};
|
|
1187
|
+
var formatSessionState = (session) => {
|
|
1188
|
+
return session.suspendReason ? `${session.state} (${SUSPEND_REASON_LABELS[session.suspendReason]})` : session.state;
|
|
1189
|
+
};
|
|
1182
1190
|
var renderLsData = (colors, data, now) => {
|
|
1183
1191
|
if (data.length === 0) {
|
|
1184
1192
|
return [colors.dim("Sessions"), " No Appduct sessions are registered."];
|
|
@@ -1187,7 +1195,7 @@ var renderLsData = (colors, data, now) => {
|
|
|
1187
1195
|
const headers = ["Alias", "State", "Device", "Tools", "Age"];
|
|
1188
1196
|
const rows = data.map((session) => [
|
|
1189
1197
|
session.alias,
|
|
1190
|
-
session
|
|
1198
|
+
formatSessionState(session),
|
|
1191
1199
|
formatDevice(session.device),
|
|
1192
1200
|
String(session.toolCount),
|
|
1193
1201
|
formatAge(session.claimedAt ?? session.createdAt, nowIso)
|
|
@@ -1361,6 +1369,53 @@ var renderToolsListData = (colors, data, flags, full) => {
|
|
|
1361
1369
|
}
|
|
1362
1370
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
1363
1371
|
};
|
|
1372
|
+
var renderEventsTruncationLine = (data) => {
|
|
1373
|
+
const offset = data.offset ?? 0;
|
|
1374
|
+
if (data.events.length >= data.total) {
|
|
1375
|
+
return [];
|
|
1376
|
+
}
|
|
1377
|
+
return [
|
|
1378
|
+
"",
|
|
1379
|
+
`Showing ${data.events.length} of ${data.total} events (offset ${offset}). Narrow with --name <glob> or page with --offset <n>.`
|
|
1380
|
+
];
|
|
1381
|
+
};
|
|
1382
|
+
var renderEventsListData = (colors, data, flags) => {
|
|
1383
|
+
const [only] = data.events;
|
|
1384
|
+
if (data.name !== void 0 && !data.name.includes("*") && only !== void 0) {
|
|
1385
|
+
return renderFields(
|
|
1386
|
+
colors.green(`Event: ${only.name}`),
|
|
1387
|
+
[
|
|
1388
|
+
["Signature", renderEventSignature(only)],
|
|
1389
|
+
["Description", only.description],
|
|
1390
|
+
["Payload schema", only.payload_schema]
|
|
1391
|
+
],
|
|
1392
|
+
flags
|
|
1393
|
+
);
|
|
1394
|
+
}
|
|
1395
|
+
if (data.events.length === 0 && data.total > 0) {
|
|
1396
|
+
return [
|
|
1397
|
+
colors.green("Events"),
|
|
1398
|
+
` No events at offset ${data.offset ?? 0}; ${data.total} matching event${data.total === 1 ? "" : "s"} in total.`
|
|
1399
|
+
];
|
|
1400
|
+
}
|
|
1401
|
+
if (data.events.length === 0) {
|
|
1402
|
+
return [
|
|
1403
|
+
colors.green("Events"),
|
|
1404
|
+
data.name === void 0 ? " No events declared." : ` No events match ${JSON.stringify(data.name)}.`
|
|
1405
|
+
];
|
|
1406
|
+
}
|
|
1407
|
+
const lines = data.events.flatMap((event) => [
|
|
1408
|
+
` ${renderEventSignature(event)}`,
|
|
1409
|
+
` ${summarizeToolDescription(event.description)}`
|
|
1410
|
+
]);
|
|
1411
|
+
return [
|
|
1412
|
+
colors.green("Events"),
|
|
1413
|
+
...lines,
|
|
1414
|
+
...renderEventsTruncationLine(data),
|
|
1415
|
+
"",
|
|
1416
|
+
"Run `appduct events ls --name <name>` for an event's full payload schema."
|
|
1417
|
+
];
|
|
1418
|
+
};
|
|
1364
1419
|
var renderInvokeData = (colors, data, flags) => {
|
|
1365
1420
|
return [colors.green("Result"), formatScalar(data, flags)];
|
|
1366
1421
|
};
|
|
@@ -1552,6 +1607,8 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
1552
1607
|
return renderToolsListData(colors, data, flags, options.full);
|
|
1553
1608
|
case "tools describe":
|
|
1554
1609
|
return renderToolDetail(colors, data, flags);
|
|
1610
|
+
case "events ls":
|
|
1611
|
+
return renderEventsListData(colors, data, flags);
|
|
1555
1612
|
case "tools call":
|
|
1556
1613
|
return renderInvokeData(colors, data, flags);
|
|
1557
1614
|
case "sessions revoke":
|
|
@@ -1079,6 +1079,7 @@ var handleEventsCommand = async (options, context) => {
|
|
|
1079
1079
|
import pc from "picocolors";
|
|
1080
1080
|
import {
|
|
1081
1081
|
formatAgentWebSocketUrl,
|
|
1082
|
+
renderEventSignature,
|
|
1082
1083
|
renderToolSignature,
|
|
1083
1084
|
summarizeToolDescription
|
|
1084
1085
|
} from "@appduct/shared";
|
|
@@ -1179,6 +1180,13 @@ var formatDevice = (device) => {
|
|
|
1179
1180
|
const label = parts.length > 0 ? parts.join(" ") : "unknown device";
|
|
1180
1181
|
return device.os ? `${label} (${device.os})` : label;
|
|
1181
1182
|
};
|
|
1183
|
+
var SUSPEND_REASON_LABELS = {
|
|
1184
|
+
app_backgrounded: "app in background",
|
|
1185
|
+
connection_lost: "connection lost"
|
|
1186
|
+
};
|
|
1187
|
+
var formatSessionState = (session) => {
|
|
1188
|
+
return session.suspendReason ? `${session.state} (${SUSPEND_REASON_LABELS[session.suspendReason]})` : session.state;
|
|
1189
|
+
};
|
|
1182
1190
|
var renderLsData = (colors, data, now) => {
|
|
1183
1191
|
if (data.length === 0) {
|
|
1184
1192
|
return [colors.dim("Sessions"), " No Appduct sessions are registered."];
|
|
@@ -1187,7 +1195,7 @@ var renderLsData = (colors, data, now) => {
|
|
|
1187
1195
|
const headers = ["Alias", "State", "Device", "Tools", "Age"];
|
|
1188
1196
|
const rows = data.map((session) => [
|
|
1189
1197
|
session.alias,
|
|
1190
|
-
session
|
|
1198
|
+
formatSessionState(session),
|
|
1191
1199
|
formatDevice(session.device),
|
|
1192
1200
|
String(session.toolCount),
|
|
1193
1201
|
formatAge(session.claimedAt ?? session.createdAt, nowIso)
|
|
@@ -1361,6 +1369,53 @@ var renderToolsListData = (colors, data, flags, full) => {
|
|
|
1361
1369
|
}
|
|
1362
1370
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
1363
1371
|
};
|
|
1372
|
+
var renderEventsTruncationLine = (data) => {
|
|
1373
|
+
const offset = data.offset ?? 0;
|
|
1374
|
+
if (data.events.length >= data.total) {
|
|
1375
|
+
return [];
|
|
1376
|
+
}
|
|
1377
|
+
return [
|
|
1378
|
+
"",
|
|
1379
|
+
`Showing ${data.events.length} of ${data.total} events (offset ${offset}). Narrow with --name <glob> or page with --offset <n>.`
|
|
1380
|
+
];
|
|
1381
|
+
};
|
|
1382
|
+
var renderEventsListData = (colors, data, flags) => {
|
|
1383
|
+
const [only] = data.events;
|
|
1384
|
+
if (data.name !== void 0 && !data.name.includes("*") && only !== void 0) {
|
|
1385
|
+
return renderFields(
|
|
1386
|
+
colors.green(`Event: ${only.name}`),
|
|
1387
|
+
[
|
|
1388
|
+
["Signature", renderEventSignature(only)],
|
|
1389
|
+
["Description", only.description],
|
|
1390
|
+
["Payload schema", only.payload_schema]
|
|
1391
|
+
],
|
|
1392
|
+
flags
|
|
1393
|
+
);
|
|
1394
|
+
}
|
|
1395
|
+
if (data.events.length === 0 && data.total > 0) {
|
|
1396
|
+
return [
|
|
1397
|
+
colors.green("Events"),
|
|
1398
|
+
` No events at offset ${data.offset ?? 0}; ${data.total} matching event${data.total === 1 ? "" : "s"} in total.`
|
|
1399
|
+
];
|
|
1400
|
+
}
|
|
1401
|
+
if (data.events.length === 0) {
|
|
1402
|
+
return [
|
|
1403
|
+
colors.green("Events"),
|
|
1404
|
+
data.name === void 0 ? " No events declared." : ` No events match ${JSON.stringify(data.name)}.`
|
|
1405
|
+
];
|
|
1406
|
+
}
|
|
1407
|
+
const lines = data.events.flatMap((event) => [
|
|
1408
|
+
` ${renderEventSignature(event)}`,
|
|
1409
|
+
` ${summarizeToolDescription(event.description)}`
|
|
1410
|
+
]);
|
|
1411
|
+
return [
|
|
1412
|
+
colors.green("Events"),
|
|
1413
|
+
...lines,
|
|
1414
|
+
...renderEventsTruncationLine(data),
|
|
1415
|
+
"",
|
|
1416
|
+
"Run `appduct events ls --name <name>` for an event's full payload schema."
|
|
1417
|
+
];
|
|
1418
|
+
};
|
|
1364
1419
|
var renderInvokeData = (colors, data, flags) => {
|
|
1365
1420
|
return [colors.green("Result"), formatScalar(data, flags)];
|
|
1366
1421
|
};
|
|
@@ -1552,6 +1607,8 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
1552
1607
|
return renderToolsListData(colors, data, flags, options.full);
|
|
1553
1608
|
case "tools describe":
|
|
1554
1609
|
return renderToolDetail(colors, data, flags);
|
|
1610
|
+
case "events ls":
|
|
1611
|
+
return renderEventsListData(colors, data, flags);
|
|
1555
1612
|
case "tools call":
|
|
1556
1613
|
return renderInvokeData(colors, data, flags);
|
|
1557
1614
|
case "sessions revoke":
|
package/dist/cli/routes/init.js
CHANGED
|
@@ -861,6 +861,7 @@ var formatJson = (value, flags) => {
|
|
|
861
861
|
import pc from "picocolors";
|
|
862
862
|
import {
|
|
863
863
|
formatAgentWebSocketUrl,
|
|
864
|
+
renderEventSignature,
|
|
864
865
|
renderToolSignature,
|
|
865
866
|
summarizeToolDescription
|
|
866
867
|
} from "@appduct/shared";
|
|
@@ -956,6 +957,13 @@ var formatDevice = (device) => {
|
|
|
956
957
|
const label = parts.length > 0 ? parts.join(" ") : "unknown device";
|
|
957
958
|
return device.os ? `${label} (${device.os})` : label;
|
|
958
959
|
};
|
|
960
|
+
var SUSPEND_REASON_LABELS = {
|
|
961
|
+
app_backgrounded: "app in background",
|
|
962
|
+
connection_lost: "connection lost"
|
|
963
|
+
};
|
|
964
|
+
var formatSessionState = (session) => {
|
|
965
|
+
return session.suspendReason ? `${session.state} (${SUSPEND_REASON_LABELS[session.suspendReason]})` : session.state;
|
|
966
|
+
};
|
|
959
967
|
var renderLsData = (colors, data, now) => {
|
|
960
968
|
if (data.length === 0) {
|
|
961
969
|
return [colors.dim("Sessions"), " No Appduct sessions are registered."];
|
|
@@ -964,7 +972,7 @@ var renderLsData = (colors, data, now) => {
|
|
|
964
972
|
const headers = ["Alias", "State", "Device", "Tools", "Age"];
|
|
965
973
|
const rows = data.map((session) => [
|
|
966
974
|
session.alias,
|
|
967
|
-
session
|
|
975
|
+
formatSessionState(session),
|
|
968
976
|
formatDevice(session.device),
|
|
969
977
|
String(session.toolCount),
|
|
970
978
|
formatAge(session.claimedAt ?? session.createdAt, nowIso)
|
|
@@ -1138,6 +1146,53 @@ var renderToolsListData = (colors, data, flags, full) => {
|
|
|
1138
1146
|
}
|
|
1139
1147
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
1140
1148
|
};
|
|
1149
|
+
var renderEventsTruncationLine = (data) => {
|
|
1150
|
+
const offset = data.offset ?? 0;
|
|
1151
|
+
if (data.events.length >= data.total) {
|
|
1152
|
+
return [];
|
|
1153
|
+
}
|
|
1154
|
+
return [
|
|
1155
|
+
"",
|
|
1156
|
+
`Showing ${data.events.length} of ${data.total} events (offset ${offset}). Narrow with --name <glob> or page with --offset <n>.`
|
|
1157
|
+
];
|
|
1158
|
+
};
|
|
1159
|
+
var renderEventsListData = (colors, data, flags) => {
|
|
1160
|
+
const [only] = data.events;
|
|
1161
|
+
if (data.name !== void 0 && !data.name.includes("*") && only !== void 0) {
|
|
1162
|
+
return renderFields(
|
|
1163
|
+
colors.green(`Event: ${only.name}`),
|
|
1164
|
+
[
|
|
1165
|
+
["Signature", renderEventSignature(only)],
|
|
1166
|
+
["Description", only.description],
|
|
1167
|
+
["Payload schema", only.payload_schema]
|
|
1168
|
+
],
|
|
1169
|
+
flags
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
1172
|
+
if (data.events.length === 0 && data.total > 0) {
|
|
1173
|
+
return [
|
|
1174
|
+
colors.green("Events"),
|
|
1175
|
+
` No events at offset ${data.offset ?? 0}; ${data.total} matching event${data.total === 1 ? "" : "s"} in total.`
|
|
1176
|
+
];
|
|
1177
|
+
}
|
|
1178
|
+
if (data.events.length === 0) {
|
|
1179
|
+
return [
|
|
1180
|
+
colors.green("Events"),
|
|
1181
|
+
data.name === void 0 ? " No events declared." : ` No events match ${JSON.stringify(data.name)}.`
|
|
1182
|
+
];
|
|
1183
|
+
}
|
|
1184
|
+
const lines = data.events.flatMap((event) => [
|
|
1185
|
+
` ${renderEventSignature(event)}`,
|
|
1186
|
+
` ${summarizeToolDescription(event.description)}`
|
|
1187
|
+
]);
|
|
1188
|
+
return [
|
|
1189
|
+
colors.green("Events"),
|
|
1190
|
+
...lines,
|
|
1191
|
+
...renderEventsTruncationLine(data),
|
|
1192
|
+
"",
|
|
1193
|
+
"Run `appduct events ls --name <name>` for an event's full payload schema."
|
|
1194
|
+
];
|
|
1195
|
+
};
|
|
1141
1196
|
var renderInvokeData = (colors, data, flags) => {
|
|
1142
1197
|
return [colors.green("Result"), formatScalar(data, flags)];
|
|
1143
1198
|
};
|
|
@@ -1329,6 +1384,8 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
1329
1384
|
return renderToolsListData(colors, data, flags, options.full);
|
|
1330
1385
|
case "tools describe":
|
|
1331
1386
|
return renderToolDetail(colors, data, flags);
|
|
1387
|
+
case "events ls":
|
|
1388
|
+
return renderEventsListData(colors, data, flags);
|
|
1332
1389
|
case "tools call":
|
|
1333
1390
|
return renderInvokeData(colors, data, flags);
|
|
1334
1391
|
case "sessions revoke":
|
|
@@ -310,6 +310,7 @@ var formatJson = (value, flags) => {
|
|
|
310
310
|
import pc from "picocolors";
|
|
311
311
|
import {
|
|
312
312
|
formatAgentWebSocketUrl,
|
|
313
|
+
renderEventSignature,
|
|
313
314
|
renderToolSignature,
|
|
314
315
|
summarizeToolDescription
|
|
315
316
|
} from "@appduct/shared";
|
|
@@ -405,6 +406,13 @@ var formatDevice = (device) => {
|
|
|
405
406
|
const label = parts.length > 0 ? parts.join(" ") : "unknown device";
|
|
406
407
|
return device.os ? `${label} (${device.os})` : label;
|
|
407
408
|
};
|
|
409
|
+
var SUSPEND_REASON_LABELS = {
|
|
410
|
+
app_backgrounded: "app in background",
|
|
411
|
+
connection_lost: "connection lost"
|
|
412
|
+
};
|
|
413
|
+
var formatSessionState = (session) => {
|
|
414
|
+
return session.suspendReason ? `${session.state} (${SUSPEND_REASON_LABELS[session.suspendReason]})` : session.state;
|
|
415
|
+
};
|
|
408
416
|
var renderLsData = (colors, data, now) => {
|
|
409
417
|
if (data.length === 0) {
|
|
410
418
|
return [colors.dim("Sessions"), " No Appduct sessions are registered."];
|
|
@@ -413,7 +421,7 @@ var renderLsData = (colors, data, now) => {
|
|
|
413
421
|
const headers = ["Alias", "State", "Device", "Tools", "Age"];
|
|
414
422
|
const rows = data.map((session) => [
|
|
415
423
|
session.alias,
|
|
416
|
-
session
|
|
424
|
+
formatSessionState(session),
|
|
417
425
|
formatDevice(session.device),
|
|
418
426
|
String(session.toolCount),
|
|
419
427
|
formatAge(session.claimedAt ?? session.createdAt, nowIso)
|
|
@@ -587,6 +595,53 @@ var renderToolsListData = (colors, data, flags, full) => {
|
|
|
587
595
|
}
|
|
588
596
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
589
597
|
};
|
|
598
|
+
var renderEventsTruncationLine = (data) => {
|
|
599
|
+
const offset = data.offset ?? 0;
|
|
600
|
+
if (data.events.length >= data.total) {
|
|
601
|
+
return [];
|
|
602
|
+
}
|
|
603
|
+
return [
|
|
604
|
+
"",
|
|
605
|
+
`Showing ${data.events.length} of ${data.total} events (offset ${offset}). Narrow with --name <glob> or page with --offset <n>.`
|
|
606
|
+
];
|
|
607
|
+
};
|
|
608
|
+
var renderEventsListData = (colors, data, flags) => {
|
|
609
|
+
const [only] = data.events;
|
|
610
|
+
if (data.name !== void 0 && !data.name.includes("*") && only !== void 0) {
|
|
611
|
+
return renderFields(
|
|
612
|
+
colors.green(`Event: ${only.name}`),
|
|
613
|
+
[
|
|
614
|
+
["Signature", renderEventSignature(only)],
|
|
615
|
+
["Description", only.description],
|
|
616
|
+
["Payload schema", only.payload_schema]
|
|
617
|
+
],
|
|
618
|
+
flags
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
if (data.events.length === 0 && data.total > 0) {
|
|
622
|
+
return [
|
|
623
|
+
colors.green("Events"),
|
|
624
|
+
` No events at offset ${data.offset ?? 0}; ${data.total} matching event${data.total === 1 ? "" : "s"} in total.`
|
|
625
|
+
];
|
|
626
|
+
}
|
|
627
|
+
if (data.events.length === 0) {
|
|
628
|
+
return [
|
|
629
|
+
colors.green("Events"),
|
|
630
|
+
data.name === void 0 ? " No events declared." : ` No events match ${JSON.stringify(data.name)}.`
|
|
631
|
+
];
|
|
632
|
+
}
|
|
633
|
+
const lines = data.events.flatMap((event) => [
|
|
634
|
+
` ${renderEventSignature(event)}`,
|
|
635
|
+
` ${summarizeToolDescription(event.description)}`
|
|
636
|
+
]);
|
|
637
|
+
return [
|
|
638
|
+
colors.green("Events"),
|
|
639
|
+
...lines,
|
|
640
|
+
...renderEventsTruncationLine(data),
|
|
641
|
+
"",
|
|
642
|
+
"Run `appduct events ls --name <name>` for an event's full payload schema."
|
|
643
|
+
];
|
|
644
|
+
};
|
|
590
645
|
var renderInvokeData = (colors, data, flags) => {
|
|
591
646
|
return [colors.green("Result"), formatScalar(data, flags)];
|
|
592
647
|
};
|
|
@@ -778,6 +833,8 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
778
833
|
return renderToolsListData(colors, data, flags, options.full);
|
|
779
834
|
case "tools describe":
|
|
780
835
|
return renderToolDetail(colors, data, flags);
|
|
836
|
+
case "events ls":
|
|
837
|
+
return renderEventsListData(colors, data, flags);
|
|
781
838
|
case "tools call":
|
|
782
839
|
return renderInvokeData(colors, data, flags);
|
|
783
840
|
case "sessions revoke":
|
package/dist/cli/routes/mcp.js
CHANGED
|
@@ -2657,6 +2657,7 @@ var resolveAppTool = async (call, selector, name) => {
|
|
|
2657
2657
|
// src/mcp/events-tool.ts
|
|
2658
2658
|
import {
|
|
2659
2659
|
RPC_METHODS as RPC_METHODS6,
|
|
2660
|
+
renderEventSignature,
|
|
2660
2661
|
toAppEvent as toAppEvent2
|
|
2661
2662
|
} from "@appduct/shared";
|
|
2662
2663
|
|
|
@@ -2760,16 +2761,36 @@ var waitForAppEvent = async (stream, options) => {
|
|
|
2760
2761
|
};
|
|
2761
2762
|
|
|
2762
2763
|
// src/mcp/events-tool.ts
|
|
2764
|
+
var LIST_EVENTS_TOOL_NAME = "appduct_list_events";
|
|
2763
2765
|
var EVENTS_TOOL_NAME = "appduct_events";
|
|
2764
2766
|
var WAIT_FOR_EVENT_TOOL_NAME = "appduct_wait_for_event";
|
|
2765
2767
|
var DEFAULT_EVENTS_LIMIT = 50;
|
|
2766
2768
|
var DEFAULT_EVENTS_PAYLOAD_MAX_BYTES = 4096;
|
|
2769
|
+
var DEFAULT_LIST_EVENTS_LIMIT = 50;
|
|
2767
2770
|
var DEFAULT_WAIT_FOR_EVENT_TIMEOUT_MS = 12e4;
|
|
2768
2771
|
var MAX_WAIT_FOR_EVENT_TIMEOUT_MS = 25 * 60 * 1e3;
|
|
2769
2772
|
var WAIT_FOR_EVENT_PROGRESS_INTERVAL_MS = 6e4;
|
|
2770
2773
|
var clampWaitForEventTimeoutMs = (requestedMs) => {
|
|
2771
2774
|
return Math.min(requestedMs ?? DEFAULT_WAIT_FOR_EVENT_TIMEOUT_MS, MAX_WAIT_FOR_EVENT_TIMEOUT_MS);
|
|
2772
2775
|
};
|
|
2776
|
+
var LIST_EVENTS_TOOL_DESCRIPTOR = {
|
|
2777
|
+
name: LIST_EVENTS_TOOL_NAME,
|
|
2778
|
+
description: `List the events the connected app declared, as one-line signatures (\`name { field: type }\`) with each event's description. Call this before appduct_wait_for_event or appduct_events so you wait on a name the app really posts instead of guessing one. An app that declares no events returns an empty list, which does not mean it posts none. name is a whole-name, case-sensitive glob (* matches any run of characters), e.g. "cart.*"; a name without * that matches a declared event also returns that event's payload_schema. limit (default ${DEFAULT_LIST_EVENTS_LIMIT}) and offset page the name-sorted list, and total counts every match before paging. Returns { session, total, limit, events }, each event { name, signature, description }.`,
|
|
2779
|
+
inputSchema: {
|
|
2780
|
+
type: "object",
|
|
2781
|
+
properties: {
|
|
2782
|
+
selector: {
|
|
2783
|
+
type: "string",
|
|
2784
|
+
minLength: 1,
|
|
2785
|
+
description: "Session alias or id. Omit to target the sole active/suspended session."
|
|
2786
|
+
},
|
|
2787
|
+
name: { type: "string", minLength: 1 },
|
|
2788
|
+
limit: { type: "integer", exclusiveMinimum: 0 },
|
|
2789
|
+
offset: { type: "integer", minimum: 0 }
|
|
2790
|
+
},
|
|
2791
|
+
additionalProperties: false
|
|
2792
|
+
}
|
|
2793
|
+
};
|
|
2773
2794
|
var EVENTS_TOOL_DESCRIPTOR = {
|
|
2774
2795
|
name: EVENTS_TOOL_NAME,
|
|
2775
2796
|
description: `Drain the events the app posted with postEvent(name, payload) that the daemon retained for a session since a cursor, for checking what the app reported after calling a tool or triggering app behavior. With no selector, targets the sole active/suspended session. name filters to events whose name matches a whole-name, case-sensitive glob (* matches any run of characters; a pattern without * is an exact name), e.g. "cart.*". Returns { events, cursor, dropped, remaining } with each event as { name, payload, ts, seq, sessionId, alias } or, once a payload's JSON exceeds payloadMaxBytes (default 4096), as { name, payloadPreview, truncated: true, payloadBytes, ts, seq, sessionId, alias } instead \u2014 check truncated before reading payload. pass cursor back as since on the next call to avoid re-reading events you've already seen; dropped counts app events after since that were evicted before this call could return them (0 once nothing has fallen off), and remaining counts events still matching this query after the returned page (0 on the last page). limit (default 50) keeps the OLDEST events in the window and advances cursor only past what was actually returned, so repeated calls page forward through everything retained rather than skipping ahead.`,
|
|
@@ -2859,6 +2880,31 @@ var rejectMatch = (args) => {
|
|
|
2859
2880
|
);
|
|
2860
2881
|
}
|
|
2861
2882
|
};
|
|
2883
|
+
var handleListEventsTool = async (rawArgs, call) => {
|
|
2884
|
+
const args = asRecord3(rawArgs);
|
|
2885
|
+
rejectUnknownKeys(args, LIST_EVENTS_TOOL_NAME, ["selector", "name", "limit", "offset"]);
|
|
2886
|
+
const session = await resolveSession(call, asOptionalString(args.selector, "selector"));
|
|
2887
|
+
const name = asOptionalString(args.name, "name");
|
|
2888
|
+
const limit = args.limit ?? DEFAULT_LIST_EVENTS_LIMIT;
|
|
2889
|
+
const result = await call(RPC_METHODS6.eventsList, {
|
|
2890
|
+
selector: session.sessionId,
|
|
2891
|
+
...name !== void 0 ? { name } : {},
|
|
2892
|
+
limit,
|
|
2893
|
+
...args.offset !== void 0 && args.offset !== null ? { offset: args.offset } : {}
|
|
2894
|
+
});
|
|
2895
|
+
const lookup = name !== void 0 && !name.includes("*");
|
|
2896
|
+
return {
|
|
2897
|
+
session: session.alias,
|
|
2898
|
+
total: result.total,
|
|
2899
|
+
limit,
|
|
2900
|
+
events: result.events.map((event) => ({
|
|
2901
|
+
name: event.name,
|
|
2902
|
+
signature: renderEventSignature(event),
|
|
2903
|
+
description: event.description,
|
|
2904
|
+
...lookup && event.payload_schema !== void 0 ? { payload_schema: event.payload_schema } : {}
|
|
2905
|
+
}))
|
|
2906
|
+
};
|
|
2907
|
+
};
|
|
2862
2908
|
var handleEventsTool = async (rawArgs, deps) => {
|
|
2863
2909
|
const args = asRecord3(rawArgs);
|
|
2864
2910
|
rejectKinds(args);
|
|
@@ -3153,6 +3199,7 @@ var createMcpServer = async (options) => {
|
|
|
3153
3199
|
LIST_TOOLS_TOOL_DESCRIPTOR,
|
|
3154
3200
|
DESCRIBE_TOOL_TOOL_DESCRIPTOR,
|
|
3155
3201
|
CALL_TOOL_TOOL_DESCRIPTOR,
|
|
3202
|
+
LIST_EVENTS_TOOL_DESCRIPTOR,
|
|
3156
3203
|
EVENTS_TOOL_DESCRIPTOR,
|
|
3157
3204
|
WAIT_FOR_EVENT_TOOL_DESCRIPTOR
|
|
3158
3205
|
]
|
|
@@ -3181,6 +3228,9 @@ var createMcpServer = async (options) => {
|
|
|
3181
3228
|
await handleWaitForSessionTool(args, { stateDir: options.stateDir, spawn: options.spawn })
|
|
3182
3229
|
);
|
|
3183
3230
|
}
|
|
3231
|
+
if (name === LIST_EVENTS_TOOL_NAME) {
|
|
3232
|
+
return toolSuccessContent(await handleListEventsTool(args, stream.call));
|
|
3233
|
+
}
|
|
3184
3234
|
if (name === EVENTS_TOOL_NAME) {
|
|
3185
3235
|
return toolSuccessContent(await handleEventsTool(args, { call: stream.call }));
|
|
3186
3236
|
}
|
|
@@ -3329,6 +3379,7 @@ var formatJson = (value, flags) => {
|
|
|
3329
3379
|
import pc from "picocolors";
|
|
3330
3380
|
import {
|
|
3331
3381
|
formatAgentWebSocketUrl,
|
|
3382
|
+
renderEventSignature as renderEventSignature2,
|
|
3332
3383
|
renderToolSignature as renderToolSignature2,
|
|
3333
3384
|
summarizeToolDescription as summarizeToolDescription2
|
|
3334
3385
|
} from "@appduct/shared";
|
|
@@ -3387,6 +3438,13 @@ var formatDevice = (device) => {
|
|
|
3387
3438
|
const label = parts.length > 0 ? parts.join(" ") : "unknown device";
|
|
3388
3439
|
return device.os ? `${label} (${device.os})` : label;
|
|
3389
3440
|
};
|
|
3441
|
+
var SUSPEND_REASON_LABELS = {
|
|
3442
|
+
app_backgrounded: "app in background",
|
|
3443
|
+
connection_lost: "connection lost"
|
|
3444
|
+
};
|
|
3445
|
+
var formatSessionState = (session) => {
|
|
3446
|
+
return session.suspendReason ? `${session.state} (${SUSPEND_REASON_LABELS[session.suspendReason]})` : session.state;
|
|
3447
|
+
};
|
|
3390
3448
|
var renderLsData = (colors, data, now) => {
|
|
3391
3449
|
if (data.length === 0) {
|
|
3392
3450
|
return [colors.dim("Sessions"), " No Appduct sessions are registered."];
|
|
@@ -3395,7 +3453,7 @@ var renderLsData = (colors, data, now) => {
|
|
|
3395
3453
|
const headers = ["Alias", "State", "Device", "Tools", "Age"];
|
|
3396
3454
|
const rows = data.map((session) => [
|
|
3397
3455
|
session.alias,
|
|
3398
|
-
session
|
|
3456
|
+
formatSessionState(session),
|
|
3399
3457
|
formatDevice(session.device),
|
|
3400
3458
|
String(session.toolCount),
|
|
3401
3459
|
formatAge(session.claimedAt ?? session.createdAt, nowIso)
|
|
@@ -3569,6 +3627,53 @@ var renderToolsListData = (colors, data, flags, full) => {
|
|
|
3569
3627
|
}
|
|
3570
3628
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
3571
3629
|
};
|
|
3630
|
+
var renderEventsTruncationLine = (data) => {
|
|
3631
|
+
const offset = data.offset ?? 0;
|
|
3632
|
+
if (data.events.length >= data.total) {
|
|
3633
|
+
return [];
|
|
3634
|
+
}
|
|
3635
|
+
return [
|
|
3636
|
+
"",
|
|
3637
|
+
`Showing ${data.events.length} of ${data.total} events (offset ${offset}). Narrow with --name <glob> or page with --offset <n>.`
|
|
3638
|
+
];
|
|
3639
|
+
};
|
|
3640
|
+
var renderEventsListData = (colors, data, flags) => {
|
|
3641
|
+
const [only] = data.events;
|
|
3642
|
+
if (data.name !== void 0 && !data.name.includes("*") && only !== void 0) {
|
|
3643
|
+
return renderFields(
|
|
3644
|
+
colors.green(`Event: ${only.name}`),
|
|
3645
|
+
[
|
|
3646
|
+
["Signature", renderEventSignature2(only)],
|
|
3647
|
+
["Description", only.description],
|
|
3648
|
+
["Payload schema", only.payload_schema]
|
|
3649
|
+
],
|
|
3650
|
+
flags
|
|
3651
|
+
);
|
|
3652
|
+
}
|
|
3653
|
+
if (data.events.length === 0 && data.total > 0) {
|
|
3654
|
+
return [
|
|
3655
|
+
colors.green("Events"),
|
|
3656
|
+
` No events at offset ${data.offset ?? 0}; ${data.total} matching event${data.total === 1 ? "" : "s"} in total.`
|
|
3657
|
+
];
|
|
3658
|
+
}
|
|
3659
|
+
if (data.events.length === 0) {
|
|
3660
|
+
return [
|
|
3661
|
+
colors.green("Events"),
|
|
3662
|
+
data.name === void 0 ? " No events declared." : ` No events match ${JSON.stringify(data.name)}.`
|
|
3663
|
+
];
|
|
3664
|
+
}
|
|
3665
|
+
const lines = data.events.flatMap((event) => [
|
|
3666
|
+
` ${renderEventSignature2(event)}`,
|
|
3667
|
+
` ${summarizeToolDescription2(event.description)}`
|
|
3668
|
+
]);
|
|
3669
|
+
return [
|
|
3670
|
+
colors.green("Events"),
|
|
3671
|
+
...lines,
|
|
3672
|
+
...renderEventsTruncationLine(data),
|
|
3673
|
+
"",
|
|
3674
|
+
"Run `appduct events ls --name <name>` for an event's full payload schema."
|
|
3675
|
+
];
|
|
3676
|
+
};
|
|
3572
3677
|
var renderInvokeData = (colors, data, flags) => {
|
|
3573
3678
|
return [colors.green("Result"), formatScalar(data, flags)];
|
|
3574
3679
|
};
|
|
@@ -3760,6 +3865,8 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
3760
3865
|
return renderToolsListData(colors, data, flags, options.full);
|
|
3761
3866
|
case "tools describe":
|
|
3762
3867
|
return renderToolDetail(colors, data, flags);
|
|
3868
|
+
case "events ls":
|
|
3869
|
+
return renderEventsListData(colors, data, flags);
|
|
3763
3870
|
case "tools call":
|
|
3764
3871
|
return renderInvokeData(colors, data, flags);
|
|
3765
3872
|
case "sessions revoke":
|
|
@@ -213,6 +213,7 @@ var formatJson = (value, flags) => {
|
|
|
213
213
|
import pc from "picocolors";
|
|
214
214
|
import {
|
|
215
215
|
formatAgentWebSocketUrl,
|
|
216
|
+
renderEventSignature,
|
|
216
217
|
renderToolSignature,
|
|
217
218
|
summarizeToolDescription
|
|
218
219
|
} from "@appduct/shared";
|
|
@@ -308,6 +309,13 @@ var formatDevice = (device) => {
|
|
|
308
309
|
const label = parts.length > 0 ? parts.join(" ") : "unknown device";
|
|
309
310
|
return device.os ? `${label} (${device.os})` : label;
|
|
310
311
|
};
|
|
312
|
+
var SUSPEND_REASON_LABELS = {
|
|
313
|
+
app_backgrounded: "app in background",
|
|
314
|
+
connection_lost: "connection lost"
|
|
315
|
+
};
|
|
316
|
+
var formatSessionState = (session) => {
|
|
317
|
+
return session.suspendReason ? `${session.state} (${SUSPEND_REASON_LABELS[session.suspendReason]})` : session.state;
|
|
318
|
+
};
|
|
311
319
|
var renderLsData = (colors, data, now) => {
|
|
312
320
|
if (data.length === 0) {
|
|
313
321
|
return [colors.dim("Sessions"), " No Appduct sessions are registered."];
|
|
@@ -316,7 +324,7 @@ var renderLsData = (colors, data, now) => {
|
|
|
316
324
|
const headers = ["Alias", "State", "Device", "Tools", "Age"];
|
|
317
325
|
const rows = data.map((session) => [
|
|
318
326
|
session.alias,
|
|
319
|
-
session
|
|
327
|
+
formatSessionState(session),
|
|
320
328
|
formatDevice(session.device),
|
|
321
329
|
String(session.toolCount),
|
|
322
330
|
formatAge(session.claimedAt ?? session.createdAt, nowIso)
|
|
@@ -490,6 +498,53 @@ var renderToolsListData = (colors, data, flags, full) => {
|
|
|
490
498
|
}
|
|
491
499
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
492
500
|
};
|
|
501
|
+
var renderEventsTruncationLine = (data) => {
|
|
502
|
+
const offset = data.offset ?? 0;
|
|
503
|
+
if (data.events.length >= data.total) {
|
|
504
|
+
return [];
|
|
505
|
+
}
|
|
506
|
+
return [
|
|
507
|
+
"",
|
|
508
|
+
`Showing ${data.events.length} of ${data.total} events (offset ${offset}). Narrow with --name <glob> or page with --offset <n>.`
|
|
509
|
+
];
|
|
510
|
+
};
|
|
511
|
+
var renderEventsListData = (colors, data, flags) => {
|
|
512
|
+
const [only] = data.events;
|
|
513
|
+
if (data.name !== void 0 && !data.name.includes("*") && only !== void 0) {
|
|
514
|
+
return renderFields(
|
|
515
|
+
colors.green(`Event: ${only.name}`),
|
|
516
|
+
[
|
|
517
|
+
["Signature", renderEventSignature(only)],
|
|
518
|
+
["Description", only.description],
|
|
519
|
+
["Payload schema", only.payload_schema]
|
|
520
|
+
],
|
|
521
|
+
flags
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
if (data.events.length === 0 && data.total > 0) {
|
|
525
|
+
return [
|
|
526
|
+
colors.green("Events"),
|
|
527
|
+
` No events at offset ${data.offset ?? 0}; ${data.total} matching event${data.total === 1 ? "" : "s"} in total.`
|
|
528
|
+
];
|
|
529
|
+
}
|
|
530
|
+
if (data.events.length === 0) {
|
|
531
|
+
return [
|
|
532
|
+
colors.green("Events"),
|
|
533
|
+
data.name === void 0 ? " No events declared." : ` No events match ${JSON.stringify(data.name)}.`
|
|
534
|
+
];
|
|
535
|
+
}
|
|
536
|
+
const lines = data.events.flatMap((event) => [
|
|
537
|
+
` ${renderEventSignature(event)}`,
|
|
538
|
+
` ${summarizeToolDescription(event.description)}`
|
|
539
|
+
]);
|
|
540
|
+
return [
|
|
541
|
+
colors.green("Events"),
|
|
542
|
+
...lines,
|
|
543
|
+
...renderEventsTruncationLine(data),
|
|
544
|
+
"",
|
|
545
|
+
"Run `appduct events ls --name <name>` for an event's full payload schema."
|
|
546
|
+
];
|
|
547
|
+
};
|
|
493
548
|
var renderInvokeData = (colors, data, flags) => {
|
|
494
549
|
return [colors.green("Result"), formatScalar(data, flags)];
|
|
495
550
|
};
|
|
@@ -681,6 +736,8 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
681
736
|
return renderToolsListData(colors, data, flags, options.full);
|
|
682
737
|
case "tools describe":
|
|
683
738
|
return renderToolDetail(colors, data, flags);
|
|
739
|
+
case "events ls":
|
|
740
|
+
return renderEventsListData(colors, data, flags);
|
|
684
741
|
case "tools call":
|
|
685
742
|
return renderInvokeData(colors, data, flags);
|
|
686
743
|
case "sessions revoke":
|