appduct 0.11.1 → 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 +43 -38
- package/dist/bin.js +50 -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 +216 -46
- package/dist/cli/routes/daemon/start.js +18 -16
- package/dist/cli/routes/daemon/status.js +18 -16
- package/dist/cli/routes/daemon/stop.js +18 -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} +184 -162
- package/dist/cli/routes/init.js +14 -18
- package/dist/cli/routes/keygen.js +13 -16
- package/dist/cli/routes/mcp.js +193 -175
- 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} +19 -17
- package/dist/cli/routes/sessions/ls.d.ts +4 -0
- package/dist/cli/routes/{ls.js → sessions/ls.js} +19 -17
- package/dist/cli/routes/sessions/revoke.d.ts +4 -0
- package/dist/cli/routes/{revoke.js → sessions/revoke.js} +20 -18
- package/dist/cli/routes/tools/call.d.ts +4 -0
- package/dist/cli/routes/{invoke.js → tools/call.js} +21 -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} +46 -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 +183 -139
- package/dist/commands/events.d.ts +31 -13
- 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 +5 -2
- package/dist/daemon/daemon.d.ts +3 -0
- package/dist/daemon/event-bus.d.ts +36 -4
- package/dist/daemon/events-log.d.ts +31 -0
- package/dist/daemon/memory-append-only-file.d.ts +17 -0
- package/dist/daemon/node-append-only-file.d.ts +9 -0
- package/dist/daemon/rpc-errors.d.ts +1 -1
- package/dist/daemon/state-dir.d.ts +2 -0
- package/dist/errors.d.ts +1 -1
- package/dist/events/index.d.ts +60 -0
- package/dist/index.js +62 -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 -34
- 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
|
@@ -139,6 +139,7 @@ var KNOWN_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
139
139
|
"eventBufferSize",
|
|
140
140
|
"auditRetentionDays",
|
|
141
141
|
"daemonLogMaxBytes",
|
|
142
|
+
"eventsLogMaxBytes",
|
|
142
143
|
"policy",
|
|
143
144
|
"advertisedIp",
|
|
144
145
|
"scheme",
|
|
@@ -198,6 +199,7 @@ var defaultConfig = (paths) => {
|
|
|
198
199
|
eventBufferSize: 256,
|
|
199
200
|
auditRetentionDays: DEFAULT_AUDIT_RETENTION_DAYS,
|
|
200
201
|
daemonLogMaxBytes: DEFAULT_DAEMON_LOG_MAX_BYTES,
|
|
202
|
+
eventsLogMaxBytes: 10 * 1024 * 1024,
|
|
201
203
|
restartDaemonOnVersionMismatch: false,
|
|
202
204
|
policy: {
|
|
203
205
|
default: "allow",
|
|
@@ -260,6 +262,9 @@ var loadConfig = async (paths, options = {}) => {
|
|
|
260
262
|
if (parsed.daemonLogMaxBytes !== void 0) {
|
|
261
263
|
config.daemonLogMaxBytes = requirePositiveInteger(parsed.daemonLogMaxBytes, "daemonLogMaxBytes");
|
|
262
264
|
}
|
|
265
|
+
if (parsed.eventsLogMaxBytes !== void 0) {
|
|
266
|
+
config.eventsLogMaxBytes = requirePositiveInteger(parsed.eventsLogMaxBytes, "eventsLogMaxBytes");
|
|
267
|
+
}
|
|
263
268
|
if (parsed.restartDaemonOnVersionMismatch !== void 0) {
|
|
264
269
|
config.restartDaemonOnVersionMismatch = requireBoolean(
|
|
265
270
|
parsed.restartDaemonOnVersionMismatch,
|
|
@@ -609,7 +614,71 @@ var createCallsManager = (options) => {
|
|
|
609
614
|
|
|
610
615
|
// src/daemon/event-bus.ts
|
|
611
616
|
var TERMINAL_EVENT_KINDS = /* @__PURE__ */ new Set(["session_expired", "session_revoked"]);
|
|
612
|
-
var
|
|
617
|
+
var utf8ByteLength = (text) => Buffer.byteLength(text, "utf8");
|
|
618
|
+
var truncateToUtf8Bytes = (text, maxBytes) => {
|
|
619
|
+
const encoded = Buffer.from(text, "utf8");
|
|
620
|
+
if (encoded.length <= maxBytes) {
|
|
621
|
+
return text;
|
|
622
|
+
}
|
|
623
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
624
|
+
for (let end = maxBytes; end > 0; end--) {
|
|
625
|
+
try {
|
|
626
|
+
return decoder.decode(encoded.subarray(0, end));
|
|
627
|
+
} catch {
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return "";
|
|
631
|
+
};
|
|
632
|
+
var matchesNameGlob = (pattern, name) => {
|
|
633
|
+
const pieces = pattern.split("*");
|
|
634
|
+
const first = pieces[0] ?? "";
|
|
635
|
+
if (pieces.length === 1) {
|
|
636
|
+
return name === first;
|
|
637
|
+
}
|
|
638
|
+
const last = pieces[pieces.length - 1] ?? "";
|
|
639
|
+
if (first.length + last.length > name.length || !name.startsWith(first) || !name.endsWith(last)) {
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
const end = name.length - last.length;
|
|
643
|
+
let position = first.length;
|
|
644
|
+
for (const piece of pieces.slice(1, -1)) {
|
|
645
|
+
const found = name.indexOf(piece, position);
|
|
646
|
+
if (found === -1 || found + piece.length > end) {
|
|
647
|
+
return false;
|
|
648
|
+
}
|
|
649
|
+
position = found + piece.length;
|
|
650
|
+
}
|
|
651
|
+
return true;
|
|
652
|
+
};
|
|
653
|
+
var projectAppEvent = (event, options = {}) => {
|
|
654
|
+
if (event.kind !== "app_event") {
|
|
655
|
+
return event;
|
|
656
|
+
}
|
|
657
|
+
const data = event.data;
|
|
658
|
+
if (options.name !== void 0 && !(typeof data.name === "string" && matchesNameGlob(options.name, data.name))) {
|
|
659
|
+
return void 0;
|
|
660
|
+
}
|
|
661
|
+
if (options.payloadMaxBytes === void 0 || !("payload" in data)) {
|
|
662
|
+
return event;
|
|
663
|
+
}
|
|
664
|
+
const payloadJson = JSON.stringify(data.payload);
|
|
665
|
+
if (payloadJson === void 0) {
|
|
666
|
+
return event;
|
|
667
|
+
}
|
|
668
|
+
const payloadBytes = utf8ByteLength(payloadJson);
|
|
669
|
+
if (payloadBytes <= options.payloadMaxBytes) {
|
|
670
|
+
return event;
|
|
671
|
+
}
|
|
672
|
+
return {
|
|
673
|
+
...event,
|
|
674
|
+
data: {
|
|
675
|
+
name: data.name,
|
|
676
|
+
payloadPreview: truncateToUtf8Bytes(payloadJson, options.payloadMaxBytes),
|
|
677
|
+
truncated: true,
|
|
678
|
+
payloadBytes
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
};
|
|
613
682
|
var createEventBus = (options = {}) => {
|
|
614
683
|
const clock = options.clock ?? { now: () => /* @__PURE__ */ new Date() };
|
|
615
684
|
const bufferSize = options.bufferSize ?? 256;
|
|
@@ -627,8 +696,9 @@ var createEventBus = (options = {}) => {
|
|
|
627
696
|
return {
|
|
628
697
|
emit: (event) => {
|
|
629
698
|
const sessionId = event.sessionId;
|
|
630
|
-
|
|
631
|
-
if (sessionId !== void 0) {
|
|
699
|
+
let seq = 0;
|
|
700
|
+
if (sessionId !== void 0 && event.kind === "app_event") {
|
|
701
|
+
seq = (cursors.get(sessionId) ?? 0) + 1;
|
|
632
702
|
cursors.set(sessionId, seq);
|
|
633
703
|
}
|
|
634
704
|
const notification = {
|
|
@@ -640,7 +710,7 @@ var createEventBus = (options = {}) => {
|
|
|
640
710
|
if (TERMINAL_EVENT_KINDS.has(notification.kind)) {
|
|
641
711
|
buffers.delete(sessionId);
|
|
642
712
|
cursors.delete(sessionId);
|
|
643
|
-
} else if (
|
|
713
|
+
} else if (notification.kind === "app_event") {
|
|
644
714
|
appendToBuffer(sessionId, notification);
|
|
645
715
|
}
|
|
646
716
|
}
|
|
@@ -660,19 +730,26 @@ var createEventBus = (options = {}) => {
|
|
|
660
730
|
since: (sessionId, query = {}) => {
|
|
661
731
|
const buffer = buffers.get(sessionId) ?? [];
|
|
662
732
|
const sessionCursor = cursors.get(sessionId) ?? 0;
|
|
663
|
-
|
|
733
|
+
const sinceValue = query.since ?? 0;
|
|
734
|
+
const oldestRetainedSeq = buffer.length > 0 ? buffer[0].seq : void 0;
|
|
735
|
+
const dropped = oldestRetainedSeq !== void 0 ? Math.max(0, oldestRetainedSeq - sinceValue - 1) : 0;
|
|
736
|
+
let matching = buffer.slice();
|
|
664
737
|
if (query.since !== void 0) {
|
|
665
|
-
|
|
738
|
+
matching = matching.filter((event) => event.seq > query.since);
|
|
666
739
|
}
|
|
667
|
-
if (query.
|
|
668
|
-
|
|
669
|
-
events = events.filter((event) => kinds.has(event.kind));
|
|
740
|
+
if (query.name !== void 0) {
|
|
741
|
+
matching = matching.filter((event) => projectAppEvent(event, { name: query.name }) !== void 0);
|
|
670
742
|
}
|
|
743
|
+
let events = matching;
|
|
671
744
|
if (query.limit !== void 0 && events.length > query.limit) {
|
|
672
745
|
events = events.slice(0, query.limit);
|
|
673
746
|
}
|
|
747
|
+
const remaining = matching.length - events.length;
|
|
674
748
|
const cursor = events.length > 0 ? events[events.length - 1].seq : sessionCursor;
|
|
675
|
-
|
|
749
|
+
if (query.payloadMaxBytes !== void 0) {
|
|
750
|
+
events = events.map((event) => projectAppEvent(event, { payloadMaxBytes: query.payloadMaxBytes }));
|
|
751
|
+
}
|
|
752
|
+
return { events, cursor, dropped, remaining };
|
|
676
753
|
},
|
|
677
754
|
drop: (sessionId) => {
|
|
678
755
|
buffers.delete(sessionId);
|
|
@@ -681,6 +758,28 @@ var createEventBus = (options = {}) => {
|
|
|
681
758
|
};
|
|
682
759
|
};
|
|
683
760
|
|
|
761
|
+
// src/daemon/events-log.ts
|
|
762
|
+
var createEventsLog = (options) => {
|
|
763
|
+
const { file, maxBytes, warn } = options;
|
|
764
|
+
let queue = Promise.resolve();
|
|
765
|
+
return {
|
|
766
|
+
record: (event) => {
|
|
767
|
+
const line = JSON.stringify(event);
|
|
768
|
+
queue = queue.then(async () => {
|
|
769
|
+
try {
|
|
770
|
+
await file.append(line);
|
|
771
|
+
if (await file.size() > maxBytes) {
|
|
772
|
+
await file.rotate();
|
|
773
|
+
}
|
|
774
|
+
} catch (error) {
|
|
775
|
+
warn(`appduct daemon: failed to write events.log: ${error.message}`);
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
},
|
|
779
|
+
flush: () => queue
|
|
780
|
+
};
|
|
781
|
+
};
|
|
782
|
+
|
|
684
783
|
// src/daemon/listener.ts
|
|
685
784
|
import { createServer as createHttpsServer } from "node:https";
|
|
686
785
|
import { isSessionClaimMessage, isSessionResumeMessage, isSessionBoundMessage } from "@appduct/shared";
|
|
@@ -1409,6 +1508,37 @@ var acquirePidfile = async (pidFilePath, options = {}) => {
|
|
|
1409
1508
|
throw new Error(`Failed to acquire the Appduct daemon pidfile at "${pidFilePath}".`);
|
|
1410
1509
|
};
|
|
1411
1510
|
|
|
1511
|
+
// src/daemon/node-append-only-file.ts
|
|
1512
|
+
import { open as open3, rename, stat as stat2 } from "node:fs/promises";
|
|
1513
|
+
var NodeAppendOnlyFile = class {
|
|
1514
|
+
constructor(path) {
|
|
1515
|
+
this.path = path;
|
|
1516
|
+
}
|
|
1517
|
+
async append(line) {
|
|
1518
|
+
const handle = await open3(this.path, "a", 384);
|
|
1519
|
+
try {
|
|
1520
|
+
await handle.appendFile(`${line}
|
|
1521
|
+
`);
|
|
1522
|
+
await handle.chmod(384);
|
|
1523
|
+
} finally {
|
|
1524
|
+
await handle.close();
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
async size() {
|
|
1528
|
+
try {
|
|
1529
|
+
return (await stat2(this.path)).size;
|
|
1530
|
+
} catch (error) {
|
|
1531
|
+
if (error.code === "ENOENT") {
|
|
1532
|
+
return 0;
|
|
1533
|
+
}
|
|
1534
|
+
throw error;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
async rotate() {
|
|
1538
|
+
await rename(this.path, `${this.path}.1`);
|
|
1539
|
+
}
|
|
1540
|
+
};
|
|
1541
|
+
|
|
1412
1542
|
// src/daemon/rpc-server.ts
|
|
1413
1543
|
import { createServer } from "node:net";
|
|
1414
1544
|
import { chmod as chmod2, rm as rm3 } from "node:fs/promises";
|
|
@@ -1594,6 +1724,7 @@ var getStateDirPaths = (stateDir) => {
|
|
|
1594
1724
|
socketPath: join4(stateDir, "daemon.sock"),
|
|
1595
1725
|
pidFilePath: join4(stateDir, "daemon.pid"),
|
|
1596
1726
|
logFilePath: join4(stateDir, "daemon.log"),
|
|
1727
|
+
eventsLogPath: join4(stateDir, "events.log"),
|
|
1597
1728
|
keyPath: join4(stateDir, "key.pem"),
|
|
1598
1729
|
configPath: join4(stateDir, "config.json"),
|
|
1599
1730
|
auditDir: join4(stateDir, "audit"),
|
|
@@ -1612,7 +1743,7 @@ var ensureStateDir = async (stateDir) => {
|
|
|
1612
1743
|
};
|
|
1613
1744
|
|
|
1614
1745
|
// src/daemon/tls.ts
|
|
1615
|
-
import { stat as
|
|
1746
|
+
import { stat as stat3, readFile as readFile3 } from "node:fs/promises";
|
|
1616
1747
|
|
|
1617
1748
|
// src/host-certificate.ts
|
|
1618
1749
|
import "reflect-metadata";
|
|
@@ -1789,7 +1920,7 @@ var generateHostCertificate = async (keyPem, advertisedIp) => {
|
|
|
1789
1920
|
// src/key-material.ts
|
|
1790
1921
|
import { generateKeyPairSync } from "node:crypto";
|
|
1791
1922
|
import { dirname as dirname2 } from "node:path";
|
|
1792
|
-
import { mkdir as mkdir3, rename, rm as rm4, writeFile } from "node:fs/promises";
|
|
1923
|
+
import { mkdir as mkdir3, rename as rename2, rm as rm4, writeFile } from "node:fs/promises";
|
|
1793
1924
|
var generatePrivateKeyPem = () => {
|
|
1794
1925
|
const { privateKey } = generateKeyPairSync("rsa", {
|
|
1795
1926
|
modulusLength: 2048,
|
|
@@ -1809,7 +1940,7 @@ var writePrivateKeyAtomically = async (path, keyPem) => {
|
|
|
1809
1940
|
mode: 384,
|
|
1810
1941
|
flag: "wx"
|
|
1811
1942
|
});
|
|
1812
|
-
await
|
|
1943
|
+
await rename2(temporaryPath, path);
|
|
1813
1944
|
} catch (error) {
|
|
1814
1945
|
await rm4(temporaryPath, { force: true }).catch(() => {
|
|
1815
1946
|
});
|
|
@@ -1825,7 +1956,7 @@ var HostKeyError = class extends Error {
|
|
|
1825
1956
|
}
|
|
1826
1957
|
};
|
|
1827
1958
|
var loadHostKeyPem = async (keyPath) => {
|
|
1828
|
-
const fileStat = await
|
|
1959
|
+
const fileStat = await stat3(keyPath);
|
|
1829
1960
|
if ((fileStat.mode & 63) !== 0) {
|
|
1830
1961
|
throw new HostKeyError(
|
|
1831
1962
|
`Appduct host key at "${keyPath}" is group- or world-readable (mode ${(fileStat.mode & 511).toString(8)}). Refusing to load it \u2014 run "chmod 600 ${keyPath}" or re-run "appduct keygen".`
|
|
@@ -2018,7 +2149,26 @@ var asEventsSubscribeParams = (params) => {
|
|
|
2018
2149
|
}
|
|
2019
2150
|
kinds = kindsRaw;
|
|
2020
2151
|
}
|
|
2021
|
-
|
|
2152
|
+
const name = record.name;
|
|
2153
|
+
if (name !== void 0 && typeof name !== "string") {
|
|
2154
|
+
throw new RpcApplicationError("invalid_request", '"name" must be a string.');
|
|
2155
|
+
}
|
|
2156
|
+
const payloadMaxBytes = asPayloadMaxBytes(record.payloadMaxBytes);
|
|
2157
|
+
return {
|
|
2158
|
+
sessionSelector,
|
|
2159
|
+
kinds,
|
|
2160
|
+
name,
|
|
2161
|
+
payloadMaxBytes
|
|
2162
|
+
};
|
|
2163
|
+
};
|
|
2164
|
+
var asPayloadMaxBytes = (value) => {
|
|
2165
|
+
if (value === void 0) {
|
|
2166
|
+
return void 0;
|
|
2167
|
+
}
|
|
2168
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
|
|
2169
|
+
throw new RpcApplicationError("invalid_request", '"payloadMaxBytes" must be a positive integer.');
|
|
2170
|
+
}
|
|
2171
|
+
return value;
|
|
2022
2172
|
};
|
|
2023
2173
|
var asEventsSinceParams = (params) => {
|
|
2024
2174
|
const record = asRecordParams(params);
|
|
@@ -2030,23 +2180,21 @@ var asEventsSinceParams = (params) => {
|
|
|
2030
2180
|
if (since !== void 0 && (typeof since !== "number" || !Number.isInteger(since) || since < 0)) {
|
|
2031
2181
|
throw new RpcApplicationError("invalid_request", '"since" must be a non-negative integer.');
|
|
2032
2182
|
}
|
|
2033
|
-
const kindsRaw = record.kinds;
|
|
2034
|
-
let kinds;
|
|
2035
|
-
if (kindsRaw !== void 0) {
|
|
2036
|
-
if (!Array.isArray(kindsRaw) || !kindsRaw.every((kind) => typeof kind === "string" && KNOWN_EVENT_KINDS.has(kind))) {
|
|
2037
|
-
throw new RpcApplicationError("invalid_request", '"kinds" must be an array of known event kinds.');
|
|
2038
|
-
}
|
|
2039
|
-
kinds = kindsRaw;
|
|
2040
|
-
}
|
|
2041
2183
|
const limit = record.limit;
|
|
2042
2184
|
if (limit !== void 0 && (typeof limit !== "number" || !Number.isInteger(limit) || limit <= 0)) {
|
|
2043
2185
|
throw new RpcApplicationError("invalid_request", '"limit" must be a positive integer.');
|
|
2044
2186
|
}
|
|
2187
|
+
const name = record.name;
|
|
2188
|
+
if (name !== void 0 && typeof name !== "string") {
|
|
2189
|
+
throw new RpcApplicationError("invalid_request", '"name" must be a string.');
|
|
2190
|
+
}
|
|
2191
|
+
const payloadMaxBytes = asPayloadMaxBytes(record.payloadMaxBytes);
|
|
2045
2192
|
return {
|
|
2046
2193
|
selector,
|
|
2047
2194
|
since,
|
|
2048
|
-
|
|
2049
|
-
|
|
2195
|
+
limit,
|
|
2196
|
+
name,
|
|
2197
|
+
payloadMaxBytes
|
|
2050
2198
|
};
|
|
2051
2199
|
};
|
|
2052
2200
|
var asLinkCreateParams = (params) => {
|
|
@@ -2080,10 +2228,19 @@ var startDaemon = async (options) => {
|
|
|
2080
2228
|
retentionDays: config.auditRetentionDays,
|
|
2081
2229
|
warn: options.warn
|
|
2082
2230
|
});
|
|
2231
|
+
const eventsLog = createEventsLog({
|
|
2232
|
+
file: new NodeAppendOnlyFile(paths.eventsLogPath),
|
|
2233
|
+
maxBytes: config.eventsLogMaxBytes,
|
|
2234
|
+
warn: options.warn ?? ((message) => {
|
|
2235
|
+
process.stderr.write(`${message}
|
|
2236
|
+
`);
|
|
2237
|
+
})
|
|
2238
|
+
});
|
|
2083
2239
|
let auditPruneInterval;
|
|
2084
2240
|
let pidfile;
|
|
2085
2241
|
let server;
|
|
2086
2242
|
let listener;
|
|
2243
|
+
let tlsManager;
|
|
2087
2244
|
let sessionManager;
|
|
2088
2245
|
let callsManager;
|
|
2089
2246
|
let eventBus;
|
|
@@ -2110,6 +2267,7 @@ var startDaemon = async (options) => {
|
|
|
2110
2267
|
await pidfile?.release();
|
|
2111
2268
|
await rm5(getSocketPath(paths), { force: true });
|
|
2112
2269
|
await auditLogger.flush();
|
|
2270
|
+
await eventsLog.flush();
|
|
2113
2271
|
} finally {
|
|
2114
2272
|
resolveExited();
|
|
2115
2273
|
}
|
|
@@ -2122,8 +2280,14 @@ var startDaemon = async (options) => {
|
|
|
2122
2280
|
});
|
|
2123
2281
|
eventBus = createEventBus({ clock, bufferSize: config.eventBufferSize });
|
|
2124
2282
|
const activeEventBus = eventBus;
|
|
2283
|
+
activeEventBus.subscribe((event) => {
|
|
2284
|
+
if (event.kind !== "app_event") {
|
|
2285
|
+
eventsLog.record(event);
|
|
2286
|
+
}
|
|
2287
|
+
});
|
|
2125
2288
|
const detectAddress = options.detectAddress ?? (() => detectAdvertisedAddress({ override: config.advertisedIp }));
|
|
2126
2289
|
const tls = await createTlsManager({ keyPath: config.keyPath, detectAddress, warn: options.warn });
|
|
2290
|
+
tlsManager = tls;
|
|
2127
2291
|
sessionManager = createSessionManager({
|
|
2128
2292
|
graceSeconds: config.graceSeconds,
|
|
2129
2293
|
keepaliveIntervalSeconds: config.keepaliveIntervalSeconds,
|
|
@@ -2177,10 +2341,17 @@ var startDaemon = async (options) => {
|
|
|
2177
2341
|
if (subscription.kinds && !subscription.kinds.has(event.kind)) {
|
|
2178
2342
|
continue;
|
|
2179
2343
|
}
|
|
2344
|
+
const projected = projectAppEvent(event, {
|
|
2345
|
+
name: subscription.name,
|
|
2346
|
+
payloadMaxBytes: subscription.payloadMaxBytes
|
|
2347
|
+
});
|
|
2348
|
+
if (projected === void 0) {
|
|
2349
|
+
continue;
|
|
2350
|
+
}
|
|
2180
2351
|
if (subscription.sessionSelector !== void 0 && event.sessionId !== subscription.sessionSelector && event.alias !== subscription.sessionSelector) {
|
|
2181
2352
|
continue;
|
|
2182
2353
|
}
|
|
2183
|
-
server?.notify(connection,
|
|
2354
|
+
server?.notify(connection, projected);
|
|
2184
2355
|
}
|
|
2185
2356
|
});
|
|
2186
2357
|
server = await startRpcServer({
|
|
@@ -2359,17 +2530,19 @@ var startDaemon = async (options) => {
|
|
|
2359
2530
|
return { cancelled };
|
|
2360
2531
|
},
|
|
2361
2532
|
[RPC_METHODS.eventsSubscribe]: (params, context) => {
|
|
2362
|
-
const { sessionSelector, kinds } = asEventsSubscribeParams(params);
|
|
2533
|
+
const { sessionSelector, kinds, name, payloadMaxBytes } = asEventsSubscribeParams(params);
|
|
2363
2534
|
context.connection.state.eventSubscription = {
|
|
2364
2535
|
sessionSelector,
|
|
2365
|
-
kinds: kinds ? new Set(kinds) : void 0
|
|
2536
|
+
kinds: kinds ? new Set(kinds) : void 0,
|
|
2537
|
+
name,
|
|
2538
|
+
payloadMaxBytes
|
|
2366
2539
|
};
|
|
2367
2540
|
return { ok: true };
|
|
2368
2541
|
},
|
|
2369
2542
|
[RPC_METHODS.eventsSince]: (params) => {
|
|
2370
|
-
const { selector, since,
|
|
2543
|
+
const { selector, since, limit, name, payloadMaxBytes } = asEventsSinceParams(params);
|
|
2371
2544
|
const resolved = activeSessionManager.describe(selector);
|
|
2372
|
-
return activeEventBus.since(resolved.sessionId, { since,
|
|
2545
|
+
return activeEventBus.since(resolved.sessionId, { since, limit, name, payloadMaxBytes });
|
|
2373
2546
|
}
|
|
2374
2547
|
}
|
|
2375
2548
|
});
|
|
@@ -2395,6 +2568,7 @@ var startDaemon = async (options) => {
|
|
|
2395
2568
|
startedAt,
|
|
2396
2569
|
server,
|
|
2397
2570
|
listener,
|
|
2571
|
+
tls: tlsManager,
|
|
2398
2572
|
eventBus,
|
|
2399
2573
|
exited,
|
|
2400
2574
|
shutdown
|
|
@@ -2729,9 +2903,6 @@ var renderLsData = (colors, data, now) => {
|
|
|
2729
2903
|
...rows.map((row) => ` ${row.map((cell, index) => cell.padEnd(widths[index])).join(" ")}`)
|
|
2730
2904
|
];
|
|
2731
2905
|
};
|
|
2732
|
-
var isToolsListing = (data) => {
|
|
2733
|
-
return typeof data === "object" && data !== null && Array.isArray(data.tools);
|
|
2734
|
-
};
|
|
2735
2906
|
var isToolGroupsListing = (data) => {
|
|
2736
2907
|
return typeof data === "object" && data !== null && Array.isArray(data.groups) && !Array.isArray(data.tools);
|
|
2737
2908
|
};
|
|
@@ -2749,7 +2920,7 @@ var renderEmptyToolsLine = (data) => {
|
|
|
2749
2920
|
}
|
|
2750
2921
|
if (data.group !== void 0) {
|
|
2751
2922
|
const match = data.filter === void 0 ? "" : ` match ${JSON.stringify(data.filter)}`;
|
|
2752
|
-
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools --groups\` to see the session's groups.`;
|
|
2923
|
+
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools ls --groups\` to see the session's groups.`;
|
|
2753
2924
|
}
|
|
2754
2925
|
return data.filter === void 0 ? " No tools registered." : ` No tools match ${JSON.stringify(data.filter)}.`;
|
|
2755
2926
|
};
|
|
@@ -2831,7 +3002,7 @@ var renderToolSummaryTable = (colors, data) => {
|
|
|
2831
3002
|
...grouped ? renderGroupedToolLines(colors, data.tools) : data.tools.flatMap((tool) => renderToolSummaryLines(tool, " ")),
|
|
2832
3003
|
...renderTruncationLine(data),
|
|
2833
3004
|
"",
|
|
2834
|
-
"Run `appduct tools <name>` for a tool's full schema."
|
|
3005
|
+
"Run `appduct tools describe <name>` for a tool's full schema."
|
|
2835
3006
|
];
|
|
2836
3007
|
};
|
|
2837
3008
|
var renderToolDetail = (colors, tool, flags) => {
|
|
@@ -2883,16 +3054,13 @@ var renderToolGroups = (colors, data) => {
|
|
|
2883
3054
|
colors.green("Groups"),
|
|
2884
3055
|
...data.groups.map((entry) => ` ${label(entry).padEnd(width)} ${String(entry.total).padStart(countWidth)}`),
|
|
2885
3056
|
"",
|
|
2886
|
-
`${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.")
|
|
3057
|
+
`${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.")
|
|
2887
3058
|
];
|
|
2888
3059
|
};
|
|
2889
|
-
var
|
|
3060
|
+
var renderToolsListData = (colors, data, flags, full) => {
|
|
2890
3061
|
if (isToolGroupsListing(data)) {
|
|
2891
3062
|
return renderToolGroups(colors, data);
|
|
2892
3063
|
}
|
|
2893
|
-
if (!isToolsListing(data)) {
|
|
2894
|
-
return renderToolDetail(colors, data, flags);
|
|
2895
|
-
}
|
|
2896
3064
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
2897
3065
|
};
|
|
2898
3066
|
var renderInvokeData = (colors, data, flags) => {
|
|
@@ -3078,15 +3246,17 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
3078
3246
|
return renderInitData(colors, data, flags);
|
|
3079
3247
|
case "keygen":
|
|
3080
3248
|
return renderKeygenData(colors, data, flags);
|
|
3081
|
-
case "link":
|
|
3249
|
+
case "sessions link":
|
|
3082
3250
|
return renderLinkData(colors, data, flags, options.qr);
|
|
3083
|
-
case "ls":
|
|
3251
|
+
case "sessions ls":
|
|
3084
3252
|
return renderLsData(colors, data, options.now ?? /* @__PURE__ */ new Date());
|
|
3085
|
-
case "tools":
|
|
3086
|
-
return
|
|
3087
|
-
case "
|
|
3253
|
+
case "tools ls":
|
|
3254
|
+
return renderToolsListData(colors, data, flags, options.full);
|
|
3255
|
+
case "tools describe":
|
|
3256
|
+
return renderToolDetail(colors, data, flags);
|
|
3257
|
+
case "tools call":
|
|
3088
3258
|
return renderInvokeData(colors, data, flags);
|
|
3089
|
-
case "revoke":
|
|
3259
|
+
case "sessions revoke":
|
|
3090
3260
|
return renderRevokeData(colors, data);
|
|
3091
3261
|
case "daemon run":
|
|
3092
3262
|
return renderDaemonRunData(colors, data, flags);
|
|
@@ -22,6 +22,7 @@ var KNOWN_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
22
22
|
"eventBufferSize",
|
|
23
23
|
"auditRetentionDays",
|
|
24
24
|
"daemonLogMaxBytes",
|
|
25
|
+
"eventsLogMaxBytes",
|
|
25
26
|
"policy",
|
|
26
27
|
"advertisedIp",
|
|
27
28
|
"scheme",
|
|
@@ -81,6 +82,7 @@ var defaultConfig = (paths) => {
|
|
|
81
82
|
eventBufferSize: 256,
|
|
82
83
|
auditRetentionDays: DEFAULT_AUDIT_RETENTION_DAYS,
|
|
83
84
|
daemonLogMaxBytes: DEFAULT_DAEMON_LOG_MAX_BYTES,
|
|
85
|
+
eventsLogMaxBytes: 10 * 1024 * 1024,
|
|
84
86
|
restartDaemonOnVersionMismatch: false,
|
|
85
87
|
policy: {
|
|
86
88
|
default: "allow",
|
|
@@ -143,6 +145,9 @@ var loadConfig = async (paths, options = {}) => {
|
|
|
143
145
|
if (parsed.daemonLogMaxBytes !== void 0) {
|
|
144
146
|
config.daemonLogMaxBytes = requirePositiveInteger(parsed.daemonLogMaxBytes, "daemonLogMaxBytes");
|
|
145
147
|
}
|
|
148
|
+
if (parsed.eventsLogMaxBytes !== void 0) {
|
|
149
|
+
config.eventsLogMaxBytes = requirePositiveInteger(parsed.eventsLogMaxBytes, "eventsLogMaxBytes");
|
|
150
|
+
}
|
|
146
151
|
if (parsed.restartDaemonOnVersionMismatch !== void 0) {
|
|
147
152
|
config.restartDaemonOnVersionMismatch = requireBoolean(
|
|
148
153
|
parsed.restartDaemonOnVersionMismatch,
|
|
@@ -243,6 +248,7 @@ var getStateDirPaths = (stateDir) => {
|
|
|
243
248
|
socketPath: join(stateDir, "daemon.sock"),
|
|
244
249
|
pidFilePath: join(stateDir, "daemon.pid"),
|
|
245
250
|
logFilePath: join(stateDir, "daemon.log"),
|
|
251
|
+
eventsLogPath: join(stateDir, "events.log"),
|
|
246
252
|
keyPath: join(stateDir, "key.pem"),
|
|
247
253
|
configPath: join(stateDir, "config.json"),
|
|
248
254
|
auditDir: join(stateDir, "audit"),
|
|
@@ -1160,9 +1166,6 @@ var renderLsData = (colors, data, now) => {
|
|
|
1160
1166
|
...rows.map((row) => ` ${row.map((cell, index) => cell.padEnd(widths[index])).join(" ")}`)
|
|
1161
1167
|
];
|
|
1162
1168
|
};
|
|
1163
|
-
var isToolsListing = (data) => {
|
|
1164
|
-
return typeof data === "object" && data !== null && Array.isArray(data.tools);
|
|
1165
|
-
};
|
|
1166
1169
|
var isToolGroupsListing = (data) => {
|
|
1167
1170
|
return typeof data === "object" && data !== null && Array.isArray(data.groups) && !Array.isArray(data.tools);
|
|
1168
1171
|
};
|
|
@@ -1180,7 +1183,7 @@ var renderEmptyToolsLine = (data) => {
|
|
|
1180
1183
|
}
|
|
1181
1184
|
if (data.group !== void 0) {
|
|
1182
1185
|
const match = data.filter === void 0 ? "" : ` match ${JSON.stringify(data.filter)}`;
|
|
1183
|
-
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools --groups\` to see the session's groups.`;
|
|
1186
|
+
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools ls --groups\` to see the session's groups.`;
|
|
1184
1187
|
}
|
|
1185
1188
|
return data.filter === void 0 ? " No tools registered." : ` No tools match ${JSON.stringify(data.filter)}.`;
|
|
1186
1189
|
};
|
|
@@ -1262,7 +1265,7 @@ var renderToolSummaryTable = (colors, data) => {
|
|
|
1262
1265
|
...grouped ? renderGroupedToolLines(colors, data.tools) : data.tools.flatMap((tool) => renderToolSummaryLines(tool, " ")),
|
|
1263
1266
|
...renderTruncationLine(data),
|
|
1264
1267
|
"",
|
|
1265
|
-
"Run `appduct tools <name>` for a tool's full schema."
|
|
1268
|
+
"Run `appduct tools describe <name>` for a tool's full schema."
|
|
1266
1269
|
];
|
|
1267
1270
|
};
|
|
1268
1271
|
var renderToolDetail = (colors, tool, flags) => {
|
|
@@ -1314,16 +1317,13 @@ var renderToolGroups = (colors, data) => {
|
|
|
1314
1317
|
colors.green("Groups"),
|
|
1315
1318
|
...data.groups.map((entry) => ` ${label(entry).padEnd(width)} ${String(entry.total).padStart(countWidth)}`),
|
|
1316
1319
|
"",
|
|
1317
|
-
`${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.")
|
|
1320
|
+
`${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.")
|
|
1318
1321
|
];
|
|
1319
1322
|
};
|
|
1320
|
-
var
|
|
1323
|
+
var renderToolsListData = (colors, data, flags, full) => {
|
|
1321
1324
|
if (isToolGroupsListing(data)) {
|
|
1322
1325
|
return renderToolGroups(colors, data);
|
|
1323
1326
|
}
|
|
1324
|
-
if (!isToolsListing(data)) {
|
|
1325
|
-
return renderToolDetail(colors, data, flags);
|
|
1326
|
-
}
|
|
1327
1327
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
1328
1328
|
};
|
|
1329
1329
|
var renderInvokeData = (colors, data, flags) => {
|
|
@@ -1509,15 +1509,17 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
1509
1509
|
return renderInitData(colors, data, flags);
|
|
1510
1510
|
case "keygen":
|
|
1511
1511
|
return renderKeygenData(colors, data, flags);
|
|
1512
|
-
case "link":
|
|
1512
|
+
case "sessions link":
|
|
1513
1513
|
return renderLinkData(colors, data, flags, options.qr);
|
|
1514
|
-
case "ls":
|
|
1514
|
+
case "sessions ls":
|
|
1515
1515
|
return renderLsData(colors, data, options.now ?? /* @__PURE__ */ new Date());
|
|
1516
|
-
case "tools":
|
|
1517
|
-
return
|
|
1518
|
-
case "
|
|
1516
|
+
case "tools ls":
|
|
1517
|
+
return renderToolsListData(colors, data, flags, options.full);
|
|
1518
|
+
case "tools describe":
|
|
1519
|
+
return renderToolDetail(colors, data, flags);
|
|
1520
|
+
case "tools call":
|
|
1519
1521
|
return renderInvokeData(colors, data, flags);
|
|
1520
|
-
case "revoke":
|
|
1522
|
+
case "sessions revoke":
|
|
1521
1523
|
return renderRevokeData(colors, data);
|
|
1522
1524
|
case "daemon run":
|
|
1523
1525
|
return renderDaemonRunData(colors, data, flags);
|
|
@@ -66,6 +66,7 @@ var KNOWN_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
66
66
|
"eventBufferSize",
|
|
67
67
|
"auditRetentionDays",
|
|
68
68
|
"daemonLogMaxBytes",
|
|
69
|
+
"eventsLogMaxBytes",
|
|
69
70
|
"policy",
|
|
70
71
|
"advertisedIp",
|
|
71
72
|
"scheme",
|
|
@@ -125,6 +126,7 @@ var defaultConfig = (paths) => {
|
|
|
125
126
|
eventBufferSize: 256,
|
|
126
127
|
auditRetentionDays: DEFAULT_AUDIT_RETENTION_DAYS,
|
|
127
128
|
daemonLogMaxBytes: DEFAULT_DAEMON_LOG_MAX_BYTES,
|
|
129
|
+
eventsLogMaxBytes: 10 * 1024 * 1024,
|
|
128
130
|
restartDaemonOnVersionMismatch: false,
|
|
129
131
|
policy: {
|
|
130
132
|
default: "allow",
|
|
@@ -187,6 +189,9 @@ var loadConfig = async (paths, options = {}) => {
|
|
|
187
189
|
if (parsed.daemonLogMaxBytes !== void 0) {
|
|
188
190
|
config.daemonLogMaxBytes = requirePositiveInteger(parsed.daemonLogMaxBytes, "daemonLogMaxBytes");
|
|
189
191
|
}
|
|
192
|
+
if (parsed.eventsLogMaxBytes !== void 0) {
|
|
193
|
+
config.eventsLogMaxBytes = requirePositiveInteger(parsed.eventsLogMaxBytes, "eventsLogMaxBytes");
|
|
194
|
+
}
|
|
190
195
|
if (parsed.restartDaemonOnVersionMismatch !== void 0) {
|
|
191
196
|
config.restartDaemonOnVersionMismatch = requireBoolean(
|
|
192
197
|
parsed.restartDaemonOnVersionMismatch,
|
|
@@ -287,6 +292,7 @@ var getStateDirPaths = (stateDir) => {
|
|
|
287
292
|
socketPath: join3(stateDir, "daemon.sock"),
|
|
288
293
|
pidFilePath: join3(stateDir, "daemon.pid"),
|
|
289
294
|
logFilePath: join3(stateDir, "daemon.log"),
|
|
295
|
+
eventsLogPath: join3(stateDir, "events.log"),
|
|
290
296
|
keyPath: join3(stateDir, "key.pem"),
|
|
291
297
|
configPath: join3(stateDir, "config.json"),
|
|
292
298
|
auditDir: join3(stateDir, "audit"),
|
|
@@ -1189,9 +1195,6 @@ var renderLsData = (colors, data, now) => {
|
|
|
1189
1195
|
...rows.map((row) => ` ${row.map((cell, index) => cell.padEnd(widths[index])).join(" ")}`)
|
|
1190
1196
|
];
|
|
1191
1197
|
};
|
|
1192
|
-
var isToolsListing = (data) => {
|
|
1193
|
-
return typeof data === "object" && data !== null && Array.isArray(data.tools);
|
|
1194
|
-
};
|
|
1195
1198
|
var isToolGroupsListing = (data) => {
|
|
1196
1199
|
return typeof data === "object" && data !== null && Array.isArray(data.groups) && !Array.isArray(data.tools);
|
|
1197
1200
|
};
|
|
@@ -1209,7 +1212,7 @@ var renderEmptyToolsLine = (data) => {
|
|
|
1209
1212
|
}
|
|
1210
1213
|
if (data.group !== void 0) {
|
|
1211
1214
|
const match = data.filter === void 0 ? "" : ` match ${JSON.stringify(data.filter)}`;
|
|
1212
|
-
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools --groups\` to see the session's groups.`;
|
|
1215
|
+
return ` No tools in group ${JSON.stringify(data.group)}${match}. Run \`appduct tools ls --groups\` to see the session's groups.`;
|
|
1213
1216
|
}
|
|
1214
1217
|
return data.filter === void 0 ? " No tools registered." : ` No tools match ${JSON.stringify(data.filter)}.`;
|
|
1215
1218
|
};
|
|
@@ -1291,7 +1294,7 @@ var renderToolSummaryTable = (colors, data) => {
|
|
|
1291
1294
|
...grouped ? renderGroupedToolLines(colors, data.tools) : data.tools.flatMap((tool) => renderToolSummaryLines(tool, " ")),
|
|
1292
1295
|
...renderTruncationLine(data),
|
|
1293
1296
|
"",
|
|
1294
|
-
"Run `appduct tools <name>` for a tool's full schema."
|
|
1297
|
+
"Run `appduct tools describe <name>` for a tool's full schema."
|
|
1295
1298
|
];
|
|
1296
1299
|
};
|
|
1297
1300
|
var renderToolDetail = (colors, tool, flags) => {
|
|
@@ -1343,16 +1346,13 @@ var renderToolGroups = (colors, data) => {
|
|
|
1343
1346
|
colors.green("Groups"),
|
|
1344
1347
|
...data.groups.map((entry) => ` ${label(entry).padEnd(width)} ${String(entry.total).padStart(countWidth)}`),
|
|
1345
1348
|
"",
|
|
1346
|
-
`${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.")
|
|
1349
|
+
`${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.")
|
|
1347
1350
|
];
|
|
1348
1351
|
};
|
|
1349
|
-
var
|
|
1352
|
+
var renderToolsListData = (colors, data, flags, full) => {
|
|
1350
1353
|
if (isToolGroupsListing(data)) {
|
|
1351
1354
|
return renderToolGroups(colors, data);
|
|
1352
1355
|
}
|
|
1353
|
-
if (!isToolsListing(data)) {
|
|
1354
|
-
return renderToolDetail(colors, data, flags);
|
|
1355
|
-
}
|
|
1356
1356
|
return full ? renderToolsFullListing(colors, data, flags) : renderToolSummaryTable(colors, data);
|
|
1357
1357
|
};
|
|
1358
1358
|
var renderInvokeData = (colors, data, flags) => {
|
|
@@ -1538,15 +1538,17 @@ var renderSuccessData = (colors, command, data, options) => {
|
|
|
1538
1538
|
return renderInitData(colors, data, flags);
|
|
1539
1539
|
case "keygen":
|
|
1540
1540
|
return renderKeygenData(colors, data, flags);
|
|
1541
|
-
case "link":
|
|
1541
|
+
case "sessions link":
|
|
1542
1542
|
return renderLinkData(colors, data, flags, options.qr);
|
|
1543
|
-
case "ls":
|
|
1543
|
+
case "sessions ls":
|
|
1544
1544
|
return renderLsData(colors, data, options.now ?? /* @__PURE__ */ new Date());
|
|
1545
|
-
case "tools":
|
|
1546
|
-
return
|
|
1547
|
-
case "
|
|
1545
|
+
case "tools ls":
|
|
1546
|
+
return renderToolsListData(colors, data, flags, options.full);
|
|
1547
|
+
case "tools describe":
|
|
1548
|
+
return renderToolDetail(colors, data, flags);
|
|
1549
|
+
case "tools call":
|
|
1548
1550
|
return renderInvokeData(colors, data, flags);
|
|
1549
|
-
case "revoke":
|
|
1551
|
+
case "sessions revoke":
|
|
1550
1552
|
return renderRevokeData(colors, data);
|
|
1551
1553
|
case "daemon run":
|
|
1552
1554
|
return renderDaemonRunData(colors, data, flags);
|