appduct 0.12.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.
Files changed (75) hide show
  1. package/README.md +43 -37
  2. package/dist/bin.js +102 -37
  3. package/dist/cli/command-options.d.ts +7 -17
  4. package/dist/cli/result-types.d.ts +19 -9
  5. package/dist/cli/routes/daemon/index.js +70 -17
  6. package/dist/cli/routes/daemon/run.js +288 -50
  7. package/dist/cli/routes/daemon/start.js +70 -17
  8. package/dist/cli/routes/daemon/status.js +70 -17
  9. package/dist/cli/routes/daemon/stop.js +70 -17
  10. package/dist/cli/routes/doctor.js +70 -17
  11. package/dist/cli/routes/events/index.d.ts +6 -0
  12. package/dist/cli/routes/events/index.js +900 -0
  13. package/dist/cli/routes/events/ls.d.ts +5 -0
  14. package/dist/cli/routes/events/ls.js +1798 -0
  15. package/dist/cli/routes/events/shared-options.d.ts +12 -0
  16. package/dist/cli/routes/events/shared-options.js +102 -0
  17. package/dist/cli/routes/events/since.d.ts +6 -0
  18. package/dist/cli/routes/events/since.js +2034 -0
  19. package/dist/cli/routes/events/tail.d.ts +6 -0
  20. package/dist/cli/routes/{events.js → events/tail.js} +235 -163
  21. package/dist/cli/routes/init.js +72 -19
  22. package/dist/cli/routes/keygen.js +70 -17
  23. package/dist/cli/routes/mcp.js +289 -166
  24. package/dist/cli/routes/sessions/index.d.ts +7 -0
  25. package/dist/cli/routes/sessions/index.js +900 -0
  26. package/dist/cli/routes/sessions/link.d.ts +4 -0
  27. package/dist/cli/routes/{link.js → sessions/link.js} +71 -18
  28. package/dist/cli/routes/sessions/ls.d.ts +4 -0
  29. package/dist/cli/routes/{ls.js → sessions/ls.js} +71 -18
  30. package/dist/cli/routes/sessions/revoke.d.ts +4 -0
  31. package/dist/cli/routes/{revoke.js → sessions/revoke.js} +72 -19
  32. package/dist/cli/routes/tools/call.d.ts +4 -0
  33. package/dist/cli/routes/{invoke.js → tools/call.js} +73 -20
  34. package/dist/cli/routes/tools/describe.d.ts +6 -0
  35. package/dist/cli/routes/tools/describe.js +1894 -0
  36. package/dist/cli/routes/tools/index.d.ts +6 -0
  37. package/dist/cli/routes/tools/index.js +900 -0
  38. package/dist/cli/routes/tools/ls.d.ts +4 -0
  39. package/dist/cli/routes/{tools.js → tools/ls.js} +98 -74
  40. package/dist/cli/routes/tools/shared-options.d.ts +16 -0
  41. package/dist/cli/routes/tools/shared-options.js +122 -0
  42. package/dist/client/app-client.d.ts +96 -37
  43. package/dist/client/index.d.ts +3 -2
  44. package/dist/client/index.js +178 -138
  45. package/dist/commands/events-ls.d.ts +21 -0
  46. package/dist/commands/events.d.ts +31 -14
  47. package/dist/commands/invoke.d.ts +1 -1
  48. package/dist/commands/link.d.ts +1 -1
  49. package/dist/commands/ls.d.ts +1 -1
  50. package/dist/commands/revoke.d.ts +1 -1
  51. package/dist/commands/tools.d.ts +12 -13
  52. package/dist/daemon/calls.d.ts +3 -1
  53. package/dist/daemon/config.d.ts +1 -1
  54. package/dist/daemon/event-bus.d.ts +42 -0
  55. package/dist/daemon/registry.d.ts +20 -12
  56. package/dist/daemon/rpc-errors.d.ts +4 -1
  57. package/dist/daemon/sessions.d.ts +4 -2
  58. package/dist/errors.d.ts +1 -1
  59. package/dist/events/index.d.ts +60 -0
  60. package/dist/index.js +114 -40
  61. package/dist/link.d.ts +1 -1
  62. package/dist/mcp/app-tools.d.ts +22 -2
  63. package/dist/mcp/connect-tool.d.ts +1 -1
  64. package/dist/mcp/events-tool.d.ts +67 -27
  65. package/dist/native-scheme.d.ts +1 -1
  66. package/dist/output.d.ts +29 -6
  67. package/dist/rpc/client.d.ts +1 -1
  68. package/dist/scheme.d.ts +4 -4
  69. package/package.json +2 -2
  70. package/dist/cli/routes/events.d.ts +0 -3
  71. package/dist/cli/routes/invoke.d.ts +0 -3
  72. package/dist/cli/routes/link.d.ts +0 -3
  73. package/dist/cli/routes/ls.d.ts +0 -3
  74. package/dist/cli/routes/revoke.d.ts +0 -3
  75. package/dist/cli/routes/tools.d.ts +0 -3
@@ -1239,6 +1239,7 @@ var formatJson = (value, flags) => {
1239
1239
  import pc from "picocolors";
1240
1240
  import {
1241
1241
  formatAgentWebSocketUrl,
1242
+ renderEventSignature,
1242
1243
  renderToolSignature,
1243
1244
  summarizeToolDescription
1244
1245
  } from "@appduct/shared";
@@ -1334,6 +1335,13 @@ var formatDevice = (device) => {
1334
1335
  const label = parts.length > 0 ? parts.join(" ") : "unknown device";
1335
1336
  return device.os ? `${label} (${device.os})` : label;
1336
1337
  };
1338
+ var SUSPEND_REASON_LABELS = {
1339
+ app_backgrounded: "app in background",
1340
+ connection_lost: "connection lost"
1341
+ };
1342
+ var formatSessionState = (session) => {
1343
+ return session.suspendReason ? `${session.state} (${SUSPEND_REASON_LABELS[session.suspendReason]})` : session.state;
1344
+ };
1337
1345
  var renderLsData = (colors, data, now) => {
1338
1346
  if (data.length === 0) {
1339
1347
  return [colors.dim("Sessions"), " No Appduct sessions are registered."];
@@ -1342,7 +1350,7 @@ var renderLsData = (colors, data, now) => {
1342
1350
  const headers = ["Alias", "State", "Device", "Tools", "Age"];
1343
1351
  const rows = data.map((session) => [
1344
1352
  session.alias,
1345
- session.state,
1353
+ formatSessionState(session),
1346
1354
  formatDevice(session.device),
1347
1355
  String(session.toolCount),
1348
1356
  formatAge(session.claimedAt ?? session.createdAt, nowIso)
@@ -1356,9 +1364,6 @@ var renderLsData = (colors, data, now) => {
1356
1364
  ...rows.map((row) => ` ${row.map((cell, index) => cell.padEnd(widths[index])).join(" ")}`)
1357
1365
  ];
1358
1366
  };
1359
- var isToolsListing = (data) => {
1360
- return typeof data === "object" && data !== null && Array.isArray(data.tools);
1361
- };
1362
1367
  var isToolGroupsListing = (data) => {
1363
1368
  return typeof data === "object" && data !== null && Array.isArray(data.groups) && !Array.isArray(data.tools);
1364
1369
  };
@@ -1376,7 +1381,7 @@ var renderEmptyToolsLine = (data) => {
1376
1381
  }
1377
1382
  if (data.group !== void 0) {
1378
1383
  const match = data.filter === void 0 ? "" : ` match ${JSON.stringify(data.filter)}`;
1379
- return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools --groups\` to see the session's groups.`;
1384
+ return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools ls --groups\` to see the session's groups.`;
1380
1385
  }
1381
1386
  return data.filter === void 0 ? " No tools registered." : ` No tools match ${JSON.stringify(data.filter)}.`;
1382
1387
  };
@@ -1458,7 +1463,7 @@ var renderToolSummaryTable = (colors, data) => {
1458
1463
  ...grouped ? renderGroupedToolLines(colors, data.tools) : data.tools.flatMap((tool) => renderToolSummaryLines(tool, " ")),
1459
1464
  ...renderTruncationLine(data),
1460
1465
  "",
1461
- "Run `appduct tools <name>` for a tool's full schema."
1466
+ "Run `appduct tools describe <name>` for a tool's full schema."
1462
1467
  ];
1463
1468
  };
1464
1469
  var renderToolDetail = (colors, tool, flags) => {
@@ -1510,18 +1515,62 @@ var renderToolGroups = (colors, data) => {
1510
1515
  colors.green("Groups"),
1511
1516
  ...data.groups.map((entry) => ` ${label(entry).padEnd(width)} ${String(entry.total).padStart(countWidth)}`),
1512
1517
  "",
1513
- `${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.")
1518
+ `${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.")
1514
1519
  ];
1515
1520
  };
1516
- var renderToolsData = (colors, data, flags, full) => {
1521
+ var renderToolsListData = (colors, data, flags, full) => {
1517
1522
  if (isToolGroupsListing(data)) {
1518
1523
  return renderToolGroups(colors, data);
1519
1524
  }
1520
- if (!isToolsListing(data)) {
1521
- return renderToolDetail(colors, data, flags);
1522
- }
1523
1525
  return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
1524
1526
  };
1527
+ var renderEventsTruncationLine = (data) => {
1528
+ const offset = data.offset ?? 0;
1529
+ if (data.events.length >= data.total) {
1530
+ return [];
1531
+ }
1532
+ return [
1533
+ "",
1534
+ `Showing ${data.events.length} of ${data.total} events (offset ${offset}). Narrow with --name <glob> or page with --offset <n>.`
1535
+ ];
1536
+ };
1537
+ var renderEventsListData = (colors, data, flags) => {
1538
+ const [only] = data.events;
1539
+ if (data.name !== void 0 && !data.name.includes("*") && only !== void 0) {
1540
+ return renderFields(
1541
+ colors.green(`Event: ${only.name}`),
1542
+ [
1543
+ ["Signature", renderEventSignature(only)],
1544
+ ["Description", only.description],
1545
+ ["Payload schema", only.payload_schema]
1546
+ ],
1547
+ flags
1548
+ );
1549
+ }
1550
+ if (data.events.length === 0 && data.total > 0) {
1551
+ return [
1552
+ colors.green("Events"),
1553
+ ` No events at offset ${data.offset ?? 0}; ${data.total} matching event${data.total === 1 ? "" : "s"} in total.`
1554
+ ];
1555
+ }
1556
+ if (data.events.length === 0) {
1557
+ return [
1558
+ colors.green("Events"),
1559
+ data.name === void 0 ? " No events declared." : ` No events match ${JSON.stringify(data.name)}.`
1560
+ ];
1561
+ }
1562
+ const lines = data.events.flatMap((event) => [
1563
+ ` ${renderEventSignature(event)}`,
1564
+ ` ${summarizeToolDescription(event.description)}`
1565
+ ]);
1566
+ return [
1567
+ colors.green("Events"),
1568
+ ...lines,
1569
+ ...renderEventsTruncationLine(data),
1570
+ "",
1571
+ "Run `appduct events ls --name <name>` for an event's full payload schema."
1572
+ ];
1573
+ };
1525
1574
  var renderInvokeData = (colors, data, flags) => {
1526
1575
  return [colors.green("Result"), formatScalar(data, flags)];
1527
1576
  };
@@ -1705,15 +1754,19 @@ var renderSuccessData = (colors, command, data, options) => {
1705
1754
  return renderInitData(colors, data, flags);
1706
1755
  case "keygen":
1707
1756
  return renderKeygenData(colors, data, flags);
1708
- case "link":
1757
+ case "sessions link":
1709
1758
  return renderLinkData(colors, data, flags, options.qr);
1710
- case "ls":
1759
+ case "sessions ls":
1711
1760
  return renderLsData(colors, data, options.now ?? /* @__PURE__ */ new Date());
1712
- case "tools":
1713
- return renderToolsData(colors, data, flags, options.full);
1714
- case "invoke":
1761
+ case "tools ls":
1762
+ return renderToolsListData(colors, data, flags, options.full);
1763
+ case "tools describe":
1764
+ return renderToolDetail(colors, data, flags);
1765
+ case "events ls":
1766
+ return renderEventsListData(colors, data, flags);
1767
+ case "tools call":
1715
1768
  return renderInvokeData(colors, data, flags);
1716
- case "revoke":
1769
+ case "sessions revoke":
1717
1770
  return renderRevokeData(colors, data);
1718
1771
  case "daemon run":
1719
1772
  return renderDaemonRunData(colors, data, flags);
@@ -1859,7 +1912,7 @@ var guarded = (context) => {
1859
1912
  };
1860
1913
  };
1861
1914
 
1862
- // src/cli/routes/invoke.ts
1915
+ // src/cli/routes/tools/call.ts
1863
1916
  var route = async (context) => {
1864
1917
  const { options, stateDir } = context;
1865
1918
  const cancelController = new AbortController();
@@ -1868,12 +1921,12 @@ var route = async (context) => {
1868
1921
  try {
1869
1922
  return await executeCommand(
1870
1923
  commandName(context),
1871
- // Positionals are split inside the handler so a missing `<tool>` renders through the runner
1924
+ // Positionals are split inside the handler so a missing `<name>` renders through the runner
1872
1925
  // as a usage error instead of escaping the route as an uncaught rejection.
1873
1926
  () => {
1874
1927
  const { selector, target: tool } = splitSelectorAndRequiredTarget(
1875
1928
  context.args,
1876
- "invoke [selector] <tool> --input '<json>'"
1929
+ "tools call [selector] <name> --input '<json>'"
1877
1930
  );
1878
1931
  return guarded(context)(
1879
1932
  () => handleInvokeCommand(
@@ -0,0 +1,6 @@
1
+ /** Route for `appduct tools describe` — loaded by `routes/tools/index.ts`'s router only when it
2
+ * runs (issue #96; replaces the removed `appduct tools <name>` / `appduct tools [selector] <name>`
3
+ * detail form). Unlike the old single-positional form, `<name>` is never ambiguous with a
4
+ * selector: `splitSelectorAndRequiredTarget` always takes the last positional as the name. */
5
+ import type { Route } from "../../router.js";
6
+ export declare const route: Route;