@scotthuang/agent-knock-knock 0.13.3 → 0.13.5
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/CHANGELOG.md +25 -0
- package/README.md +13 -5
- package/dist/src/callback-outbox-policy.js +27 -6
- package/dist/src/callback-outbox-policy.js.map +1 -1
- package/dist/src/callback-outbox-service.d.ts +4 -30
- package/dist/src/callback-outbox-service.js +21 -154
- package/dist/src/callback-outbox-service.js.map +1 -1
- package/dist/src/callback-outbox-settlement.js +13 -8
- package/dist/src/callback-outbox-settlement.js.map +1 -1
- package/dist/src/callback-route-service.d.ts +46 -0
- package/dist/src/callback-route-service.js +155 -0
- package/dist/src/callback-route-service.js.map +1 -0
- package/dist/src/codex-process-incarnation.d.ts +8 -0
- package/dist/src/codex-process-incarnation.js +36 -0
- package/dist/src/codex-process-incarnation.js.map +1 -0
- package/dist/src/codex-terminal-agent-adapter.d.ts +1 -1
- package/dist/src/codex-terminal-agent-adapter.js +56 -4
- package/dist/src/codex-terminal-agent-adapter.js.map +1 -1
- package/dist/src/deferred-foreground-conflict-policy.d.ts +22 -0
- package/dist/src/deferred-foreground-conflict-policy.js +52 -0
- package/dist/src/deferred-foreground-conflict-policy.js.map +1 -0
- package/dist/src/durable-notification-kernel.d.ts +94 -0
- package/dist/src/durable-notification-kernel.js +68 -0
- package/dist/src/durable-notification-kernel.js.map +1 -0
- package/dist/src/herdr-socket-transport.d.ts +43 -0
- package/dist/src/herdr-socket-transport.js +170 -0
- package/dist/src/herdr-socket-transport.js.map +1 -0
- package/dist/src/herdr-terminal-control-provider.d.ts +2 -45
- package/dist/src/herdr-terminal-control-provider.js +2 -172
- package/dist/src/herdr-terminal-control-provider.js.map +1 -1
- package/dist/src/host-adapter-capabilities.d.ts +35 -0
- package/dist/src/host-adapter-capabilities.js +146 -0
- package/dist/src/host-adapter-capabilities.js.map +1 -0
- package/dist/src/host-adapter.d.ts +9 -3
- package/dist/src/host-adapter.js +33 -9
- package/dist/src/host-adapter.js.map +1 -1
- package/dist/src/host-bridge-tools.d.ts +3 -4
- package/dist/src/host-bridge-tools.js +49 -92
- package/dist/src/host-bridge-tools.js.map +1 -1
- package/dist/src/host-bridge.js +5 -5
- package/dist/src/host-bridge.js.map +1 -1
- package/dist/src/host-monitor-reconciliation.d.ts +6 -0
- package/dist/src/host-monitor-reconciliation.js +96 -0
- package/dist/src/host-monitor-reconciliation.js.map +1 -0
- package/dist/src/native-thread-lifecycle-cli-adapter.js +116 -60
- package/dist/src/native-thread-lifecycle-cli-adapter.js.map +1 -1
- package/dist/src/openclaw-list-projection.d.ts +2 -0
- package/dist/src/openclaw-list-projection.js +3 -0
- package/dist/src/openclaw-list-projection.js.map +1 -0
- package/dist/src/openclaw-model-facing-field-policy.d.ts +2 -0
- package/dist/src/openclaw-model-facing-field-policy.js +3 -0
- package/dist/src/openclaw-model-facing-field-policy.js.map +1 -0
- package/dist/src/openclaw-plugin-command-adapter.d.ts +6 -29
- package/dist/src/openclaw-plugin-command-adapter.js +7 -2660
- package/dist/src/openclaw-plugin-command-adapter.js.map +1 -1
- package/dist/src/openclaw-plugin-helpers.d.ts +2 -148
- package/dist/src/openclaw-plugin-helpers.js +2 -1844
- package/dist/src/openclaw-plugin-helpers.js.map +1 -1
- package/dist/src/openclaw-plugin-schemas.d.ts +2 -563
- package/dist/src/openclaw-plugin-schemas.js +2 -572
- package/dist/src/openclaw-plugin-schemas.js.map +1 -1
- package/dist/src/openclaw-plugin-supervisor.d.ts +4 -5
- package/dist/src/openclaw-plugin-supervisor.js +5 -94
- package/dist/src/openclaw-plugin-supervisor.js.map +1 -1
- package/dist/src/openclaw-plugin-value-helpers.d.ts +2 -0
- package/dist/src/openclaw-plugin-value-helpers.js +3 -0
- package/dist/src/openclaw-plugin-value-helpers.js.map +1 -0
- package/dist/src/openclaw-private-authority-offers.d.ts +4 -39
- package/dist/src/openclaw-private-authority-offers.js +3 -258
- package/dist/src/openclaw-private-authority-offers.js.map +1 -1
- package/dist/src/semantic-private-authority-offers.d.ts +41 -0
- package/dist/src/semantic-private-authority-offers.js +261 -0
- package/dist/src/semantic-private-authority-offers.js.map +1 -0
- package/dist/src/semantic-tool-arguments.d.ts +9 -0
- package/dist/src/semantic-tool-arguments.js +64 -0
- package/dist/src/semantic-tool-arguments.js.map +1 -0
- package/dist/src/semantic-tool-catalog.d.ts +48 -0
- package/dist/src/semantic-tool-catalog.js +105 -0
- package/dist/src/semantic-tool-catalog.js.map +1 -0
- package/dist/src/semantic-tool-command-helpers.d.ts +145 -0
- package/dist/src/semantic-tool-command-helpers.js +1272 -0
- package/dist/src/semantic-tool-command-helpers.js.map +1 -0
- package/dist/src/semantic-tool-list-projection.d.ts +10 -0
- package/dist/src/semantic-tool-list-projection.js +497 -0
- package/dist/src/semantic-tool-list-projection.js.map +1 -0
- package/dist/src/semantic-tool-model-facing-field-policy.d.ts +3 -0
- package/dist/src/semantic-tool-model-facing-field-policy.js +66 -0
- package/dist/src/semantic-tool-model-facing-field-policy.js.map +1 -0
- package/dist/src/semantic-tool-presentation.d.ts +37 -0
- package/dist/src/semantic-tool-presentation.js +680 -0
- package/dist/src/semantic-tool-presentation.js.map +1 -0
- package/dist/src/semantic-tool-private-authority.d.ts +39 -0
- package/dist/src/semantic-tool-private-authority.js +602 -0
- package/dist/src/semantic-tool-private-authority.js.map +1 -0
- package/dist/src/semantic-tool-relay.d.ts +16 -0
- package/dist/src/semantic-tool-relay.js +175 -0
- package/dist/src/semantic-tool-relay.js.map +1 -0
- package/dist/src/semantic-tool-runtime.d.ts +10 -0
- package/dist/src/semantic-tool-runtime.js +1157 -0
- package/dist/src/semantic-tool-runtime.js.map +1 -0
- package/dist/src/semantic-tool-schemas.d.ts +563 -0
- package/dist/src/semantic-tool-schemas.js +573 -0
- package/dist/src/semantic-tool-schemas.js.map +1 -0
- package/dist/src/semantic-tool-value-helpers.d.ts +5 -0
- package/dist/src/semantic-tool-value-helpers.js +27 -0
- package/dist/src/semantic-tool-value-helpers.js.map +1 -0
- package/dist/src/store-event-presentation.d.ts +17 -0
- package/dist/src/store-event-presentation.js +33 -0
- package/dist/src/store-event-presentation.js.map +1 -0
- package/dist/src/store.d.ts +3 -16
- package/dist/src/store.js +2 -30
- package/dist/src/store.js.map +1 -1
- package/dist/src/terminal-action-projection.d.ts +2 -98
- package/dist/src/terminal-action-projection.js +13 -215
- package/dist/src/terminal-action-projection.js.map +1 -1
- package/dist/src/terminal-agent-bridge.d.ts +14 -340
- package/dist/src/terminal-agent-bridge.js +155 -3226
- package/dist/src/terminal-agent-bridge.js.map +1 -1
- package/dist/src/terminal-approval-cli-adapter.d.ts +17 -0
- package/dist/src/terminal-approval-cli-adapter.js +921 -0
- package/dist/src/terminal-approval-cli-adapter.js.map +1 -0
- package/dist/src/terminal-command-cli-adapter.d.ts +2 -429
- package/dist/src/terminal-command-cli-adapter.js +344 -6061
- package/dist/src/terminal-command-cli-adapter.js.map +1 -1
- package/dist/src/terminal-command-cli-ports.d.ts +443 -0
- package/dist/src/terminal-command-cli-ports.js +2 -0
- package/dist/src/terminal-command-cli-ports.js.map +1 -0
- package/dist/src/terminal-command-dispatch-preparation.d.ts +81 -0
- package/dist/src/terminal-command-dispatch-preparation.js +209 -0
- package/dist/src/terminal-command-dispatch-preparation.js.map +1 -0
- package/dist/src/terminal-command-dispatch-transport.d.ts +35 -0
- package/dist/src/terminal-command-dispatch-transport.js +859 -0
- package/dist/src/terminal-command-dispatch-transport.js.map +1 -0
- package/dist/src/terminal-command-foreground-proof.d.ts +32 -0
- package/dist/src/terminal-command-foreground-proof.js +72 -0
- package/dist/src/terminal-command-foreground-proof.js.map +1 -0
- package/dist/src/terminal-command-send-preflight.d.ts +41 -0
- package/dist/src/terminal-command-send-preflight.js +86 -0
- package/dist/src/terminal-command-send-preflight.js.map +1 -0
- package/dist/src/terminal-composer-classifier.d.ts +55 -0
- package/dist/src/terminal-composer-classifier.js +638 -0
- package/dist/src/terminal-composer-classifier.js.map +1 -0
- package/dist/src/terminal-dispatch-recovery-authority.d.ts +56 -0
- package/dist/src/terminal-dispatch-recovery-authority.js +251 -0
- package/dist/src/terminal-dispatch-recovery-authority.js.map +1 -0
- package/dist/src/terminal-dispatch-recovery-cli-adapter.d.ts +1 -9
- package/dist/src/terminal-dispatch-recovery-cli-adapter.js +5 -240
- package/dist/src/terminal-dispatch-recovery-cli-adapter.js.map +1 -1
- package/dist/src/terminal-handoff-cli-adapter.d.ts +1 -11
- package/dist/src/terminal-handoff-cli-adapter.js +2 -39
- package/dist/src/terminal-handoff-cli-adapter.js.map +1 -1
- package/dist/src/terminal-human-explicit-send-cli-adapter.d.ts +25 -0
- package/dist/src/terminal-human-explicit-send-cli-adapter.js +903 -0
- package/dist/src/terminal-human-explicit-send-cli-adapter.js.map +1 -0
- package/dist/src/terminal-identity-authority-cli-adapter.d.ts +1 -6
- package/dist/src/terminal-identity-authority-cli-adapter.js +3 -33
- package/dist/src/terminal-identity-authority-cli-adapter.js.map +1 -1
- package/dist/src/terminal-interaction-cli-adapter.js +209 -210
- package/dist/src/terminal-interaction-cli-adapter.js.map +1 -1
- package/dist/src/terminal-interaction-core.d.ts +0 -2
- package/dist/src/terminal-interaction-core.js +4 -3
- package/dist/src/terminal-interaction-core.js.map +1 -1
- package/dist/src/terminal-interaction-protocol.d.ts +21 -0
- package/dist/src/terminal-interaction-protocol.js +74 -0
- package/dist/src/terminal-interaction-protocol.js.map +1 -1
- package/dist/src/terminal-interaction-response-bridge.d.ts +126 -0
- package/dist/src/terminal-interaction-response-bridge.js +579 -0
- package/dist/src/terminal-interaction-response-bridge.js.map +1 -0
- package/dist/src/terminal-interaction-response-transaction.d.ts +44 -0
- package/dist/src/terminal-interaction-response-transaction.js +56 -0
- package/dist/src/terminal-interaction-response-transaction.js.map +1 -0
- package/dist/src/terminal-list-action-policy.d.ts +43 -0
- package/dist/src/terminal-list-action-policy.js +165 -0
- package/dist/src/terminal-list-action-policy.js.map +1 -0
- package/dist/src/terminal-list-cli-adapter.d.ts +6 -36
- package/dist/src/terminal-list-cli-adapter.js +241 -1946
- package/dist/src/terminal-list-cli-adapter.js.map +1 -1
- package/dist/src/terminal-list-facts.d.ts +129 -0
- package/dist/src/terminal-list-facts.js +179 -0
- package/dist/src/terminal-list-facts.js.map +1 -0
- package/dist/src/terminal-list-inventory.d.ts +59 -0
- package/dist/src/terminal-list-inventory.js +194 -0
- package/dist/src/terminal-list-inventory.js.map +1 -0
- package/dist/src/terminal-list-ownership-service.d.ts +118 -0
- package/dist/src/terminal-list-ownership-service.js +1003 -0
- package/dist/src/terminal-list-ownership-service.js.map +1 -0
- package/dist/src/terminal-list-projection-service.d.ts +49 -0
- package/dist/src/terminal-list-projection-service.js +407 -0
- package/dist/src/terminal-list-projection-service.js.map +1 -0
- package/dist/src/terminal-list-renderer.d.ts +11 -11
- package/dist/src/terminal-list-renderer.js +168 -119
- package/dist/src/terminal-list-renderer.js.map +1 -1
- package/dist/src/terminal-managed-send-cli-adapter.d.ts +33 -0
- package/dist/src/terminal-managed-send-cli-adapter.js +994 -0
- package/dist/src/terminal-managed-send-cli-adapter.js.map +1 -0
- package/dist/src/terminal-managed-turn-list-action-policy.d.ts +47 -0
- package/dist/src/terminal-managed-turn-list-action-policy.js +64 -0
- package/dist/src/terminal-managed-turn-list-action-policy.js.map +1 -0
- package/dist/src/terminal-model-control-action-policy.d.ts +60 -0
- package/dist/src/terminal-model-control-action-policy.js +96 -0
- package/dist/src/terminal-model-control-action-policy.js.map +1 -0
- package/dist/src/terminal-model-control-availability.d.ts +68 -0
- package/dist/src/terminal-model-control-availability.js +157 -0
- package/dist/src/terminal-model-control-availability.js.map +1 -0
- package/dist/src/terminal-model-control-bridge.d.ts +48 -0
- package/dist/src/terminal-model-control-bridge.js +259 -0
- package/dist/src/terminal-model-control-bridge.js.map +1 -0
- package/dist/src/terminal-model-control-profile.d.ts +55 -0
- package/dist/src/terminal-model-control-profile.js +137 -0
- package/dist/src/terminal-model-control-profile.js.map +1 -0
- package/dist/src/terminal-model-control-subject.d.ts +34 -0
- package/dist/src/terminal-model-control-subject.js +58 -0
- package/dist/src/terminal-model-control-subject.js.map +1 -0
- package/dist/src/terminal-model-control-transaction.d.ts +19 -0
- package/dist/src/terminal-model-control-transaction.js +39 -0
- package/dist/src/terminal-model-control-transaction.js.map +1 -0
- package/dist/src/terminal-model-control.d.ts +37 -18
- package/dist/src/terminal-model-control.js +285 -194
- package/dist/src/terminal-model-control.js.map +1 -1
- package/dist/src/terminal-monitor-application-service.js +50 -17
- package/dist/src/terminal-monitor-application-service.js.map +1 -1
- package/dist/src/terminal-native-inspection-bridge.d.ts +211 -0
- package/dist/src/terminal-native-inspection-bridge.js +1127 -0
- package/dist/src/terminal-native-inspection-bridge.js.map +1 -0
- package/dist/src/terminal-runtime-cli-adapter.d.ts +2 -2
- package/dist/src/terminal-runtime-cli-adapter.js.map +1 -1
- package/dist/src/terminal-submission-retry-application.d.ts +24 -0
- package/dist/src/terminal-submission-retry-application.js +402 -0
- package/dist/src/terminal-submission-retry-application.js.map +1 -0
- package/dist/src/terminal-submission-retry-ports.d.ts +30 -0
- package/dist/src/terminal-submission-retry-ports.js +2 -0
- package/dist/src/terminal-submission-retry-ports.js.map +1 -0
- package/dist/src/terminal-submission-retry-reconciliation.d.ts +236 -0
- package/dist/src/terminal-submission-retry-reconciliation.js +1130 -0
- package/dist/src/terminal-submission-retry-reconciliation.js.map +1 -0
- package/dist/src/terminal-submission-retry-transport.d.ts +58 -0
- package/dist/src/terminal-submission-retry-transport.js +675 -0
- package/dist/src/terminal-submission-retry-transport.js.map +1 -0
- package/dist/src/terminal-text-submission-bridge.d.ts +200 -0
- package/dist/src/terminal-text-submission-bridge.js +632 -0
- package/dist/src/terminal-text-submission-bridge.js.map +1 -0
- package/dist/src/terminal-user-explicit-send-policy.d.ts +29 -0
- package/dist/src/terminal-user-explicit-send-policy.js +46 -0
- package/dist/src/terminal-user-explicit-send-policy.js.map +1 -0
- package/dist/src/terminal-watch-cli-adapter.js +91 -143
- package/dist/src/terminal-watch-cli-adapter.js.map +1 -1
- package/dist/src/terminal-watch-codec.d.ts +9 -0
- package/dist/src/terminal-watch-codec.js +1051 -0
- package/dist/src/terminal-watch-codec.js.map +1 -0
- package/dist/src/terminal-watch-interaction-response-store.d.ts +19 -0
- package/dist/src/terminal-watch-interaction-response-store.js +87 -0
- package/dist/src/terminal-watch-interaction-response-store.js.map +1 -0
- package/dist/src/terminal-watch-record.d.ts +319 -0
- package/dist/src/terminal-watch-record.js +742 -0
- package/dist/src/terminal-watch-record.js.map +1 -0
- package/dist/src/terminal-watch-service.js +48 -27
- package/dist/src/terminal-watch-service.js.map +1 -1
- package/dist/src/terminal-watch-store.d.ts +3 -279
- package/dist/src/terminal-watch-store.js +5 -1779
- package/dist/src/terminal-watch-store.js.map +1 -1
- package/package.json +7 -2
- package/templates/openclaw-skills/agent-knock-knock/SKILL.md +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { createConnection } from "node:net";
|
|
3
|
+
const HERDR_MAX_REQUEST_BYTES = 1024 * 1024;
|
|
4
|
+
const HERDR_MAX_RESPONSE_BYTES = 16 * 1024 * 1024;
|
|
5
|
+
export const HERDR_DEFAULT_TIMEOUT_MS = 5_000;
|
|
6
|
+
/** A structured Herdr API rejection received after a complete request. */
|
|
7
|
+
export class HerdrApiError extends Error {
|
|
8
|
+
code;
|
|
9
|
+
requestId;
|
|
10
|
+
constructor(code, message, requestId) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.requestId = requestId;
|
|
14
|
+
this.name = "HerdrApiError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Raw socket failure with an explicit dispatch boundary.
|
|
19
|
+
*
|
|
20
|
+
* `definitelyNotSent` is true only when the Unix socket never connected or
|
|
21
|
+
* the request was rejected locally before any socket write was attempted.
|
|
22
|
+
*/
|
|
23
|
+
export class HerdrTransportError extends Error {
|
|
24
|
+
definitelyNotSent;
|
|
25
|
+
constructor(message, definitelyNotSent, options = {}) {
|
|
26
|
+
super(message, options);
|
|
27
|
+
this.definitelyNotSent = definitelyNotSent;
|
|
28
|
+
this.name = "HerdrTransportError";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Send one newline-delimited JSON request over a Herdr Unix-domain socket. */
|
|
32
|
+
export function requestHerdrUnixSocket(socketPath, request, options = {}) {
|
|
33
|
+
let encoded;
|
|
34
|
+
try {
|
|
35
|
+
encoded = `${JSON.stringify(request)}\n`;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return Promise.reject(new HerdrTransportError(`failed to encode Herdr request: ${describeError(error)}`, true, { cause: error }));
|
|
39
|
+
}
|
|
40
|
+
if (Buffer.byteLength(encoded) > HERDR_MAX_REQUEST_BYTES) {
|
|
41
|
+
return Promise.reject(new HerdrTransportError(`Herdr request exceeds ${HERDR_MAX_REQUEST_BYTES} bytes`, true));
|
|
42
|
+
}
|
|
43
|
+
const timeoutMs = positiveInteger(options.timeoutMs) ?? HERDR_DEFAULT_TIMEOUT_MS;
|
|
44
|
+
const maxResponseBytes = positiveInteger(options.maxResponseBytes) ??
|
|
45
|
+
HERDR_MAX_RESPONSE_BYTES;
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
let connected = false;
|
|
48
|
+
let settled = false;
|
|
49
|
+
let response = "";
|
|
50
|
+
const socket = createConnection({ path: socketPath });
|
|
51
|
+
socket.setEncoding("utf8");
|
|
52
|
+
socket.setTimeout(timeoutMs);
|
|
53
|
+
const fail = (message, definitelyNotSent, cause) => {
|
|
54
|
+
if (settled)
|
|
55
|
+
return;
|
|
56
|
+
settled = true;
|
|
57
|
+
socket.destroy();
|
|
58
|
+
reject(new HerdrTransportError(message, definitelyNotSent, { cause }));
|
|
59
|
+
};
|
|
60
|
+
socket.once("connect", () => {
|
|
61
|
+
if (settled)
|
|
62
|
+
return;
|
|
63
|
+
connected = true;
|
|
64
|
+
if (options.expectedSocketIdentity) {
|
|
65
|
+
let liveSocketIdentity;
|
|
66
|
+
try {
|
|
67
|
+
liveSocketIdentity = readHerdrSocketIdentity(socketPath);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
fail(`failed to revalidate Herdr socket ${socketPath}: ${describeError(error)}`, true, error);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!sameHerdrSocketIdentity(options.expectedSocketIdentity, liveSocketIdentity)) {
|
|
74
|
+
fail(`Herdr socket ${socketPath} changed before request dispatch`, true);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
socket.write(encoded, (error) => {
|
|
80
|
+
if (error) {
|
|
81
|
+
fail(`failed to write Herdr request: ${error.message}`, false, error);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
fail(`failed to write Herdr request: ${describeError(error)}`, false, error);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
socket.on("data", (chunk) => {
|
|
90
|
+
if (settled)
|
|
91
|
+
return;
|
|
92
|
+
response += String(chunk);
|
|
93
|
+
if (Buffer.byteLength(response) > maxResponseBytes) {
|
|
94
|
+
fail(`Herdr response exceeds ${maxResponseBytes} bytes`, false);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const newline = response.indexOf("\n");
|
|
98
|
+
if (newline < 0)
|
|
99
|
+
return;
|
|
100
|
+
const line = response.slice(0, newline).trim();
|
|
101
|
+
if (!line) {
|
|
102
|
+
fail("Herdr returned an empty response", false);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
let parsed;
|
|
106
|
+
try {
|
|
107
|
+
parsed = JSON.parse(line);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
fail(`Herdr returned invalid JSON: ${describeError(error)}`, false, error);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
settled = true;
|
|
114
|
+
socket.destroy();
|
|
115
|
+
resolve(parsed);
|
|
116
|
+
});
|
|
117
|
+
socket.once("timeout", () => {
|
|
118
|
+
fail(`timed out waiting for Herdr socket ${socketPath}`, !connected);
|
|
119
|
+
});
|
|
120
|
+
socket.once("error", (error) => {
|
|
121
|
+
fail(`Herdr socket ${socketPath} failed: ${error.message}`, !connected, error);
|
|
122
|
+
});
|
|
123
|
+
socket.once("end", () => {
|
|
124
|
+
if (!settled)
|
|
125
|
+
fail("Herdr closed the socket without a response", false);
|
|
126
|
+
});
|
|
127
|
+
socket.once("close", () => {
|
|
128
|
+
if (!settled)
|
|
129
|
+
fail("Herdr closed the socket without a response", !connected);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/** Resolve immutable filesystem identity for one owner-local Herdr socket. */
|
|
134
|
+
export function readHerdrSocketIdentity(socketPath) {
|
|
135
|
+
const stats = fs.lstatSync(socketPath, { bigint: true });
|
|
136
|
+
if (stats.isSymbolicLink()) {
|
|
137
|
+
throw new Error(`Herdr endpoint must not be a symbolic link: ${socketPath}`);
|
|
138
|
+
}
|
|
139
|
+
if (!stats.isSocket()) {
|
|
140
|
+
throw new Error(`Herdr endpoint is not a Unix socket: ${socketPath}`);
|
|
141
|
+
}
|
|
142
|
+
const ownerUid = Number(stats.uid);
|
|
143
|
+
const currentUid = typeof process.getuid === "function"
|
|
144
|
+
? process.getuid()
|
|
145
|
+
: undefined;
|
|
146
|
+
if (currentUid !== undefined && ownerUid !== currentUid) {
|
|
147
|
+
throw new Error(`Herdr socket ${socketPath} is owned by uid ${ownerUid}, expected ${currentUid}`);
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
device: stats.dev.toString(),
|
|
151
|
+
inode: stats.ino.toString(),
|
|
152
|
+
ctimeNs: stats.ctimeNs.toString(),
|
|
153
|
+
ownerUid
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
export function sameHerdrSocketIdentity(left, right) {
|
|
157
|
+
return left.device === right.device &&
|
|
158
|
+
left.inode === right.inode &&
|
|
159
|
+
left.ctimeNs === right.ctimeNs &&
|
|
160
|
+
left.ownerUid === right.ownerUid;
|
|
161
|
+
}
|
|
162
|
+
function positiveInteger(value) {
|
|
163
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0
|
|
164
|
+
? value
|
|
165
|
+
: undefined;
|
|
166
|
+
}
|
|
167
|
+
function describeError(error) {
|
|
168
|
+
return error instanceof Error ? error.message : String(error);
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=herdr-socket-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"herdr-socket-transport.js","sourceRoot":"","sources":["../../src/herdr-socket-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
import { type CommandResult, type TerminalDiscoveryDiagnosticLog, type TerminalControlProvider, type TerminalViewport } from "./terminal-control-provider.js";
|
|
2
2
|
import { type TerminalControlCapability, type TerminalControlRef, type TerminalEndpointRef, type TerminalProviderCapability } from "./terminal-control-ref.js";
|
|
3
3
|
import type { TerminalProcessSnapshot } from "./terminal-agent-adapter.js";
|
|
4
|
+
import { type HerdrRequestFunction, type HerdrSocketIdentity } from "./herdr-socket-transport.js";
|
|
5
|
+
export { HerdrApiError, HerdrTransportError, readHerdrSocketIdentity, requestHerdrUnixSocket, type HerdrRequestFunction, type HerdrRequestOptions, type HerdrSocketIdentity, type HerdrWireRequest } from "./herdr-socket-transport.js";
|
|
4
6
|
export declare const HERDR_EXACT_VERSION = "0.8.0";
|
|
5
7
|
export declare const HERDR_EXACT_PROTOCOL = 19;
|
|
6
|
-
type JsonRecord = Record<string, unknown>;
|
|
7
|
-
export interface HerdrWireRequest {
|
|
8
|
-
id: string;
|
|
9
|
-
method: string;
|
|
10
|
-
params: JsonRecord;
|
|
11
|
-
}
|
|
12
|
-
export interface HerdrSocketIdentity {
|
|
13
|
-
device: string;
|
|
14
|
-
inode: string;
|
|
15
|
-
ctimeNs: string;
|
|
16
|
-
ownerUid?: number;
|
|
17
|
-
}
|
|
18
8
|
export interface HerdrTtyDeviceIdentity {
|
|
19
9
|
device: string;
|
|
20
10
|
inode: string;
|
|
@@ -31,10 +21,6 @@ export interface HerdrTtyViewportInspectionOptions {
|
|
|
31
21
|
currentUid?: number;
|
|
32
22
|
}
|
|
33
23
|
export type HerdrTtyViewportInspector = (shellPid: number) => TerminalViewport | undefined | Promise<TerminalViewport | undefined>;
|
|
34
|
-
export interface HerdrRequestOptions {
|
|
35
|
-
expectedSocketIdentity?: HerdrSocketIdentity;
|
|
36
|
-
}
|
|
37
|
-
export type HerdrRequestFunction = (socketPath: string, request: HerdrWireRequest, options?: HerdrRequestOptions) => Promise<unknown>;
|
|
38
24
|
export interface HerdrSessionInfo {
|
|
39
25
|
name: string;
|
|
40
26
|
default: boolean;
|
|
@@ -58,33 +44,6 @@ export interface HerdrTerminalControlDiagnostics {
|
|
|
58
44
|
}>;
|
|
59
45
|
terminalCount: number;
|
|
60
46
|
}
|
|
61
|
-
/** A structured Herdr API rejection received after a complete request. */
|
|
62
|
-
export declare class HerdrApiError extends Error {
|
|
63
|
-
readonly code: string;
|
|
64
|
-
readonly requestId: string;
|
|
65
|
-
constructor(code: string, message: string, requestId: string);
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Raw socket failure with an explicit dispatch boundary.
|
|
69
|
-
*
|
|
70
|
-
* `definitelyNotSent` is true only when the Unix socket never connected or
|
|
71
|
-
* the request was rejected locally before any socket write was attempted.
|
|
72
|
-
*/
|
|
73
|
-
export declare class HerdrTransportError extends Error {
|
|
74
|
-
readonly definitelyNotSent: boolean;
|
|
75
|
-
constructor(message: string, definitelyNotSent: boolean, options?: {
|
|
76
|
-
cause?: unknown;
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Send one newline-delimited JSON request over a Herdr Unix-domain socket.
|
|
81
|
-
* Normal Herdr requests receive exactly one newline-delimited JSON response.
|
|
82
|
-
*/
|
|
83
|
-
export declare function requestHerdrUnixSocket(socketPath: string, request: HerdrWireRequest, options?: {
|
|
84
|
-
timeoutMs?: number;
|
|
85
|
-
maxResponseBytes?: number;
|
|
86
|
-
expectedSocketIdentity?: HerdrSocketIdentity;
|
|
87
|
-
}): Promise<unknown>;
|
|
88
47
|
export declare class HerdrTerminalControlProvider implements TerminalControlProvider {
|
|
89
48
|
readonly kind = "herdr";
|
|
90
49
|
readonly supportedCapabilities: readonly TerminalControlCapability[];
|
|
@@ -139,5 +98,3 @@ export declare function translateHerdrKey(value: string): string;
|
|
|
139
98
|
* resize the PTY without updating the layout rectangle that owns the pane.
|
|
140
99
|
*/
|
|
141
100
|
export declare function inspectHerdrTtyViewport(shellPid: number, options?: HerdrTtyViewportInspectionOptions): TerminalViewport | undefined;
|
|
142
|
-
export declare function readHerdrSocketIdentity(socketPath: string): HerdrSocketIdentity;
|
|
143
|
-
export {};
|
|
@@ -1,43 +1,16 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
-
import { createConnection } from "node:net";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import { isRecord } from "./value-guards.js";
|
|
6
5
|
import { TerminalControlInputNotSentError, TerminalControlUnavailableError } from "./terminal-control-provider.js";
|
|
7
6
|
import { createTerminalEndpointRef, herdrTerminalRouteKey, sameTerminalControlIncarnation, sameTerminalEndpointIdentity, terminalControlWithCapabilities, terminalEndpointFromControlRef } from "./terminal-control-ref.js";
|
|
7
|
+
import { HERDR_DEFAULT_TIMEOUT_MS, HerdrApiError, HerdrTransportError, readHerdrSocketIdentity, requestHerdrUnixSocket, sameHerdrSocketIdentity } from "./herdr-socket-transport.js";
|
|
8
|
+
export { HerdrApiError, HerdrTransportError, readHerdrSocketIdentity, requestHerdrUnixSocket } from "./herdr-socket-transport.js";
|
|
8
9
|
export const HERDR_EXACT_VERSION = "0.8.0";
|
|
9
10
|
export const HERDR_EXACT_PROTOCOL = 19;
|
|
10
|
-
const HERDR_MAX_REQUEST_BYTES = 1024 * 1024;
|
|
11
|
-
const HERDR_MAX_RESPONSE_BYTES = 16 * 1024 * 1024;
|
|
12
|
-
const HERDR_DEFAULT_TIMEOUT_MS = 5_000;
|
|
13
11
|
const HERDR_MAX_READ_LINES = 1_000;
|
|
14
12
|
const HERDR_MAX_TTY_PATH_BYTES = 1_024;
|
|
15
13
|
const HERDR_MAX_TTY_VIEWPORT_DIMENSION = 65_535;
|
|
16
|
-
/** A structured Herdr API rejection received after a complete request. */
|
|
17
|
-
export class HerdrApiError extends Error {
|
|
18
|
-
code;
|
|
19
|
-
requestId;
|
|
20
|
-
constructor(code, message, requestId) {
|
|
21
|
-
super(message);
|
|
22
|
-
this.code = code;
|
|
23
|
-
this.requestId = requestId;
|
|
24
|
-
this.name = "HerdrApiError";
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Raw socket failure with an explicit dispatch boundary.
|
|
29
|
-
*
|
|
30
|
-
* `definitelyNotSent` is true only when the Unix socket never connected or
|
|
31
|
-
* the request was rejected locally before any socket write was attempted.
|
|
32
|
-
*/
|
|
33
|
-
export class HerdrTransportError extends Error {
|
|
34
|
-
definitelyNotSent;
|
|
35
|
-
constructor(message, definitelyNotSent, options = {}) {
|
|
36
|
-
super(message, options);
|
|
37
|
-
this.definitelyNotSent = definitelyNotSent;
|
|
38
|
-
this.name = "HerdrTransportError";
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
14
|
class HerdrProviderUnavailableError extends Error {
|
|
42
15
|
constructor(message, options = {}) {
|
|
43
16
|
super(message, options);
|
|
@@ -50,121 +23,6 @@ class HerdrCompatibilityError extends Error {
|
|
|
50
23
|
this.name = "HerdrCompatibilityError";
|
|
51
24
|
}
|
|
52
25
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Send one newline-delimited JSON request over a Herdr Unix-domain socket.
|
|
55
|
-
* Normal Herdr requests receive exactly one newline-delimited JSON response.
|
|
56
|
-
*/
|
|
57
|
-
export function requestHerdrUnixSocket(socketPath, request, options = {}) {
|
|
58
|
-
let encoded;
|
|
59
|
-
try {
|
|
60
|
-
encoded = `${JSON.stringify(request)}\n`;
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
return Promise.reject(new HerdrTransportError(`failed to encode Herdr request: ${describeError(error)}`, true, { cause: error }));
|
|
64
|
-
}
|
|
65
|
-
if (Buffer.byteLength(encoded) > HERDR_MAX_REQUEST_BYTES) {
|
|
66
|
-
return Promise.reject(new HerdrTransportError(`Herdr request exceeds ${HERDR_MAX_REQUEST_BYTES} bytes`, true));
|
|
67
|
-
}
|
|
68
|
-
const timeoutMs = positiveInteger(options.timeoutMs) ?? HERDR_DEFAULT_TIMEOUT_MS;
|
|
69
|
-
const maxResponseBytes = positiveInteger(options.maxResponseBytes) ??
|
|
70
|
-
HERDR_MAX_RESPONSE_BYTES;
|
|
71
|
-
return new Promise((resolve, reject) => {
|
|
72
|
-
let connected = false;
|
|
73
|
-
let settled = false;
|
|
74
|
-
let response = "";
|
|
75
|
-
const socket = createConnection({ path: socketPath });
|
|
76
|
-
socket.setEncoding("utf8");
|
|
77
|
-
socket.setTimeout(timeoutMs);
|
|
78
|
-
const fail = (message, definitelyNotSent, cause) => {
|
|
79
|
-
if (settled) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
settled = true;
|
|
83
|
-
socket.destroy();
|
|
84
|
-
reject(new HerdrTransportError(message, definitelyNotSent, { cause }));
|
|
85
|
-
};
|
|
86
|
-
socket.once("connect", () => {
|
|
87
|
-
if (settled) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
connected = true;
|
|
91
|
-
if (options.expectedSocketIdentity) {
|
|
92
|
-
let liveSocketIdentity;
|
|
93
|
-
try {
|
|
94
|
-
liveSocketIdentity = readHerdrSocketIdentity(socketPath);
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
fail(`failed to revalidate Herdr socket ${socketPath}: ${describeError(error)}`, true, error);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (!sameHerdrSocketIdentity(options.expectedSocketIdentity, liveSocketIdentity)) {
|
|
101
|
-
fail(`Herdr socket ${socketPath} changed before request dispatch`, true);
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
try {
|
|
106
|
-
socket.write(encoded, (error) => {
|
|
107
|
-
if (error) {
|
|
108
|
-
// A connected stream may have accepted a prefix before reporting
|
|
109
|
-
// an error, so this boundary is deliberately uncertain.
|
|
110
|
-
fail(`failed to write Herdr request: ${error.message}`, false, error);
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
// The socket connected, so even a synchronous write failure is kept
|
|
116
|
-
// conservative: implementations may have accepted a prefix first.
|
|
117
|
-
fail(`failed to write Herdr request: ${describeError(error)}`, false, error);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
socket.on("data", (chunk) => {
|
|
121
|
-
if (settled) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
response += String(chunk);
|
|
125
|
-
if (Buffer.byteLength(response) > maxResponseBytes) {
|
|
126
|
-
fail(`Herdr response exceeds ${maxResponseBytes} bytes`, false);
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
const newline = response.indexOf("\n");
|
|
130
|
-
if (newline < 0) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
const line = response.slice(0, newline).trim();
|
|
134
|
-
if (!line) {
|
|
135
|
-
fail("Herdr returned an empty response", false);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
let parsed;
|
|
139
|
-
try {
|
|
140
|
-
parsed = JSON.parse(line);
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
fail(`Herdr returned invalid JSON: ${describeError(error)}`, false, error);
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
settled = true;
|
|
147
|
-
socket.destroy();
|
|
148
|
-
resolve(parsed);
|
|
149
|
-
});
|
|
150
|
-
socket.once("timeout", () => {
|
|
151
|
-
fail(`timed out waiting for Herdr socket ${socketPath}`, !connected);
|
|
152
|
-
});
|
|
153
|
-
socket.once("error", (error) => {
|
|
154
|
-
fail(`Herdr socket ${socketPath} failed: ${error.message}`, !connected, error);
|
|
155
|
-
});
|
|
156
|
-
socket.once("end", () => {
|
|
157
|
-
if (!settled) {
|
|
158
|
-
fail("Herdr closed the socket without a response", false);
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
socket.once("close", () => {
|
|
162
|
-
if (!settled) {
|
|
163
|
-
fail("Herdr closed the socket without a response", !connected);
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
26
|
export class HerdrTerminalControlProvider {
|
|
169
27
|
kind = "herdr";
|
|
170
28
|
supportedCapabilities = [
|
|
@@ -1463,34 +1321,6 @@ function sameHerdrTtyDeviceIdentity(left, right) {
|
|
|
1463
1321
|
left.symbolicLink === right.symbolicLink &&
|
|
1464
1322
|
left.characterDevice === right.characterDevice;
|
|
1465
1323
|
}
|
|
1466
|
-
export function readHerdrSocketIdentity(socketPath) {
|
|
1467
|
-
const stats = fs.lstatSync(socketPath, { bigint: true });
|
|
1468
|
-
if (stats.isSymbolicLink()) {
|
|
1469
|
-
throw new Error(`Herdr endpoint must not be a symbolic link: ${socketPath}`);
|
|
1470
|
-
}
|
|
1471
|
-
if (!stats.isSocket()) {
|
|
1472
|
-
throw new Error(`Herdr endpoint is not a Unix socket: ${socketPath}`);
|
|
1473
|
-
}
|
|
1474
|
-
const ownerUid = Number(stats.uid);
|
|
1475
|
-
const currentUid = typeof process.getuid === "function"
|
|
1476
|
-
? process.getuid()
|
|
1477
|
-
: undefined;
|
|
1478
|
-
if (currentUid !== undefined && ownerUid !== currentUid) {
|
|
1479
|
-
throw new Error(`Herdr socket ${socketPath} is owned by uid ${ownerUid}, expected ${currentUid}`);
|
|
1480
|
-
}
|
|
1481
|
-
return {
|
|
1482
|
-
device: stats.dev.toString(),
|
|
1483
|
-
inode: stats.ino.toString(),
|
|
1484
|
-
ctimeNs: stats.ctimeNs.toString(),
|
|
1485
|
-
ownerUid
|
|
1486
|
-
};
|
|
1487
|
-
}
|
|
1488
|
-
function sameHerdrSocketIdentity(left, right) {
|
|
1489
|
-
return left.device === right.device &&
|
|
1490
|
-
left.inode === right.inode &&
|
|
1491
|
-
left.ctimeNs === right.ctimeNs &&
|
|
1492
|
-
left.ownerUid === right.ownerUid;
|
|
1493
|
-
}
|
|
1494
1324
|
function commandDefinitelyDidNotStart(error) {
|
|
1495
1325
|
const code = error?.code;
|
|
1496
1326
|
return code === "ENOENT" || code === "EACCES";
|