@stateforge-labs/herdr-sdk 0.0.0-stage → 0.3.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/LICENSE +18 -0
- package/NOTICE.md +51 -0
- package/README.md +211 -2
- package/bin/herdr-drift.js +14 -0
- package/bin/herdr-skill.js +38 -0
- package/dist/admin.d.ts +2 -0
- package/dist/admin.js +3 -0
- package/dist/constants.d.ts +236 -0
- package/dist/constants.js +294 -0
- package/dist/core/backoff.d.ts +20 -0
- package/dist/core/backoff.js +53 -0
- package/dist/core/constants.d.ts +143 -0
- package/dist/core/constants.js +98 -0
- package/dist/core/errors.d.ts +35 -0
- package/dist/core/errors.js +16 -0
- package/dist/core/events.d.ts +42 -0
- package/dist/core/events.js +128 -0
- package/dist/core/kernel.d.ts +65 -0
- package/dist/core/kernel.js +138 -0
- package/dist/core/link.d.ts +47 -0
- package/dist/core/link.js +187 -0
- package/dist/core/test-kit/constants.d.ts +51 -0
- package/dist/core/test-kit/constants.js +43 -0
- package/dist/core/test-kit/fake-core.d.ts +61 -0
- package/dist/core/test-kit/fake-core.js +228 -0
- package/dist/core/test-kit/frames.d.ts +1 -0
- package/dist/core/test-kit/frames.js +480 -0
- package/dist/core/test-kit/setup-test.d.ts +18 -0
- package/dist/core/test-kit/setup-test.js +35 -0
- package/dist/core/wire.d.ts +85 -0
- package/dist/core/wire.js +199 -0
- package/dist/core-test-kit.d.ts +5 -0
- package/dist/core-test-kit.js +5 -0
- package/dist/core.d.ts +15 -0
- package/dist/core.js +12 -0
- package/dist/drift/cli.d.ts +22 -0
- package/dist/drift/cli.js +146 -0
- package/dist/drift/constants.d.ts +83 -0
- package/dist/drift/constants.js +73 -0
- package/dist/drift/diff.d.ts +7 -0
- package/dist/drift/diff.js +91 -0
- package/dist/drift/schema.d.ts +19 -0
- package/dist/drift/schema.js +190 -0
- package/dist/drift/types.d.ts +76 -0
- package/dist/drift/types.js +1 -0
- package/dist/drift.d.ts +5 -0
- package/dist/drift.js +6 -0
- package/dist/effect.d.ts +3 -0
- package/dist/effect.js +4 -0
- package/dist/herdr/client/connect.d.ts +5 -0
- package/dist/herdr/client/connect.js +81 -0
- package/dist/herdr/client/held.d.ts +54 -0
- package/dist/herdr/client/held.js +100 -0
- package/dist/herdr/client/long-poll.d.ts +33 -0
- package/dist/herdr/client/long-poll.js +66 -0
- package/dist/herdr/client/scoped.d.ts +45 -0
- package/dist/herdr/client/scoped.js +241 -0
- package/dist/herdr/client/streams.d.ts +9 -0
- package/dist/herdr/client/streams.js +40 -0
- package/dist/herdr/client/subscribe.d.ts +75 -0
- package/dist/herdr/client/subscribe.js +208 -0
- package/dist/herdr/client/types.d.ts +150 -0
- package/dist/herdr/client/types.js +1 -0
- package/dist/herdr/client/watch-pane-set.d.ts +34 -0
- package/dist/herdr/client/watch-pane-set.js +271 -0
- package/dist/herdr/client/watch.d.ts +117 -0
- package/dist/herdr/client/watch.js +138 -0
- package/dist/herdr/effect/to-tagged-error.d.ts +2 -0
- package/dist/herdr/effect/to-tagged-error.js +54 -0
- package/dist/herdr/effect/types.d.ts +51 -0
- package/dist/herdr/effect/types.js +26 -0
- package/dist/herdr/errors.d.ts +53 -0
- package/dist/herdr/errors.js +87 -0
- package/dist/herdr/generated/entries/admin.d.ts +2 -0
- package/dist/herdr/generated/entries/admin.js +5 -0
- package/dist/herdr/generated/entries/client.d.ts +2 -0
- package/dist/herdr/generated/entries/client.js +5 -0
- package/dist/herdr/generated/entries/held.d.ts +2 -0
- package/dist/herdr/generated/entries/held.js +5 -0
- package/dist/herdr/generated/entries/prompt.d.ts +2 -0
- package/dist/herdr/generated/entries/prompt.js +5 -0
- package/dist/herdr/generated/entries/read-only-content.d.ts +2 -0
- package/dist/herdr/generated/entries/read-only-content.js +5 -0
- package/dist/herdr/generated/entries/read-only.d.ts +2 -0
- package/dist/herdr/generated/entries/read-only.js +5 -0
- package/dist/herdr/generated/entry-methods.d.ts +9 -0
- package/dist/herdr/generated/entry-methods.js +17 -0
- package/dist/herdr/generated/errors.d.ts +4 -0
- package/dist/herdr/generated/errors.js +3 -0
- package/dist/herdr/generated/events.d.ts +274 -0
- package/dist/herdr/generated/events.js +3 -0
- package/dist/herdr/generated/index.d.ts +20 -0
- package/dist/herdr/generated/index.js +19 -0
- package/dist/herdr/generated/method-table.d.ts +615 -0
- package/dist/herdr/generated/method-table.js +106 -0
- package/dist/herdr/generated/names/agent-status.d.ts +10 -0
- package/dist/herdr/generated/names/agent-status.js +10 -0
- package/dist/herdr/generated/names/capability-class.d.ts +14 -0
- package/dist/herdr/generated/names/capability-class.js +15 -0
- package/dist/herdr/generated/names/event-kind.d.ts +31 -0
- package/dist/herdr/generated/names/event-kind.js +31 -0
- package/dist/herdr/generated/names/event-match-kind.d.ts +23 -0
- package/dist/herdr/generated/names/event-match-kind.js +24 -0
- package/dist/herdr/generated/names/index.d.ts +10 -0
- package/dist/herdr/generated/names/index.js +12 -0
- package/dist/herdr/generated/names/method.d.ts +209 -0
- package/dist/herdr/generated/names/method.js +209 -0
- package/dist/herdr/generated/names/result-tag.d.ts +68 -0
- package/dist/herdr/generated/names/result-tag.js +68 -0
- package/dist/herdr/generated/names/server-capability.d.ts +10 -0
- package/dist/herdr/generated/names/server-capability.js +11 -0
- package/dist/herdr/generated/names/subscription-event-kind.d.ts +8 -0
- package/dist/herdr/generated/names/subscription-event-kind.js +8 -0
- package/dist/herdr/generated/names/subscription-type.d.ts +31 -0
- package/dist/herdr/generated/names/subscription-type.js +32 -0
- package/dist/herdr/generated/names/token-name-pattern.d.ts +2 -0
- package/dist/herdr/generated/names/token-name-pattern.js +4 -0
- package/dist/herdr/generated/namespaces.d.ts +785 -0
- package/dist/herdr/generated/namespaces.js +3 -0
- package/dist/herdr/generated/overrides.d.ts +33 -0
- package/dist/herdr/generated/overrides.js +20 -0
- package/dist/herdr/generated/params.d.ts +799 -0
- package/dist/herdr/generated/params.js +3 -0
- package/dist/herdr/generated/preset-methods.d.ts +4 -0
- package/dist/herdr/generated/preset-methods.js +7 -0
- package/dist/herdr/generated/presets/sessions-reader.d.ts +2 -0
- package/dist/herdr/generated/presets/sessions-reader.js +5 -0
- package/dist/herdr/generated/results.d.ts +978 -0
- package/dist/herdr/generated/results.js +52 -0
- package/dist/herdr/generated/test-data/defaults.d.ts +739 -0
- package/dist/herdr/generated/test-data/defaults.js +741 -0
- package/dist/herdr/generated/test-data/shapes.d.ts +1325 -0
- package/dist/herdr/generated/test-data/shapes.js +2245 -0
- package/dist/herdr/test-kit/fake-herdr.d.ts +13 -0
- package/dist/herdr/test-kit/fake-herdr.js +216 -0
- package/dist/herdr/test-kit/fake-protocol.d.ts +107 -0
- package/dist/herdr/test-kit/fake-protocol.js +436 -0
- package/dist/herdr/test-kit/types.d.ts +88 -0
- package/dist/herdr/test-kit/types.js +1 -0
- package/dist/herdr/wire/codec.d.ts +36 -0
- package/dist/herdr/wire/codec.js +62 -0
- package/dist/herdr/wire/connection.d.ts +13 -0
- package/dist/herdr/wire/connection.js +65 -0
- package/dist/herdr/wire/dedicated.d.ts +2 -0
- package/dist/herdr/wire/dedicated.js +238 -0
- package/dist/herdr/wire/push-decoder.d.ts +2 -0
- package/dist/herdr/wire/push-decoder.js +40 -0
- package/dist/herdr/wire/rpc.d.ts +3 -0
- package/dist/herdr/wire/rpc.js +141 -0
- package/dist/herdr/wire/socket-path.d.ts +8 -0
- package/dist/herdr/wire/socket-path.js +23 -0
- package/dist/herdr/wire/types.d.ts +78 -0
- package/dist/herdr/wire/types.js +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +7 -0
- package/dist/read-only.d.ts +5 -0
- package/dist/read-only.js +6 -0
- package/dist/schema.d.ts +5 -0
- package/dist/schema.js +6 -0
- package/dist/test-kit.d.ts +2 -0
- package/dist/test-kit.js +3 -0
- package/docs/api/events.md +43 -0
- package/docs/api/methods.md +232 -0
- package/package.json +112 -4
- package/schema/herdr-api.schema.json +10759 -0
- package/schema/herdr-version.json +5 -0
- package/skills/herdr-sdk/SKILL.md +75 -0
- package/skills/herdr-sdk/references/api-map.md +28 -0
- package/skills/herdr-sdk/references/errors.md +19 -0
- package/skills/herdr-sdk/references/recipes.md +171 -0
- package/skills/herdr-sdk/references/versions.md +7 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Role: one Unix-socket connection to herdr: opens it, writes NDJSON lines, reads lines through the LineSplitter and reports close and error.
|
|
2
|
+
// Informs HERDR-ADR-0016 (W1 one connection per request) and plan 3.1 (connection).
|
|
3
|
+
import { createConnection } from 'node:net';
|
|
4
|
+
import { ErrorText, LINE_SEPARATOR, TEXT_ENCODING } from '../../constants.js';
|
|
5
|
+
import { HerdrTransportError } from '../errors.js';
|
|
6
|
+
import { LineSplitter } from './codec.js';
|
|
7
|
+
export class Connection {
|
|
8
|
+
socket;
|
|
9
|
+
constructor(socket) {
|
|
10
|
+
this.socket = socket;
|
|
11
|
+
}
|
|
12
|
+
// Resolves once connected. A failure or a close before connecting rejects with CannotConnect; later failures go to onError
|
|
13
|
+
// and the close after connecting goes to onClose (exactly once, from the socket's own close event).
|
|
14
|
+
static open(path, handlers) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const socket = createConnection({ path });
|
|
17
|
+
const state = { connected: false };
|
|
18
|
+
socket.setEncoding(TEXT_ENCODING);
|
|
19
|
+
attachReaders(socket, handlers, state);
|
|
20
|
+
socket.on('error', (error) => {
|
|
21
|
+
if (state.connected) {
|
|
22
|
+
handlers.onError(error);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
reject(cannotConnect(path, error));
|
|
26
|
+
});
|
|
27
|
+
socket.on('close', () => {
|
|
28
|
+
if (!state.connected) {
|
|
29
|
+
reject(cannotConnect(path, undefined));
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
socket.on('connect', () => {
|
|
33
|
+
state.connected = true;
|
|
34
|
+
resolve(new Connection(socket));
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
writeLine(line) {
|
|
39
|
+
this.socket.write(`${line}${LINE_SEPARATOR}`);
|
|
40
|
+
}
|
|
41
|
+
// Half-close: ends the write side only. rpc does not use it: every call destroys its socket on exit (W1).
|
|
42
|
+
close() {
|
|
43
|
+
this.socket.end();
|
|
44
|
+
}
|
|
45
|
+
destroy() {
|
|
46
|
+
this.socket.destroy();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function cannotConnect(path, cause) {
|
|
50
|
+
return new HerdrTransportError(ErrorText.CannotConnect(path), { cause });
|
|
51
|
+
}
|
|
52
|
+
// Data becomes lines through a splitter; close is forwarded only once connected. The error listener is attached by open().
|
|
53
|
+
function attachReaders(socket, handlers, state) {
|
|
54
|
+
const splitter = new LineSplitter();
|
|
55
|
+
socket.on('data', (chunk) => {
|
|
56
|
+
for (const line of splitter.push(chunk)) {
|
|
57
|
+
handlers.onLine(line);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
socket.on('close', () => {
|
|
61
|
+
if (state.connected) {
|
|
62
|
+
handlers.onClose();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
// Role: a connection kept open on purpose (a subscription, later a held connection): one request at a time, pushes handed to one listener, and one `ended` that says who closed it.
|
|
2
|
+
// Informs HERDR-ADR-0016 (W1 one request per connection, W2 ack then a held stream of id-less pushes, W3 an id "" reply then EOF is an answer), HERDR-ADR-0007 and plan 3.6; contract in wire/types.ts (OpenDedicated, DedicatedConnection).
|
|
3
|
+
import { CallOutcome, EMPTY_REPLY_ID, ErrorText, WireField } from '../../constants.js';
|
|
4
|
+
import { outcomeOf, reportCall } from './codec.js';
|
|
5
|
+
import { Connection } from './connection.js';
|
|
6
|
+
import { HerdrError, HerdrTransportError } from '../errors.js';
|
|
7
|
+
import { encodeRequest, isErrorEnvelope, isObject } from './codec.js';
|
|
8
|
+
import { nextId } from './codec.js';
|
|
9
|
+
// Texts only this layer words (the shared constants file is read-only for lane P4a).
|
|
10
|
+
const DedicatedText = {
|
|
11
|
+
Aborted: 'dedicated connection: aborted before it opened',
|
|
12
|
+
Malformed: 'dedicated connection: unparseable line',
|
|
13
|
+
SocketError: 'dedicated connection: socket error',
|
|
14
|
+
RequestPending: (method) => `${method}: another request is still pending on this connection`,
|
|
15
|
+
};
|
|
16
|
+
const NO_CLEANUP = () => undefined;
|
|
17
|
+
export const openDedicated = async function openDedicated(options) {
|
|
18
|
+
if (options.signal?.aborted === true) {
|
|
19
|
+
throw new HerdrTransportError(DedicatedText.Aborted);
|
|
20
|
+
}
|
|
21
|
+
const session = newSession(options.onCall);
|
|
22
|
+
const connection = await Connection.open(options.socketPath, handlersFor(session));
|
|
23
|
+
session.connection = connection;
|
|
24
|
+
session.detachSignal = listenForAbort(options.signal, () => {
|
|
25
|
+
finish(session, { byServer: false });
|
|
26
|
+
});
|
|
27
|
+
if (session.finished) {
|
|
28
|
+
connection.destroy();
|
|
29
|
+
}
|
|
30
|
+
return connectionOf(session);
|
|
31
|
+
};
|
|
32
|
+
function newSession(onCall) {
|
|
33
|
+
return {
|
|
34
|
+
onCall,
|
|
35
|
+
ending: newEnding(),
|
|
36
|
+
connection: undefined,
|
|
37
|
+
pending: undefined,
|
|
38
|
+
pushListener: undefined,
|
|
39
|
+
finished: false,
|
|
40
|
+
detachSignal: NO_CLEANUP,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function newEnding() {
|
|
44
|
+
let settle = NO_CLEANUP;
|
|
45
|
+
const ended = new Promise((resolve) => {
|
|
46
|
+
settle = resolve;
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
ended,
|
|
50
|
+
settle: (end) => {
|
|
51
|
+
settle(end);
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Socket events feed the session: a line is routed, a server close ends it by server, a socket error ends it with a cause.
|
|
56
|
+
function handlersFor(session) {
|
|
57
|
+
return {
|
|
58
|
+
onLine: (line) => {
|
|
59
|
+
routeLine(session, line);
|
|
60
|
+
},
|
|
61
|
+
onClose: () => {
|
|
62
|
+
finish(session, { byServer: true });
|
|
63
|
+
},
|
|
64
|
+
onError: (error) => {
|
|
65
|
+
finish(session, { byServer: false, cause: new HerdrTransportError(DedicatedText.SocketError, { cause: error }) });
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function connectionOf(session) {
|
|
70
|
+
return {
|
|
71
|
+
request: requestOn(session),
|
|
72
|
+
onPush: (listener) => {
|
|
73
|
+
session.pushListener = listener;
|
|
74
|
+
},
|
|
75
|
+
ended: session.ending.ended,
|
|
76
|
+
destroy: () => {
|
|
77
|
+
finish(session, { byServer: false });
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// Named generic so the request keeps the method's params and result types (ParamsOf, ResultOf).
|
|
82
|
+
function requestOn(session) {
|
|
83
|
+
return function request(method, params, options = {}) {
|
|
84
|
+
return sendRequest(session, method, params, options);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Reports the call to onCall once, whatever the outcome; the hook cannot change the result.
|
|
88
|
+
function sendRequest(session, method, params, options) {
|
|
89
|
+
const startedAt = performance.now();
|
|
90
|
+
return exchange(session, method, params, options).then((value) => {
|
|
91
|
+
reportCall(session.onCall, { method, durationMs: performance.now() - startedAt, outcome: CallOutcome.Answered });
|
|
92
|
+
return typedResult(value);
|
|
93
|
+
}, (error) => {
|
|
94
|
+
reportCall(session.onCall, { method, durationMs: performance.now() - startedAt, ...outcomeOf(error) });
|
|
95
|
+
throw error;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// The reply is typed by the method's result; the wire layer trusts herdr's shape here, as rpc does.
|
|
99
|
+
function typedResult(value) {
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
function exchange(session, method, params, options) {
|
|
103
|
+
if (session.finished) {
|
|
104
|
+
return Promise.reject(new HerdrTransportError(ErrorText.ClosedBeforeResponse(method)));
|
|
105
|
+
}
|
|
106
|
+
if (session.pending !== undefined) {
|
|
107
|
+
return Promise.reject(new HerdrTransportError(DedicatedText.RequestPending(method)));
|
|
108
|
+
}
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
const pending = {
|
|
111
|
+
method,
|
|
112
|
+
requestId: nextId(),
|
|
113
|
+
resolve,
|
|
114
|
+
reject,
|
|
115
|
+
timer: undefined,
|
|
116
|
+
detachAbort: NO_CLEANUP,
|
|
117
|
+
};
|
|
118
|
+
session.pending = pending;
|
|
119
|
+
pending.detachAbort = listenForAbort(options.signal, () => {
|
|
120
|
+
failRequest(session, new HerdrTransportError(ErrorText.Aborted(method)));
|
|
121
|
+
});
|
|
122
|
+
if (session.pending !== pending) {
|
|
123
|
+
// An abort that was already on the signal settled the request before it was sent.
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
armTimeout(session, pending, options.timeoutMs);
|
|
127
|
+
if (!session.finished) {
|
|
128
|
+
session.connection?.writeLine(encodeRequest(pending.requestId, method, params));
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function armTimeout(session, pending, timeoutMs) {
|
|
133
|
+
if (timeoutMs === undefined) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
pending.timer = setTimeout(() => {
|
|
137
|
+
failRequest(session, new HerdrTransportError(ErrorText.NoResponse(pending.method, timeoutMs), { isTimeout: true }));
|
|
138
|
+
}, timeoutMs);
|
|
139
|
+
}
|
|
140
|
+
// Reads one line: an unparseable one ends the connection; an id-less one is a push; any other is a reply to the request.
|
|
141
|
+
function routeLine(session, text) {
|
|
142
|
+
if (session.finished) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const line = parseObject(text);
|
|
146
|
+
if (line === undefined) {
|
|
147
|
+
finish(session, { byServer: false, cause: new HerdrTransportError(DedicatedText.Malformed) });
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (!(WireField.Id in line)) {
|
|
151
|
+
session.pushListener?.(line);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
routeReply(session, line);
|
|
155
|
+
}
|
|
156
|
+
function parseObject(text) {
|
|
157
|
+
let value;
|
|
158
|
+
try {
|
|
159
|
+
value = JSON.parse(text);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
return isObject(value) ? value : undefined;
|
|
165
|
+
}
|
|
166
|
+
// The reply carries the request id, or the empty id herdr uses for an unparseable request (W3). Any other id is a stray.
|
|
167
|
+
function routeReply(session, reply) {
|
|
168
|
+
const pending = session.pending;
|
|
169
|
+
if (pending === undefined || !isAnswerTo(pending, reply)) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (isErrorEnvelope(reply)) {
|
|
173
|
+
const { error } = reply;
|
|
174
|
+
settleRequest(session, (done) => {
|
|
175
|
+
done.reject(HerdrError.from(done.method, error));
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const result = resultOf(reply);
|
|
180
|
+
settleRequest(session, (done) => {
|
|
181
|
+
done.resolve(result);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function isAnswerTo(pending, reply) {
|
|
185
|
+
const id = idOf(reply);
|
|
186
|
+
return id === pending.requestId || id === EMPTY_REPLY_ID;
|
|
187
|
+
}
|
|
188
|
+
function idOf(reply) {
|
|
189
|
+
return WireField.Id in reply ? reply[WireField.Id] : undefined;
|
|
190
|
+
}
|
|
191
|
+
function resultOf(reply) {
|
|
192
|
+
return WireField.Result in reply ? reply[WireField.Result] : undefined;
|
|
193
|
+
}
|
|
194
|
+
// The first exit wins: clears the timer and the abort listener, then runs the outcome once.
|
|
195
|
+
function settleRequest(session, outcome) {
|
|
196
|
+
const pending = session.pending;
|
|
197
|
+
if (pending === undefined) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
session.pending = undefined;
|
|
201
|
+
clearTimeout(pending.timer);
|
|
202
|
+
pending.detachAbort();
|
|
203
|
+
outcome(pending);
|
|
204
|
+
}
|
|
205
|
+
// A request that timed out or was aborted rejects, and the connection is destroyed: its state after that is unknown.
|
|
206
|
+
function failRequest(session, error) {
|
|
207
|
+
settleRequest(session, (pending) => {
|
|
208
|
+
pending.reject(error);
|
|
209
|
+
});
|
|
210
|
+
finish(session, { byServer: false, cause: error });
|
|
211
|
+
}
|
|
212
|
+
// Ends the connection once: a request still waiting rejects with the cause (or a closed-before-response error), the socket is destroyed, `ended` resolves.
|
|
213
|
+
function finish(session, end) {
|
|
214
|
+
if (session.finished) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
session.finished = true;
|
|
218
|
+
session.detachSignal();
|
|
219
|
+
settleRequest(session, (pending) => {
|
|
220
|
+
pending.reject(end.cause ?? new HerdrTransportError(ErrorText.ClosedBeforeResponse(pending.method)));
|
|
221
|
+
});
|
|
222
|
+
session.connection?.destroy();
|
|
223
|
+
session.ending.settle(end);
|
|
224
|
+
}
|
|
225
|
+
// Runs the handler when the signal aborts (at once when it already has). Returns the function that removes the listener.
|
|
226
|
+
function listenForAbort(signal, onAbort) {
|
|
227
|
+
if (signal === undefined) {
|
|
228
|
+
return NO_CLEANUP;
|
|
229
|
+
}
|
|
230
|
+
if (signal.aborted) {
|
|
231
|
+
onAbort();
|
|
232
|
+
return NO_CLEANUP;
|
|
233
|
+
}
|
|
234
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
235
|
+
return () => {
|
|
236
|
+
signal.removeEventListener('abort', onAbort);
|
|
237
|
+
};
|
|
238
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Role: decodes one push line into a known frame or an UnknownFrame: the envelope is checked (event is a string, data is present), the data is not (P4).
|
|
2
|
+
// Informs HERDR-ADR-0016 (W2 pushes carry no id, P3 unknown kinds surfaced, P4 envelope-only validation), HERDR-ADR-0007 and plan 3.6; contract in wire/types.ts (DecodePush).
|
|
3
|
+
import { UNKNOWN_EVENT, WireField } from '../../constants.js';
|
|
4
|
+
import { EventKind, SubscriptionEventKind } from '../generated/index.js';
|
|
5
|
+
import { isObject } from './codec.js';
|
|
6
|
+
// Field names and JSON type names this decoder reads (the push envelope has no other fields).
|
|
7
|
+
const PushField = {
|
|
8
|
+
Data: 'data',
|
|
9
|
+
};
|
|
10
|
+
const JsonType = {
|
|
11
|
+
String: 'string',
|
|
12
|
+
};
|
|
13
|
+
// Every event name herdr can push, built once from the generated kinds (no hand list).
|
|
14
|
+
const KNOWN_EVENTS = new Set([
|
|
15
|
+
...Object.values(EventKind),
|
|
16
|
+
...Object.values(SubscriptionEventKind),
|
|
17
|
+
]);
|
|
18
|
+
export const decodePush = function decodePush(line) {
|
|
19
|
+
if (!hasPushShape(line)) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const event = line[WireField.Event];
|
|
23
|
+
return isKnownEvent(event) ? toPushFrame(line) : toUnknownFrame(line, event);
|
|
24
|
+
};
|
|
25
|
+
function hasPushShape(line) {
|
|
26
|
+
return (isObject(line) &&
|
|
27
|
+
WireField.Event in line &&
|
|
28
|
+
typeof line[WireField.Event] === JsonType.String &&
|
|
29
|
+
PushField.Data in line);
|
|
30
|
+
}
|
|
31
|
+
function isKnownEvent(name) {
|
|
32
|
+
return KNOWN_EVENTS.has(name);
|
|
33
|
+
}
|
|
34
|
+
// The envelope is checked, the data is not (P4): the typed frame is the line itself, the caller trusts herdr's data shape.
|
|
35
|
+
function toPushFrame(line) {
|
|
36
|
+
return line;
|
|
37
|
+
}
|
|
38
|
+
function toUnknownFrame(line, rawEvent) {
|
|
39
|
+
return { event: UNKNOWN_EVENT, rawEvent, raw: line };
|
|
40
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// Role: one request, one answer: opens a fresh connection per call, writes the request line, takes the first matching reply and destroys the socket on every exit.
|
|
2
|
+
// Informs HERDR-ADR-0016 (W1 close after every response, W3 id "" accepted, W2 events carry no id), HERDR-ADR-0004 (Promise core), plan 3.1 and 3.3;
|
|
3
|
+
// settle-once, destroy on every exit, late-open destroyed, AbortSignal, and a per-call timing hook.
|
|
4
|
+
import { CallOutcome, EMPTY_REPLY_ID, ErrorText } from '../../constants.js';
|
|
5
|
+
import { outcomeOf, reportCall } from './codec.js';
|
|
6
|
+
import { Connection } from './connection.js';
|
|
7
|
+
import { HerdrError, HerdrTransportError } from '../errors.js';
|
|
8
|
+
import { encodeRequest, isErrorEnvelope, isObject } from './codec.js';
|
|
9
|
+
import { nextId } from './codec.js';
|
|
10
|
+
const NO_CLEANUP = () => undefined;
|
|
11
|
+
export const rpc = async function rpc(opts, method, params) {
|
|
12
|
+
const startedAt = performance.now();
|
|
13
|
+
try {
|
|
14
|
+
const result = await exchange(opts, method, params);
|
|
15
|
+
reportCall(opts.onCall, { method, durationMs: performance.now() - startedAt, outcome: CallOutcome.Answered });
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
reportCall(opts.onCall, { method, durationMs: performance.now() - startedAt, ...outcomeOf(error) });
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
function exchange(opts, method, params) {
|
|
24
|
+
const requestId = nextId();
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const call = {
|
|
27
|
+
method,
|
|
28
|
+
requestId,
|
|
29
|
+
requestLine: encodeRequest(requestId, method, params),
|
|
30
|
+
socketPath: opts.socketPath,
|
|
31
|
+
resolve,
|
|
32
|
+
reject,
|
|
33
|
+
done: false,
|
|
34
|
+
timer: undefined,
|
|
35
|
+
detachAbort: NO_CLEANUP,
|
|
36
|
+
connection: undefined,
|
|
37
|
+
};
|
|
38
|
+
armAbort(call, opts.signal);
|
|
39
|
+
if (call.done) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
armTimeout(call, opts.timeoutMs);
|
|
43
|
+
openAndWrite(call).catch((error) => {
|
|
44
|
+
failWith(call, error);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// An already-aborted signal settles the call before any connection is opened.
|
|
49
|
+
function armAbort(call, signal) {
|
|
50
|
+
if (signal === undefined) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const onAbort = () => {
|
|
54
|
+
failWith(call, new HerdrTransportError(ErrorText.Aborted(call.method)));
|
|
55
|
+
};
|
|
56
|
+
if (signal.aborted) {
|
|
57
|
+
onAbort();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
61
|
+
call.detachAbort = () => {
|
|
62
|
+
signal.removeEventListener('abort', onAbort);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function armTimeout(call, timeoutMs) {
|
|
66
|
+
if (timeoutMs === undefined) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
call.timer = setTimeout(() => {
|
|
70
|
+
failWith(call, new HerdrTransportError(ErrorText.NoResponse(call.method, timeoutMs), { isTimeout: true }));
|
|
71
|
+
}, timeoutMs);
|
|
72
|
+
}
|
|
73
|
+
async function openAndWrite(call) {
|
|
74
|
+
const opened = await Connection.open(call.socketPath, {
|
|
75
|
+
onLine: (line) => {
|
|
76
|
+
handleLine(call, line);
|
|
77
|
+
},
|
|
78
|
+
onClose: () => {
|
|
79
|
+
failWith(call, new HerdrTransportError(ErrorText.ClosedBeforeResponse(call.method)));
|
|
80
|
+
},
|
|
81
|
+
onError: (error) => {
|
|
82
|
+
failWith(call, new HerdrTransportError(ErrorText.SocketError(call.method), { cause: error }));
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
if (call.done) {
|
|
86
|
+
// The call settled while the socket was connecting (timeout, abort): nothing is written, the socket is closed.
|
|
87
|
+
opened.destroy();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
call.connection = opened;
|
|
91
|
+
opened.writeLine(call.requestLine);
|
|
92
|
+
}
|
|
93
|
+
// Reads one line: a malformed line fails the call, a line for another id is a stray and is ignored.
|
|
94
|
+
function handleLine(call, line) {
|
|
95
|
+
let parsed;
|
|
96
|
+
try {
|
|
97
|
+
parsed = JSON.parse(line);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
failWith(call, new HerdrTransportError(ErrorText.Unparseable(call.method), { cause: error }));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (!isObject(parsed)) {
|
|
104
|
+
failWith(call, new HerdrTransportError(ErrorText.Unparseable(call.method)));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const envelope = parsed;
|
|
108
|
+
if (!isAnswerTo(call, envelope)) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (isErrorEnvelope(envelope)) {
|
|
112
|
+
failWith(call, HerdrError.from(call.method, envelope.error));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
answerWith(call, envelope.result);
|
|
116
|
+
}
|
|
117
|
+
// The reply carries the request id, or the empty id herdr uses for an unparseable request (W3).
|
|
118
|
+
function isAnswerTo(call, envelope) {
|
|
119
|
+
return envelope.id === call.requestId || envelope.id === EMPTY_REPLY_ID;
|
|
120
|
+
}
|
|
121
|
+
// The first exit wins: clears the timer and the abort listener, runs the outcome, then destroys the socket.
|
|
122
|
+
function settle(call, outcome) {
|
|
123
|
+
if (call.done) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
call.done = true;
|
|
127
|
+
clearTimeout(call.timer);
|
|
128
|
+
call.detachAbort();
|
|
129
|
+
outcome();
|
|
130
|
+
call.connection?.destroy();
|
|
131
|
+
}
|
|
132
|
+
function failWith(call, error) {
|
|
133
|
+
settle(call, () => {
|
|
134
|
+
call.reject(error);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function answerWith(call, result) {
|
|
138
|
+
settle(call, () => {
|
|
139
|
+
call.resolve(result);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type EnvMap = Readonly<Record<string, string | undefined>>;
|
|
2
|
+
export interface SocketPathOptions {
|
|
3
|
+
socketPath?: string | undefined;
|
|
4
|
+
env?: EnvMap | undefined;
|
|
5
|
+
}
|
|
6
|
+
export declare function defaultSocketPath(env?: EnvMap): string;
|
|
7
|
+
export declare function resolveSocketPath(options: SocketPathOptions): string;
|
|
8
|
+
export declare function assertSocketExists(path: string): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Role: finds the herdr socket: an explicit option, then HERDR_SOCKET, then ~/.config/herdr/herdr.sock; checks that the path is a socket.
|
|
2
|
+
// Informs HERDR-ADR-0003 (layers) and plan 3.3 (socketPath option); explicit option and an existence check.
|
|
3
|
+
import { statSync } from 'node:fs';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { ErrorText, HerdrEnv, SocketPathPart } from '../../constants.js';
|
|
7
|
+
import { HerdrTransportError } from '../errors.js';
|
|
8
|
+
// The socket path when no explicit option is given. The env is passed in, so tests never read process.env.
|
|
9
|
+
export function defaultSocketPath(env = process.env) {
|
|
10
|
+
return (env[HerdrEnv.Socket] ??
|
|
11
|
+
join(env[HerdrEnv.Home] ?? homedir(), SocketPathPart.ConfigDir, SocketPathPart.HerdrDir, SocketPathPart.SocketFile));
|
|
12
|
+
}
|
|
13
|
+
// An explicit socketPath option wins over the environment and the default.
|
|
14
|
+
export function resolveSocketPath(options) {
|
|
15
|
+
return options.socketPath ?? defaultSocketPath(options.env);
|
|
16
|
+
}
|
|
17
|
+
// Throws a transport error when nothing is a socket at the path (missing path, regular file, directory).
|
|
18
|
+
export function assertSocketExists(path) {
|
|
19
|
+
const stats = statSync(path, { throwIfNoEntry: false });
|
|
20
|
+
if (stats?.isSocket() !== true) {
|
|
21
|
+
throw new HerdrTransportError(ErrorText.NoSocket(path));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { CallOutcome, UNKNOWN_EVENT } from '../../constants.js';
|
|
2
|
+
import type { Method, PushFrame } from '../generated/index.js';
|
|
3
|
+
import type { ParamsOf, ResultOf } from './codec.js';
|
|
4
|
+
export type { ParamsOf, ResultOf } from './codec.js';
|
|
5
|
+
/** One finished call, reported to the onCall hook (plan 3.3). */
|
|
6
|
+
export interface CallEvent {
|
|
7
|
+
readonly method: Method;
|
|
8
|
+
readonly durationMs: number;
|
|
9
|
+
readonly outcome: CallOutcome;
|
|
10
|
+
/** The server's error code when outcome is Refused. */
|
|
11
|
+
readonly code?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Timing hook. A hook that throws never changes the call's result (wire/call-hook.ts reportCall). */
|
|
14
|
+
export type OnCall = (event: CallEvent) => void;
|
|
15
|
+
/** Options of one per-request call. */
|
|
16
|
+
export interface RpcOptions {
|
|
17
|
+
readonly socketPath: string;
|
|
18
|
+
/** No timeout when undefined. Long-poll callers pass timeout_ms + Timeout.LongPollMarginMs (plan 3.6). */
|
|
19
|
+
readonly timeoutMs?: number | undefined;
|
|
20
|
+
/** Abort destroys the connection and rejects with HerdrTransportError. */
|
|
21
|
+
readonly signal?: AbortSignal | undefined;
|
|
22
|
+
readonly onCall?: OnCall | undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* One request on a fresh connection, destroyed on every exit path (W1). The reply is the first line whose id is the
|
|
26
|
+
* request id or "" (W3). Rejects with HerdrError (server envelope) or HerdrTransportError (connect, timeout, abort,
|
|
27
|
+
* malformed line, close before a reply). Implemented by wire/rpc.ts (P2a).
|
|
28
|
+
*/
|
|
29
|
+
export type Rpc = <M extends Method>(opts: RpcOptions, method: M, params: ParamsOf<M>) => Promise<ResultOf<M>>;
|
|
30
|
+
/** A push line whose `event` this library does not know: surfaced, never dropped, coerced or thrown (HERDR-ADR-0016 P3). */
|
|
31
|
+
export interface UnknownFrame {
|
|
32
|
+
readonly event: typeof UNKNOWN_EVENT;
|
|
33
|
+
/** The `event` value herdr sent. */
|
|
34
|
+
readonly rawEvent: string;
|
|
35
|
+
/** The whole parsed line. */
|
|
36
|
+
readonly raw: object;
|
|
37
|
+
}
|
|
38
|
+
/** What a subscription yields: a known frame or an UnknownFrame. */
|
|
39
|
+
export type DecodedFrame = PushFrame | UnknownFrame;
|
|
40
|
+
/**
|
|
41
|
+
* Turns one parsed push line (an object without `id`) into a frame. Validates the envelope only (P4): `event` must be a
|
|
42
|
+
* string and `data` present; an unknown `event` gives UnknownFrame. Returns undefined for a line that is not a push
|
|
43
|
+
* frame shape (the caller fails the subscription with HerdrTransportError). Implemented by wire/push-decoder.ts (P4a).
|
|
44
|
+
*/
|
|
45
|
+
export type DecodePush = (line: object) => DecodedFrame | undefined;
|
|
46
|
+
/** Options of a dedicated connection. */
|
|
47
|
+
export interface DedicatedOptions {
|
|
48
|
+
readonly socketPath: string;
|
|
49
|
+
readonly signal?: AbortSignal | undefined;
|
|
50
|
+
readonly onCall?: OnCall | undefined;
|
|
51
|
+
}
|
|
52
|
+
/** Per-request options on a dedicated connection. */
|
|
53
|
+
export interface DedicatedRequestOptions {
|
|
54
|
+
readonly timeoutMs?: number | undefined;
|
|
55
|
+
readonly signal?: AbortSignal | undefined;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* One connection kept open on purpose: by a subscription (W2: ack, then a held stream) or by hold() for class C
|
|
59
|
+
* methods. Requests are sent one at a time (no pipelining, W1); a line with an id answers the pending request, a line
|
|
60
|
+
* without id is a push (W2). Implemented by wire/dedicated.ts (P4a); consumed by client/subscribe (P4a) and client/held (P4b).
|
|
61
|
+
*/
|
|
62
|
+
export interface DedicatedConnection {
|
|
63
|
+
/** Sends one request and waits for the line with its id (or ""). Rejects if another request is still pending. */
|
|
64
|
+
request<M extends Method>(method: M, params: ParamsOf<M>, options?: DedicatedRequestOptions): Promise<ResultOf<M>>;
|
|
65
|
+
/** Every line without an id, parsed, in arrival order. Set once, before the first request. */
|
|
66
|
+
onPush(listener: (line: object) => void): void;
|
|
67
|
+
/** Resolves when the connection closes for any reason; the value says whether the server closed it. */
|
|
68
|
+
readonly ended: Promise<DedicatedEnd>;
|
|
69
|
+
/** Destroys the socket. Idempotent. */
|
|
70
|
+
destroy(): void;
|
|
71
|
+
}
|
|
72
|
+
/** Why a dedicated connection ended. `byServer` false means destroy() or abort. */
|
|
73
|
+
export interface DedicatedEnd {
|
|
74
|
+
readonly byServer: boolean;
|
|
75
|
+
readonly cause?: unknown;
|
|
76
|
+
}
|
|
77
|
+
/** Opens a dedicated connection; rejects with HerdrTransportError when nothing listens at the path. */
|
|
78
|
+
export type OpenDedicated = (options: DedicatedOptions) => Promise<DedicatedConnection>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { CallOutcome, Overflow, ProtocolPolicy, UNKNOWN_EVENT, WatchKind, PaneSetKind } from './constants.js';
|
|
2
|
+
export { AgentStatus, EventKind, Method, PROTOCOL, ResultTag, SCHEMA_VERSION, ServerCapability, SubscriptionType, } from './herdr/generated/index.js';
|
|
3
|
+
export type { ErrorBody, PushFrame, ResultByTag, Subscription } from './herdr/generated/index.js';
|
|
4
|
+
export { connect } from './herdr/client/connect.js';
|
|
5
|
+
export { watchPaneSet } from './herdr/client/watch-pane-set.js';
|
|
6
|
+
export type { CallOptions, Client, ClientCapabilities, ConnectOptions, ServerInfo, } from './herdr/client/types.js';
|
|
7
|
+
export type { EventSubscription, QueueOptions, Subscribe, SubscribeOptions } from './herdr/client/subscribe.js';
|
|
8
|
+
export type { BackoffPolicy, PaneSetChange, PaneSetSource, PaneSetWatch, Sleep, Watch, WatchChange, WatchFn, WatchOptions, WatchPaneSetOptions, } from './herdr/client/watch.js';
|
|
9
|
+
export type { Hold, HeldConnection, HoldOptions } from './herdr/client/held.js';
|
|
10
|
+
export { HerdrError, HerdrTransportError, ProtocolMismatchError, SubscriptionEnded, UnsupportedByServerError, } from './herdr/errors.js';
|
|
11
|
+
export type { CallEvent, DecodedFrame, OnCall, UnknownFrame } from './herdr/wire/types.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Role: the package entry ("."): connect(), errors, generated constants and types, the client and stream types.
|
|
2
|
+
// Informs plan 3.1, 3.3 and 3.6, HERDR-ADR-0003 (entry points) and HERDR-ADR-0017 (contracts); edited only by the integration step.
|
|
3
|
+
export { CallOutcome, Overflow, ProtocolPolicy, UNKNOWN_EVENT, WatchKind, PaneSetKind } from './constants.js';
|
|
4
|
+
export { AgentStatus, EventKind, Method, PROTOCOL, ResultTag, SCHEMA_VERSION, ServerCapability, SubscriptionType, } from './herdr/generated/index.js';
|
|
5
|
+
export { connect } from './herdr/client/connect.js';
|
|
6
|
+
export { watchPaneSet } from './herdr/client/watch-pane-set.js';
|
|
7
|
+
export { HerdrError, HerdrTransportError, ProtocolMismatchError, SubscriptionEnded, UnsupportedByServerError, } from './herdr/errors.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { connectReadOnly } from './herdr/client/scoped.js';
|
|
2
|
+
export { connectPrompt } from './herdr/client/scoped.js';
|
|
3
|
+
export { Presets, WatchKind } from './constants.js';
|
|
4
|
+
export { Method, PRESET_METHODS, SubscriptionType, EventKind, AgentStatus } from './herdr/generated/index.js';
|
|
5
|
+
export type { PromptClient, ReadOnlyClient, ReadOnlyContentClient, ReadOnlyOptions, PresetOptions, SessionsReaderClient, } from './herdr/client/types.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Role: the /read-only entry: connectReadOnly(), connectPrompt(), Presets, and the read-only client types.
|
|
2
|
+
// Informs HERDR-ADR-0003, HERDR-ADR-0005 and HERDR-ADR-0017; edited only by the integration step.
|
|
3
|
+
export { connectReadOnly } from './herdr/client/scoped.js';
|
|
4
|
+
export { connectPrompt } from './herdr/client/scoped.js';
|
|
5
|
+
export { Presets, WatchKind } from './constants.js';
|
|
6
|
+
export { Method, PRESET_METHODS, SubscriptionType, EventKind, AgentStatus } from './herdr/generated/index.js';
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { METHODS } from './herdr/generated/method-table.js';
|
|
2
|
+
export { ENTRY_METHODS } from './herdr/generated/entry-methods.js';
|
|
3
|
+
export { JsonKind, PARAMS_SHAPE } from './herdr/generated/test-data/shapes.js';
|
|
4
|
+
export type { FieldShape, ParamsShape } from './herdr/generated/test-data/shapes.js';
|
|
5
|
+
export { CapabilityClass } from './herdr/generated/names/capability-class.js';
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Role: the /schema entry: the method table and parameter shapes of the generated API, read as data by tools outside the SDK.
|
|
2
|
+
// Each export is named straight from its generated module, so a bundler keeps only what a consumer imports. Nothing else imports this entry.
|
|
3
|
+
export { METHODS } from './herdr/generated/method-table.js';
|
|
4
|
+
export { ENTRY_METHODS } from './herdr/generated/entry-methods.js';
|
|
5
|
+
export { JsonKind, PARAMS_SHAPE } from './herdr/generated/test-data/shapes.js';
|
|
6
|
+
export { CapabilityClass } from './herdr/generated/names/capability-class.js';
|