appduct 0.12.0 → 0.13.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 +41 -36
- package/dist/bin.js +44 -36
- package/dist/cli/command-options.d.ts +7 -17
- package/dist/cli/result-types.d.ts +11 -8
- package/dist/cli/routes/daemon/index.js +12 -16
- package/dist/cli/routes/daemon/run.js +136 -28
- package/dist/cli/routes/daemon/start.js +12 -16
- package/dist/cli/routes/daemon/status.js +12 -16
- package/dist/cli/routes/daemon/stop.js +12 -16
- package/dist/cli/routes/doctor.js +12 -16
- package/dist/cli/routes/events/index.d.ts +9 -0
- package/dist/cli/routes/events/index.js +842 -0
- package/dist/cli/routes/events/shared-options.d.ts +12 -0
- package/dist/cli/routes/events/shared-options.js +102 -0
- package/dist/cli/routes/events/since.d.ts +6 -0
- package/dist/cli/routes/events/since.js +1977 -0
- package/dist/cli/routes/events/tail.d.ts +6 -0
- package/dist/cli/routes/{events.js → events/tail.js} +177 -162
- package/dist/cli/routes/init.js +14 -18
- package/dist/cli/routes/keygen.js +12 -16
- package/dist/cli/routes/mcp.js +181 -165
- package/dist/cli/routes/sessions/index.d.ts +7 -0
- package/dist/cli/routes/sessions/index.js +843 -0
- package/dist/cli/routes/sessions/link.d.ts +4 -0
- package/dist/cli/routes/{link.js → sessions/link.js} +13 -17
- package/dist/cli/routes/sessions/ls.d.ts +4 -0
- package/dist/cli/routes/{ls.js → sessions/ls.js} +13 -17
- package/dist/cli/routes/sessions/revoke.d.ts +4 -0
- package/dist/cli/routes/{revoke.js → sessions/revoke.js} +14 -18
- package/dist/cli/routes/tools/call.d.ts +4 -0
- package/dist/cli/routes/{invoke.js → tools/call.js} +15 -19
- package/dist/cli/routes/tools/describe.d.ts +6 -0
- package/dist/cli/routes/tools/describe.js +1837 -0
- package/dist/cli/routes/tools/index.d.ts +6 -0
- package/dist/cli/routes/tools/index.js +843 -0
- package/dist/cli/routes/tools/ls.d.ts +4 -0
- package/dist/cli/routes/{tools.js → tools/ls.js} +40 -73
- package/dist/cli/routes/tools/shared-options.d.ts +16 -0
- package/dist/cli/routes/tools/shared-options.js +122 -0
- package/dist/client/app-client.d.ts +96 -37
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.js +178 -138
- package/dist/commands/events.d.ts +31 -14
- package/dist/commands/invoke.d.ts +1 -1
- package/dist/commands/link.d.ts +1 -1
- package/dist/commands/ls.d.ts +1 -1
- package/dist/commands/revoke.d.ts +1 -1
- package/dist/commands/tools.d.ts +12 -13
- package/dist/daemon/config.d.ts +1 -1
- package/dist/daemon/event-bus.d.ts +32 -0
- package/dist/daemon/rpc-errors.d.ts +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/events/index.d.ts +60 -0
- package/dist/index.js +56 -39
- package/dist/link.d.ts +1 -1
- package/dist/mcp/app-tools.d.ts +3 -2
- package/dist/mcp/connect-tool.d.ts +1 -1
- package/dist/mcp/events-tool.d.ts +28 -27
- package/dist/native-scheme.d.ts +1 -1
- package/dist/output.d.ts +29 -6
- package/dist/rpc/client.d.ts +1 -1
- package/dist/scheme.d.ts +4 -4
- package/package.json +2 -2
- package/dist/cli/routes/events.d.ts +0 -3
- package/dist/cli/routes/invoke.d.ts +0 -3
- package/dist/cli/routes/link.d.ts +0 -3
- package/dist/cli/routes/ls.d.ts +0 -3
- package/dist/cli/routes/revoke.d.ts +0 -3
- package/dist/cli/routes/tools.d.ts +0 -3
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Route for `appduct events tail` — loaded by `routes/events/index.ts`'s router only when it
|
|
2
|
+
* runs (issue #96; replaces the removed `appduct events` streaming form). `--follow` is accepted
|
|
3
|
+
* (declared at the `events` noun level in `create-cli.ts`) but never read here: the default
|
|
4
|
+
* behavior already follows, so the flag exists only for script readability. */
|
|
5
|
+
import type { Route } from "../../router.js";
|
|
6
|
+
export declare const route: Route;
|
|
@@ -1015,12 +1015,14 @@ var handleEventsSinceCommand = async (options, context) => {
|
|
|
1015
1015
|
try {
|
|
1016
1016
|
const since = await stream.call(RPC_METHODS2.eventsSince, {
|
|
1017
1017
|
selector: options.selector,
|
|
1018
|
-
since: options.since
|
|
1018
|
+
since: options.since,
|
|
1019
|
+
name: options.name,
|
|
1020
|
+
payloadMaxBytes: options.payloadMaxBytes
|
|
1019
1021
|
});
|
|
1020
1022
|
for (const event of since.events) {
|
|
1021
1023
|
context.onEvent(event);
|
|
1022
1024
|
}
|
|
1023
|
-
context.onCursor?.(since.cursor);
|
|
1025
|
+
context.onCursor?.({ cursor: since.cursor, dropped: since.dropped, remaining: since.remaining });
|
|
1024
1026
|
} finally {
|
|
1025
1027
|
stream.close();
|
|
1026
1028
|
}
|
|
@@ -1035,7 +1037,9 @@ var handleEventsCommand = async (options, context) => {
|
|
|
1035
1037
|
try {
|
|
1036
1038
|
await stream.call(RPC_METHODS2.eventsSubscribe, {
|
|
1037
1039
|
sessionSelector: options.selector,
|
|
1038
|
-
kinds: ["app_event"]
|
|
1040
|
+
kinds: ["app_event"],
|
|
1041
|
+
name: options.name,
|
|
1042
|
+
payloadMaxBytes: options.payloadMaxBytes
|
|
1039
1043
|
});
|
|
1040
1044
|
} catch (error) {
|
|
1041
1045
|
stream.close();
|
|
@@ -1071,124 +1075,6 @@ var handleEventsCommand = async (options, context) => {
|
|
|
1071
1075
|
};
|
|
1072
1076
|
};
|
|
1073
1077
|
|
|
1074
|
-
// src/errors.ts
|
|
1075
|
-
var EXIT_CODE_BY_ERROR_TYPE = {
|
|
1076
|
-
usage_error: 64,
|
|
1077
|
-
validation_error: 65,
|
|
1078
|
-
// EX_NOINPUT (66): "an input file did not exist or was not readable" — `doctor` throws this for a
|
|
1079
|
-
// missing external tool or an unreadable/corrupt artifact, deliberately distinct from every other
|
|
1080
|
-
// code here so a release pipeline can't mistake "we couldn't tell" for either a clean pass or an
|
|
1081
|
-
// assertion failure (docs/tasks/08-appduct-doctor.md).
|
|
1082
|
-
inspection_error: 66,
|
|
1083
|
-
connection_error: 70,
|
|
1084
|
-
session_error: 71,
|
|
1085
|
-
tool_error: 72,
|
|
1086
|
-
permission_error: 77,
|
|
1087
|
-
internal_error: 1,
|
|
1088
|
-
// `doctor --assert-present`/`--assert-absent`: the artifact was inspected successfully and the
|
|
1089
|
-
// assertion did not hold. Distinct from `inspection_error` (66) — this means the answer is known
|
|
1090
|
-
// and it's "no", not "couldn't tell" — and distinct from `internal_error` (1) so a caller can't
|
|
1091
|
-
// conflate a normal assertion failure with an unexpected crash.
|
|
1092
|
-
assertion_error: 3
|
|
1093
|
-
};
|
|
1094
|
-
var RPC_ERROR_EXIT_CLASS = {
|
|
1095
|
-
no_session: "session_error",
|
|
1096
|
-
ambiguous_session: "session_error",
|
|
1097
|
-
unknown_session: "session_error",
|
|
1098
|
-
session_not_active: "session_error",
|
|
1099
|
-
session_suspended: "session_error",
|
|
1100
|
-
tool_not_found: "tool_error",
|
|
1101
|
-
tool_input_validation_error: "tool_error",
|
|
1102
|
-
tool_output_validation_error: "tool_error",
|
|
1103
|
-
tool_execution_error: "tool_error",
|
|
1104
|
-
tool_serialization_error: "tool_error",
|
|
1105
|
-
tool_timeout: "tool_error",
|
|
1106
|
-
tool_cancelled: "tool_error",
|
|
1107
|
-
policy_denied: "permission_error",
|
|
1108
|
-
invalid_request: "validation_error"
|
|
1109
|
-
};
|
|
1110
|
-
var AppductCliError = class extends Error {
|
|
1111
|
-
type;
|
|
1112
|
-
details;
|
|
1113
|
-
constructor(type, message, details) {
|
|
1114
|
-
super(message);
|
|
1115
|
-
this.name = "AppductCliError";
|
|
1116
|
-
this.type = type;
|
|
1117
|
-
this.details = details;
|
|
1118
|
-
}
|
|
1119
|
-
};
|
|
1120
|
-
var usageError = (message, details) => {
|
|
1121
|
-
return new AppductCliError("usage_error", message, details);
|
|
1122
|
-
};
|
|
1123
|
-
var isAppductCliError = (value) => {
|
|
1124
|
-
return value instanceof AppductCliError;
|
|
1125
|
-
};
|
|
1126
|
-
var rpcErrorClass = (error) => {
|
|
1127
|
-
const type = error.data?.type;
|
|
1128
|
-
return type ? RPC_ERROR_EXIT_CLASS[type] : void 0;
|
|
1129
|
-
};
|
|
1130
|
-
var toCliError = (error) => {
|
|
1131
|
-
if (isAppductCliError(error)) {
|
|
1132
|
-
return {
|
|
1133
|
-
type: error.type,
|
|
1134
|
-
message: error.message,
|
|
1135
|
-
details: error.details
|
|
1136
|
-
};
|
|
1137
|
-
}
|
|
1138
|
-
if (error instanceof DaemonVersionMismatchError) {
|
|
1139
|
-
return {
|
|
1140
|
-
type: "connection_error",
|
|
1141
|
-
message: error.message,
|
|
1142
|
-
details: {
|
|
1143
|
-
daemon_version: error.daemonVersion,
|
|
1144
|
-
client_version: error.clientVersion,
|
|
1145
|
-
session_count: error.sessionCount,
|
|
1146
|
-
pending_link_count: error.pendingLinkCount
|
|
1147
|
-
}
|
|
1148
|
-
};
|
|
1149
|
-
}
|
|
1150
|
-
if (error instanceof DaemonRpcError && error.data?.type) {
|
|
1151
|
-
return {
|
|
1152
|
-
type: error.data.type,
|
|
1153
|
-
message: error.message,
|
|
1154
|
-
details: error.data.details
|
|
1155
|
-
};
|
|
1156
|
-
}
|
|
1157
|
-
if (isDaemonUnreachableError(error)) {
|
|
1158
|
-
return {
|
|
1159
|
-
type: "connection_error",
|
|
1160
|
-
message: error instanceof Error ? error.message : "The Appduct daemon is unreachable."
|
|
1161
|
-
};
|
|
1162
|
-
}
|
|
1163
|
-
if (error instanceof Error) {
|
|
1164
|
-
return {
|
|
1165
|
-
type: "internal_error",
|
|
1166
|
-
message: error.message
|
|
1167
|
-
};
|
|
1168
|
-
}
|
|
1169
|
-
return {
|
|
1170
|
-
type: "internal_error",
|
|
1171
|
-
message: "An unexpected error occurred.",
|
|
1172
|
-
details: error
|
|
1173
|
-
};
|
|
1174
|
-
};
|
|
1175
|
-
var getExitCodeForError = (error) => {
|
|
1176
|
-
if (isAppductCliError(error)) {
|
|
1177
|
-
return EXIT_CODE_BY_ERROR_TYPE[error.type];
|
|
1178
|
-
}
|
|
1179
|
-
if (error instanceof DaemonVersionMismatchError) {
|
|
1180
|
-
return EXIT_CODE_BY_ERROR_TYPE.connection_error;
|
|
1181
|
-
}
|
|
1182
|
-
if (error instanceof DaemonRpcError) {
|
|
1183
|
-
const cliErrorClass = rpcErrorClass(error);
|
|
1184
|
-
return EXIT_CODE_BY_ERROR_TYPE[cliErrorClass ?? "internal_error"];
|
|
1185
|
-
}
|
|
1186
|
-
if (isDaemonUnreachableError(error)) {
|
|
1187
|
-
return EXIT_CODE_BY_ERROR_TYPE.connection_error;
|
|
1188
|
-
}
|
|
1189
|
-
return EXIT_CODE_BY_ERROR_TYPE.internal_error;
|
|
1190
|
-
};
|
|
1191
|
-
|
|
1192
1078
|
// src/output.ts
|
|
1193
1079
|
import pc from "picocolors";
|
|
1194
1080
|
import {
|
|
@@ -1315,9 +1201,6 @@ var renderLsData = (colors, data, now) => {
|
|
|
1315
1201
|
...rows.map((row) => ` ${row.map((cell, index) => cell.padEnd(widths[index])).join(" ")}`)
|
|
1316
1202
|
];
|
|
1317
1203
|
};
|
|
1318
|
-
var isToolsListing = (data) => {
|
|
1319
|
-
return typeof data === "object" && data !== null && Array.isArray(data.tools);
|
|
1320
|
-
};
|
|
1321
1204
|
var isToolGroupsListing = (data) => {
|
|
1322
1205
|
return typeof data === "object" && data !== null && Array.isArray(data.groups) && !Array.isArray(data.tools);
|
|
1323
1206
|
};
|
|
@@ -1335,7 +1218,7 @@ var renderEmptyToolsLine = (data) => {
|
|
|
1335
1218
|
}
|
|
1336
1219
|
if (data.group !== void 0) {
|
|
1337
1220
|
const match = data.filter === void 0 ? "" : ` match ${JSON.stringify(data.filter)}`;
|
|
1338
|
-
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools --groups\` to see the session's groups.`;
|
|
1221
|
+
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools ls --groups\` to see the session's groups.`;
|
|
1339
1222
|
}
|
|
1340
1223
|
return data.filter === void 0 ? " No tools registered." : ` No tools match ${JSON.stringify(data.filter)}.`;
|
|
1341
1224
|
};
|
|
@@ -1417,7 +1300,7 @@ var renderToolSummaryTable = (colors, data) => {
|
|
|
1417
1300
|
...grouped ? renderGroupedToolLines(colors, data.tools) : data.tools.flatMap((tool) => renderToolSummaryLines(tool, " ")),
|
|
1418
1301
|
...renderTruncationLine(data),
|
|
1419
1302
|
"",
|
|
1420
|
-
"Run `appduct tools <name>` for a tool's full schema."
|
|
1303
|
+
"Run `appduct tools describe <name>` for a tool's full schema."
|
|
1421
1304
|
];
|
|
1422
1305
|
};
|
|
1423
1306
|
var renderToolDetail = (colors, tool, flags) => {
|
|
@@ -1469,16 +1352,13 @@ var renderToolGroups = (colors, data) => {
|
|
|
1469
1352
|
colors.green("Groups"),
|
|
1470
1353
|
...data.groups.map((entry) => ` ${label(entry).padEnd(width)} ${String(entry.total).padStart(countWidth)}`),
|
|
1471
1354
|
"",
|
|
1472
|
-
`${data.total} tool${data.total === 1 ? "" : "s"} in total. ` + (hasAnyGroup(data.groups) ? "Run `appduct tools --group <name>` to list one group's tools." : "No tool declares a group.")
|
|
1355
|
+
`${data.total} tool${data.total === 1 ? "" : "s"} in total. ` + (hasAnyGroup(data.groups) ? "Run `appduct tools ls --group <name>` to list one group's tools." : "No tool declares a group.")
|
|
1473
1356
|
];
|
|
1474
1357
|
};
|
|
1475
|
-
var
|
|
1358
|
+
var renderToolsListData = (colors, data, flags, full) => {
|
|
1476
1359
|
if (isToolGroupsListing(data)) {
|
|
1477
1360
|
return renderToolGroups(colors, data);
|
|
1478
1361
|
}
|
|
1479
|
-
if (!isToolsListing(data)) {
|
|
1480
|
-
return renderToolDetail(colors, data, flags);
|
|
1481
|
-
}
|
|
1482
1362
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
1483
1363
|
};
|
|
1484
1364
|
var renderInvokeData = (colors, data, flags) => {
|
|
@@ -1664,15 +1544,17 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
1664
1544
|
return renderInitData(colors, data, flags);
|
|
1665
1545
|
case "keygen":
|
|
1666
1546
|
return renderKeygenData(colors, data, flags);
|
|
1667
|
-
case "link":
|
|
1547
|
+
case "sessions link":
|
|
1668
1548
|
return renderLinkData(colors, data, flags, options.qr);
|
|
1669
|
-
case "ls":
|
|
1549
|
+
case "sessions ls":
|
|
1670
1550
|
return renderLsData(colors, data, options.now ?? /* @__PURE__ */ new Date());
|
|
1671
|
-
case "tools":
|
|
1672
|
-
return
|
|
1673
|
-
case "
|
|
1551
|
+
case "tools ls":
|
|
1552
|
+
return renderToolsListData(colors, data, flags, options.full);
|
|
1553
|
+
case "tools describe":
|
|
1554
|
+
return renderToolDetail(colors, data, flags);
|
|
1555
|
+
case "tools call":
|
|
1674
1556
|
return renderInvokeData(colors, data, flags);
|
|
1675
|
-
case "revoke":
|
|
1557
|
+
case "sessions revoke":
|
|
1676
1558
|
return renderRevokeData(colors, data);
|
|
1677
1559
|
case "daemon run":
|
|
1678
1560
|
return renderDaemonRunData(colors, data, flags);
|
|
@@ -1742,25 +1624,158 @@ var renderEventLine = (event, flags) => {
|
|
|
1742
1624
|
const dataSuffix = event.data === void 0 ? "" : ` ${formatJson(event.data, flags)}`;
|
|
1743
1625
|
return `${colors.dim(timestamp)} ${colors.green(event.kind)}${target ? ` ${target}` : ""}${dataSuffix}`;
|
|
1744
1626
|
};
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1627
|
+
|
|
1628
|
+
// src/errors.ts
|
|
1629
|
+
var EXIT_CODE_BY_ERROR_TYPE = {
|
|
1630
|
+
usage_error: 64,
|
|
1631
|
+
validation_error: 65,
|
|
1632
|
+
// EX_NOINPUT (66): "an input file did not exist or was not readable" — `doctor` throws this for a
|
|
1633
|
+
// missing external tool or an unreadable/corrupt artifact, deliberately distinct from every other
|
|
1634
|
+
// code here so a release pipeline can't mistake "we couldn't tell" for either a clean pass or an
|
|
1635
|
+
// assertion failure (docs/tasks/08-appduct-doctor.md).
|
|
1636
|
+
inspection_error: 66,
|
|
1637
|
+
connection_error: 70,
|
|
1638
|
+
session_error: 71,
|
|
1639
|
+
tool_error: 72,
|
|
1640
|
+
permission_error: 77,
|
|
1641
|
+
internal_error: 1,
|
|
1642
|
+
// `doctor --assert-present`/`--assert-absent`: the artifact was inspected successfully and the
|
|
1643
|
+
// assertion did not hold. Distinct from `inspection_error` (66) — this means the answer is known
|
|
1644
|
+
// and it's "no", not "couldn't tell" — and distinct from `internal_error` (1) so a caller can't
|
|
1645
|
+
// conflate a normal assertion failure with an unexpected crash.
|
|
1646
|
+
assertion_error: 3
|
|
1647
|
+
};
|
|
1648
|
+
var RPC_ERROR_EXIT_CLASS = {
|
|
1649
|
+
no_session: "session_error",
|
|
1650
|
+
ambiguous_session: "session_error",
|
|
1651
|
+
unknown_session: "session_error",
|
|
1652
|
+
session_not_active: "session_error",
|
|
1653
|
+
session_suspended: "session_error",
|
|
1654
|
+
tool_not_found: "tool_error",
|
|
1655
|
+
tool_input_validation_error: "tool_error",
|
|
1656
|
+
tool_output_validation_error: "tool_error",
|
|
1657
|
+
tool_execution_error: "tool_error",
|
|
1658
|
+
tool_serialization_error: "tool_error",
|
|
1659
|
+
tool_timeout: "tool_error",
|
|
1660
|
+
tool_cancelled: "tool_error",
|
|
1661
|
+
policy_denied: "permission_error",
|
|
1662
|
+
invalid_request: "validation_error"
|
|
1663
|
+
};
|
|
1664
|
+
var AppductCliError = class extends Error {
|
|
1665
|
+
type;
|
|
1666
|
+
details;
|
|
1667
|
+
constructor(type, message, details) {
|
|
1668
|
+
super(message);
|
|
1669
|
+
this.name = "AppductCliError";
|
|
1670
|
+
this.type = type;
|
|
1671
|
+
this.details = details;
|
|
1748
1672
|
}
|
|
1749
|
-
|
|
1750
|
-
|
|
1673
|
+
};
|
|
1674
|
+
var usageError = (message, details) => {
|
|
1675
|
+
return new AppductCliError("usage_error", message, details);
|
|
1676
|
+
};
|
|
1677
|
+
var isAppductCliError = (value) => {
|
|
1678
|
+
return value instanceof AppductCliError;
|
|
1679
|
+
};
|
|
1680
|
+
var rpcErrorClass = (error) => {
|
|
1681
|
+
const type = error.data?.type;
|
|
1682
|
+
return type ? RPC_ERROR_EXIT_CLASS[type] : void 0;
|
|
1683
|
+
};
|
|
1684
|
+
var toCliError = (error) => {
|
|
1685
|
+
if (isAppductCliError(error)) {
|
|
1686
|
+
return {
|
|
1687
|
+
type: error.type,
|
|
1688
|
+
message: error.message,
|
|
1689
|
+
details: error.details
|
|
1690
|
+
};
|
|
1691
|
+
}
|
|
1692
|
+
if (error instanceof DaemonVersionMismatchError) {
|
|
1693
|
+
return {
|
|
1694
|
+
type: "connection_error",
|
|
1695
|
+
message: error.message,
|
|
1696
|
+
details: {
|
|
1697
|
+
daemon_version: error.daemonVersion,
|
|
1698
|
+
client_version: error.clientVersion,
|
|
1699
|
+
session_count: error.sessionCount,
|
|
1700
|
+
pending_link_count: error.pendingLinkCount
|
|
1701
|
+
}
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
if (error instanceof DaemonRpcError && error.data?.type) {
|
|
1705
|
+
return {
|
|
1706
|
+
type: error.data.type,
|
|
1707
|
+
message: error.message,
|
|
1708
|
+
details: error.data.details
|
|
1709
|
+
};
|
|
1710
|
+
}
|
|
1711
|
+
if (isDaemonUnreachableError(error)) {
|
|
1712
|
+
return {
|
|
1713
|
+
type: "connection_error",
|
|
1714
|
+
message: error instanceof Error ? error.message : "The Appduct daemon is unreachable."
|
|
1715
|
+
};
|
|
1716
|
+
}
|
|
1717
|
+
if (error instanceof Error) {
|
|
1718
|
+
return {
|
|
1719
|
+
type: "internal_error",
|
|
1720
|
+
message: error.message
|
|
1721
|
+
};
|
|
1722
|
+
}
|
|
1723
|
+
return {
|
|
1724
|
+
type: "internal_error",
|
|
1725
|
+
message: "An unexpected error occurred.",
|
|
1726
|
+
details: error
|
|
1727
|
+
};
|
|
1728
|
+
};
|
|
1729
|
+
var getExitCodeForError = (error) => {
|
|
1730
|
+
if (isAppductCliError(error)) {
|
|
1731
|
+
return EXIT_CODE_BY_ERROR_TYPE[error.type];
|
|
1732
|
+
}
|
|
1733
|
+
if (error instanceof DaemonVersionMismatchError) {
|
|
1734
|
+
return EXIT_CODE_BY_ERROR_TYPE.connection_error;
|
|
1735
|
+
}
|
|
1736
|
+
if (error instanceof DaemonRpcError) {
|
|
1737
|
+
const cliErrorClass = rpcErrorClass(error);
|
|
1738
|
+
return EXIT_CODE_BY_ERROR_TYPE[cliErrorClass ?? "internal_error"];
|
|
1739
|
+
}
|
|
1740
|
+
if (isDaemonUnreachableError(error)) {
|
|
1741
|
+
return EXIT_CODE_BY_ERROR_TYPE.connection_error;
|
|
1742
|
+
}
|
|
1743
|
+
return EXIT_CODE_BY_ERROR_TYPE.internal_error;
|
|
1751
1744
|
};
|
|
1752
1745
|
|
|
1753
1746
|
// src/cli/command-options.ts
|
|
1754
|
-
var
|
|
1747
|
+
var parsePositiveIntegerOption = (value, flagName) => {
|
|
1755
1748
|
if (value === void 0) {
|
|
1756
1749
|
return void 0;
|
|
1757
1750
|
}
|
|
1758
1751
|
const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : Number.NaN;
|
|
1759
|
-
if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed
|
|
1760
|
-
throw usageError(`"${flagName}" must be a
|
|
1752
|
+
if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed <= 0) {
|
|
1753
|
+
throw usageError(`"${flagName}" must be a positive integer.`);
|
|
1761
1754
|
}
|
|
1762
1755
|
return parsed;
|
|
1763
1756
|
};
|
|
1757
|
+
var readTextOption = (argv, value, flagName) => {
|
|
1758
|
+
if (value === void 0) {
|
|
1759
|
+
return void 0;
|
|
1760
|
+
}
|
|
1761
|
+
if (typeof value === "boolean") {
|
|
1762
|
+
throw usageError(`"${flagName}" requires a value.`);
|
|
1763
|
+
}
|
|
1764
|
+
let raw;
|
|
1765
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
1766
|
+
const token = argv[index];
|
|
1767
|
+
if (token === "--") {
|
|
1768
|
+
break;
|
|
1769
|
+
}
|
|
1770
|
+
if (token === flagName && index + 1 < argv.length) {
|
|
1771
|
+
raw = argv[index + 1];
|
|
1772
|
+
index += 1;
|
|
1773
|
+
} else if (token.startsWith(`${flagName}=`)) {
|
|
1774
|
+
raw = token.slice(flagName.length + 1);
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
return raw ?? String(Array.isArray(value) ? value.at(-1) : value);
|
|
1778
|
+
};
|
|
1764
1779
|
var splitOptionalSelector = (args, commandUsage) => {
|
|
1765
1780
|
if (args.length > 1) {
|
|
1766
1781
|
throw usageError(`Usage: ${commandUsage} (too many arguments).`);
|
|
@@ -1874,33 +1889,33 @@ var guarded = (context) => {
|
|
|
1874
1889
|
};
|
|
1875
1890
|
};
|
|
1876
1891
|
|
|
1877
|
-
// src/cli/routes/events.ts
|
|
1892
|
+
// src/cli/routes/events/shared-options.ts
|
|
1893
|
+
var parseEventsFilterFlags = (context) => {
|
|
1894
|
+
const { options } = context;
|
|
1895
|
+
return {
|
|
1896
|
+
name: readTextOption(context.argv, options.name, "--name"),
|
|
1897
|
+
payloadMaxBytes: parsePositiveIntegerOption(options.payloadMaxBytes, "--payload-max-bytes")
|
|
1898
|
+
};
|
|
1899
|
+
};
|
|
1900
|
+
|
|
1901
|
+
// src/cli/routes/events/tail.ts
|
|
1878
1902
|
var route = async (context) => {
|
|
1879
|
-
const {
|
|
1880
|
-
const follow = Boolean(options.follow);
|
|
1903
|
+
const { stateDir, env } = context;
|
|
1881
1904
|
return executeHostedCommand(
|
|
1882
1905
|
commandName(context),
|
|
1883
|
-
//
|
|
1884
|
-
//
|
|
1885
|
-
//
|
|
1886
|
-
// the daemon.
|
|
1906
|
+
// Argument parsing runs inside the handler (not the route body) so `executeHostedCommand`'s
|
|
1907
|
+
// own try/catch renders a bad argument as a normal usage_error instead of an uncaught
|
|
1908
|
+
// rejection, and before the version check so a typo never waits on the daemon.
|
|
1887
1909
|
() => {
|
|
1888
|
-
const { selector } = splitOptionalSelector(context.args, "events [selector]");
|
|
1889
|
-
const
|
|
1890
|
-
if (since !== void 0 && follow) {
|
|
1891
|
-
throw usageError('"--since" is a one-shot pull and cannot be combined with "--follow".');
|
|
1892
|
-
}
|
|
1910
|
+
const { selector } = splitOptionalSelector(context.args, "events tail [selector]");
|
|
1911
|
+
const { name, payloadMaxBytes } = parseEventsFilterFlags(context);
|
|
1893
1912
|
return guarded(context)(
|
|
1894
1913
|
() => handleEventsCommand(
|
|
1895
|
-
{ selector,
|
|
1914
|
+
{ selector, name, payloadMaxBytes },
|
|
1896
1915
|
{
|
|
1897
1916
|
stateDir,
|
|
1898
1917
|
onEvent: (event) => {
|
|
1899
1918
|
env.stdout.write(`${renderEventLine(event, env.flags)}
|
|
1900
|
-
`);
|
|
1901
|
-
},
|
|
1902
|
-
onCursor: (cursor) => {
|
|
1903
|
-
env.stdout.write(`${renderEventsCursorLine(cursor, env.flags)}
|
|
1904
1919
|
`);
|
|
1905
1920
|
}
|
|
1906
1921
|
}
|
package/dist/cli/routes/init.js
CHANGED
|
@@ -841,10 +841,10 @@ Run \`appduct init --scheme <scheme>\` with the scheme your app registers for de
|
|
|
841
841
|
nextSteps: [
|
|
842
842
|
'Add `import "@appduct/react-native/auto";` to your app entry (index.js / App.tsx) \u2014 it is what starts the in-app agent endpoint.',
|
|
843
843
|
`Add the Appduct MCP server entry to your agent's MCP config. "--scheme ${scheme}" keeps that entry self-contained; ${SCHEME_ENV_VAR} and this ${PROJECT_CONFIG_RELATIVE_PATH} work too.`,
|
|
844
|
-
"With the app running, pair a device: `appduct link --open ios-sim` (or `--open android`).",
|
|
844
|
+
"With the app running, pair a device: `appduct sessions link --open ios-sim` (or `--open android`).",
|
|
845
845
|
...origin === void 0 ? [] : [`Scheme "${scheme}" was read from ${origin}.`],
|
|
846
846
|
...iosAppId === void 0 && androidAppId === void 0 ? [
|
|
847
|
-
"Delivering to a physical iPhone (`--open ios-device`) or an Android device/emulator (`--open android`) needs the installed app's id: run `appduct init --ios-app-id <id> --android-app-id <id>`, or pass --app-id on `appduct link`."
|
|
847
|
+
"Delivering to a physical iPhone (`--open ios-device`) or an Android device/emulator (`--open android`) needs the installed app's id: run `appduct init --ios-app-id <id> --android-app-id <id>`, or pass --app-id on `appduct sessions link`."
|
|
848
848
|
] : [],
|
|
849
849
|
`This file is safe to commit \u2014 it holds only "scheme" and "appId". Do not point --state-dir at this directory: the state dir holds the daemon's private key and audit log, which must never be committed.`
|
|
850
850
|
]
|
|
@@ -978,9 +978,6 @@ var renderLsData = (colors, data, now) => {
|
|
|
978
978
|
...rows.map((row) => ` ${row.map((cell, index) => cell.padEnd(widths[index])).join(" ")}`)
|
|
979
979
|
];
|
|
980
980
|
};
|
|
981
|
-
var isToolsListing = (data) => {
|
|
982
|
-
return typeof data === "object" && data !== null && Array.isArray(data.tools);
|
|
983
|
-
};
|
|
984
981
|
var isToolGroupsListing = (data) => {
|
|
985
982
|
return typeof data === "object" && data !== null && Array.isArray(data.groups) && !Array.isArray(data.tools);
|
|
986
983
|
};
|
|
@@ -998,7 +995,7 @@ var renderEmptyToolsLine = (data) => {
|
|
|
998
995
|
}
|
|
999
996
|
if (data.group !== void 0) {
|
|
1000
997
|
const match = data.filter === void 0 ? "" : ` match ${JSON.stringify(data.filter)}`;
|
|
1001
|
-
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools --groups\` to see the session's groups.`;
|
|
998
|
+
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools ls --groups\` to see the session's groups.`;
|
|
1002
999
|
}
|
|
1003
1000
|
return data.filter === void 0 ? " No tools registered." : ` No tools match ${JSON.stringify(data.filter)}.`;
|
|
1004
1001
|
};
|
|
@@ -1080,7 +1077,7 @@ var renderToolSummaryTable = (colors, data) => {
|
|
|
1080
1077
|
...grouped ? renderGroupedToolLines(colors, data.tools) : data.tools.flatMap((tool) => renderToolSummaryLines(tool, " ")),
|
|
1081
1078
|
...renderTruncationLine(data),
|
|
1082
1079
|
"",
|
|
1083
|
-
"Run `appduct tools <name>` for a tool's full schema."
|
|
1080
|
+
"Run `appduct tools describe <name>` for a tool's full schema."
|
|
1084
1081
|
];
|
|
1085
1082
|
};
|
|
1086
1083
|
var renderToolDetail = (colors, tool, flags) => {
|
|
@@ -1132,16 +1129,13 @@ var renderToolGroups = (colors, data) => {
|
|
|
1132
1129
|
colors.green("Groups"),
|
|
1133
1130
|
...data.groups.map((entry) => ` ${label(entry).padEnd(width)} ${String(entry.total).padStart(countWidth)}`),
|
|
1134
1131
|
"",
|
|
1135
|
-
`${data.total} tool${data.total === 1 ? "" : "s"} in total. ` + (hasAnyGroup(data.groups) ? "Run `appduct tools --group <name>` to list one group's tools." : "No tool declares a group.")
|
|
1132
|
+
`${data.total} tool${data.total === 1 ? "" : "s"} in total. ` + (hasAnyGroup(data.groups) ? "Run `appduct tools ls --group <name>` to list one group's tools." : "No tool declares a group.")
|
|
1136
1133
|
];
|
|
1137
1134
|
};
|
|
1138
|
-
var
|
|
1135
|
+
var renderToolsListData = (colors, data, flags, full) => {
|
|
1139
1136
|
if (isToolGroupsListing(data)) {
|
|
1140
1137
|
return renderToolGroups(colors, data);
|
|
1141
1138
|
}
|
|
1142
|
-
if (!isToolsListing(data)) {
|
|
1143
|
-
return renderToolDetail(colors, data, flags);
|
|
1144
|
-
}
|
|
1145
1139
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
1146
1140
|
};
|
|
1147
1141
|
var renderInvokeData = (colors, data, flags) => {
|
|
@@ -1327,15 +1321,17 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
1327
1321
|
return renderInitData(colors, data, flags);
|
|
1328
1322
|
case "keygen":
|
|
1329
1323
|
return renderKeygenData(colors, data, flags);
|
|
1330
|
-
case "link":
|
|
1324
|
+
case "sessions link":
|
|
1331
1325
|
return renderLinkData(colors, data, flags, options.qr);
|
|
1332
|
-
case "ls":
|
|
1326
|
+
case "sessions ls":
|
|
1333
1327
|
return renderLsData(colors, data, options.now ?? /* @__PURE__ */ new Date());
|
|
1334
|
-
case "tools":
|
|
1335
|
-
return
|
|
1336
|
-
case "
|
|
1328
|
+
case "tools ls":
|
|
1329
|
+
return renderToolsListData(colors, data, flags, options.full);
|
|
1330
|
+
case "tools describe":
|
|
1331
|
+
return renderToolDetail(colors, data, flags);
|
|
1332
|
+
case "tools call":
|
|
1337
1333
|
return renderInvokeData(colors, data, flags);
|
|
1338
|
-
case "revoke":
|
|
1334
|
+
case "sessions revoke":
|
|
1339
1335
|
return renderRevokeData(colors, data);
|
|
1340
1336
|
case "daemon run":
|
|
1341
1337
|
return renderDaemonRunData(colors, data, flags);
|
|
@@ -427,9 +427,6 @@ var renderLsData = (colors, data, now) => {
|
|
|
427
427
|
...rows.map((row) => ` ${row.map((cell, index) => cell.padEnd(widths[index])).join(" ")}`)
|
|
428
428
|
];
|
|
429
429
|
};
|
|
430
|
-
var isToolsListing = (data) => {
|
|
431
|
-
return typeof data === "object" && data !== null && Array.isArray(data.tools);
|
|
432
|
-
};
|
|
433
430
|
var isToolGroupsListing = (data) => {
|
|
434
431
|
return typeof data === "object" && data !== null && Array.isArray(data.groups) && !Array.isArray(data.tools);
|
|
435
432
|
};
|
|
@@ -447,7 +444,7 @@ var renderEmptyToolsLine = (data) => {
|
|
|
447
444
|
}
|
|
448
445
|
if (data.group !== void 0) {
|
|
449
446
|
const match = data.filter === void 0 ? "" : ` match ${JSON.stringify(data.filter)}`;
|
|
450
|
-
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools --groups\` to see the session's groups.`;
|
|
447
|
+
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools ls --groups\` to see the session's groups.`;
|
|
451
448
|
}
|
|
452
449
|
return data.filter === void 0 ? " No tools registered." : ` No tools match ${JSON.stringify(data.filter)}.`;
|
|
453
450
|
};
|
|
@@ -529,7 +526,7 @@ var renderToolSummaryTable = (colors, data) => {
|
|
|
529
526
|
...grouped ? renderGroupedToolLines(colors, data.tools) : data.tools.flatMap((tool) => renderToolSummaryLines(tool, " ")),
|
|
530
527
|
...renderTruncationLine(data),
|
|
531
528
|
"",
|
|
532
|
-
"Run `appduct tools <name>` for a tool's full schema."
|
|
529
|
+
"Run `appduct tools describe <name>` for a tool's full schema."
|
|
533
530
|
];
|
|
534
531
|
};
|
|
535
532
|
var renderToolDetail = (colors, tool, flags) => {
|
|
@@ -581,16 +578,13 @@ var renderToolGroups = (colors, data) => {
|
|
|
581
578
|
colors.green("Groups"),
|
|
582
579
|
...data.groups.map((entry) => ` ${label(entry).padEnd(width)} ${String(entry.total).padStart(countWidth)}`),
|
|
583
580
|
"",
|
|
584
|
-
`${data.total} tool${data.total === 1 ? "" : "s"} in total. ` + (hasAnyGroup(data.groups) ? "Run `appduct tools --group <name>` to list one group's tools." : "No tool declares a group.")
|
|
581
|
+
`${data.total} tool${data.total === 1 ? "" : "s"} in total. ` + (hasAnyGroup(data.groups) ? "Run `appduct tools ls --group <name>` to list one group's tools." : "No tool declares a group.")
|
|
585
582
|
];
|
|
586
583
|
};
|
|
587
|
-
var
|
|
584
|
+
var renderToolsListData = (colors, data, flags, full) => {
|
|
588
585
|
if (isToolGroupsListing(data)) {
|
|
589
586
|
return renderToolGroups(colors, data);
|
|
590
587
|
}
|
|
591
|
-
if (!isToolsListing(data)) {
|
|
592
|
-
return renderToolDetail(colors, data, flags);
|
|
593
|
-
}
|
|
594
588
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
595
589
|
};
|
|
596
590
|
var renderInvokeData = (colors, data, flags) => {
|
|
@@ -776,15 +770,17 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
776
770
|
return renderInitData(colors, data, flags);
|
|
777
771
|
case "keygen":
|
|
778
772
|
return renderKeygenData(colors, data, flags);
|
|
779
|
-
case "link":
|
|
773
|
+
case "sessions link":
|
|
780
774
|
return renderLinkData(colors, data, flags, options.qr);
|
|
781
|
-
case "ls":
|
|
775
|
+
case "sessions ls":
|
|
782
776
|
return renderLsData(colors, data, options.now ?? /* @__PURE__ */ new Date());
|
|
783
|
-
case "tools":
|
|
784
|
-
return
|
|
785
|
-
case "
|
|
777
|
+
case "tools ls":
|
|
778
|
+
return renderToolsListData(colors, data, flags, options.full);
|
|
779
|
+
case "tools describe":
|
|
780
|
+
return renderToolDetail(colors, data, flags);
|
|
781
|
+
case "tools call":
|
|
786
782
|
return renderInvokeData(colors, data, flags);
|
|
787
|
-
case "revoke":
|
|
783
|
+
case "sessions revoke":
|
|
788
784
|
return renderRevokeData(colors, data);
|
|
789
785
|
case "daemon run":
|
|
790
786
|
return renderDaemonRunData(colors, data, flags);
|