@kadi.build/core 0.0.1-alpha.1 → 0.0.1-alpha.11
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 +361 -230
- package/dist/abilities/AbilityCache.d.ts +242 -0
- package/dist/abilities/AbilityCache.d.ts.map +1 -0
- package/dist/abilities/AbilityCache.js +285 -0
- package/dist/abilities/AbilityCache.js.map +1 -0
- package/dist/abilities/AbilityContext.d.ts +215 -0
- package/dist/abilities/AbilityContext.d.ts.map +1 -0
- package/dist/abilities/AbilityContext.js +36 -0
- package/dist/abilities/AbilityContext.js.map +1 -0
- package/dist/abilities/AbilityLoader.d.ts +203 -0
- package/dist/abilities/AbilityLoader.d.ts.map +1 -0
- package/dist/abilities/AbilityLoader.js +343 -0
- package/dist/abilities/AbilityLoader.js.map +1 -0
- package/dist/abilities/AbilityProxy.d.ts +496 -0
- package/dist/abilities/AbilityProxy.d.ts.map +1 -0
- package/dist/abilities/AbilityProxy.js +551 -0
- package/dist/abilities/AbilityProxy.js.map +1 -0
- package/dist/abilities/AbilityValidator.d.ts +172 -0
- package/dist/abilities/AbilityValidator.d.ts.map +1 -0
- package/dist/abilities/AbilityValidator.js +253 -0
- package/dist/abilities/AbilityValidator.js.map +1 -0
- package/dist/abilities/index.d.ts +26 -0
- package/dist/abilities/index.d.ts.map +1 -0
- package/dist/abilities/index.js +23 -0
- package/dist/abilities/index.js.map +1 -0
- package/dist/abilities/types.d.ts +223 -0
- package/dist/abilities/types.d.ts.map +1 -0
- package/dist/abilities/types.js +10 -0
- package/dist/abilities/types.js.map +1 -0
- package/dist/api/index.d.ts +92 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +124 -0
- package/dist/api/index.js.map +1 -0
- package/dist/broker/BrokerConnection.d.ts +253 -0
- package/dist/broker/BrokerConnection.d.ts.map +1 -0
- package/dist/broker/BrokerConnection.js +434 -0
- package/dist/broker/BrokerConnection.js.map +1 -0
- package/dist/broker/BrokerConnectionManager.d.ts +216 -0
- package/dist/broker/BrokerConnectionManager.d.ts.map +1 -0
- package/dist/broker/BrokerConnectionManager.js +305 -0
- package/dist/broker/BrokerConnectionManager.js.map +1 -0
- package/dist/broker/BrokerProtocol.d.ts +280 -0
- package/dist/broker/BrokerProtocol.d.ts.map +1 -0
- package/dist/broker/BrokerProtocol.js +466 -0
- package/dist/broker/BrokerProtocol.js.map +1 -0
- package/dist/broker/index.d.ts +9 -0
- package/dist/broker/index.d.ts.map +1 -0
- package/dist/broker/index.js +9 -0
- package/dist/broker/index.js.map +1 -0
- package/dist/client/KadiClient.d.ts +459 -0
- package/dist/client/KadiClient.d.ts.map +1 -0
- package/dist/client/KadiClient.js +902 -0
- package/dist/client/KadiClient.js.map +1 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +138 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +226 -0
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/config/ConfigResolver.d.ts +135 -0
- package/dist/config/ConfigResolver.d.ts.map +1 -0
- package/dist/config/ConfigResolver.js +282 -0
- package/dist/config/ConfigResolver.js.map +1 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/index.js.map +1 -0
- package/dist/errors/index.d.ts +9 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +8 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/events/EventHub.d.ts +172 -0
- package/dist/events/EventHub.d.ts.map +1 -0
- package/dist/events/EventHub.js +333 -0
- package/dist/events/EventHub.js.map +1 -0
- package/dist/events/index.d.ts +7 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +7 -0
- package/dist/events/index.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/dist/messages/index.d.ts +33 -0
- package/dist/messages/index.d.ts.map +1 -0
- package/dist/messages/index.js +33 -0
- package/dist/messages/index.js.map +1 -0
- package/dist/schemas/index.d.ts +22 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +27 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/kadi-extensions.d.ts +231 -0
- package/dist/schemas/kadi-extensions.d.ts.map +1 -0
- package/dist/schemas/kadi-extensions.js +14 -0
- package/dist/schemas/kadi-extensions.js.map +1 -0
- package/dist/schemas/mcp/schema.d.ts +1399 -0
- package/dist/schemas/mcp/schema.d.ts.map +1 -0
- package/dist/schemas/mcp/schema.js +53 -0
- package/dist/schemas/mcp/schema.js.map +1 -0
- package/dist/schemas/mcp/version.d.ts +37 -0
- package/dist/schemas/mcp/version.d.ts.map +1 -0
- package/dist/schemas/mcp/version.js +39 -0
- package/dist/schemas/mcp/version.js.map +1 -0
- package/dist/schemas/schema-builders.d.ts +178 -0
- package/dist/schemas/schema-builders.d.ts.map +1 -0
- package/dist/schemas/schema-builders.js +258 -0
- package/dist/schemas/schema-builders.js.map +1 -0
- package/dist/schemas/zod-helpers.d.ts +129 -0
- package/dist/schemas/zod-helpers.d.ts.map +1 -0
- package/dist/schemas/zod-helpers.js +225 -0
- package/dist/schemas/zod-helpers.js.map +1 -0
- package/dist/schemas/zod-to-json-schema.d.ts +159 -0
- package/dist/schemas/zod-to-json-schema.d.ts.map +1 -0
- package/dist/schemas/zod-to-json-schema.js +154 -0
- package/dist/schemas/zod-to-json-schema.js.map +1 -0
- package/dist/tools/ToolRegistry.d.ts +256 -0
- package/dist/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/tools/ToolRegistry.js +340 -0
- package/dist/tools/ToolRegistry.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/transports/BrokerTransport.d.ts +151 -0
- package/dist/transports/BrokerTransport.d.ts.map +1 -0
- package/dist/transports/BrokerTransport.js +261 -0
- package/dist/transports/BrokerTransport.js.map +1 -0
- package/dist/transports/NativeTransport.d.ts +178 -0
- package/dist/transports/NativeTransport.d.ts.map +1 -0
- package/dist/transports/NativeTransport.js +397 -0
- package/dist/transports/NativeTransport.js.map +1 -0
- package/dist/transports/StdioTransport.d.ts +250 -0
- package/dist/transports/StdioTransport.d.ts.map +1 -0
- package/dist/transports/StdioTransport.js +487 -0
- package/dist/transports/StdioTransport.js.map +1 -0
- package/dist/transports/index.d.ts +10 -0
- package/dist/transports/index.d.ts.map +1 -0
- package/dist/transports/index.js +9 -0
- package/dist/transports/index.js.map +1 -0
- package/dist/types/broker.d.ts +279 -0
- package/dist/types/broker.d.ts.map +1 -0
- package/dist/types/broker.js +19 -0
- package/dist/types/broker.js.map +1 -0
- package/dist/types/config.d.ts +325 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +17 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/errors.d.ts +178 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +165 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/events.d.ts +210 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +8 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +34 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/protocol.d.ts +48 -0
- package/dist/types/protocol.d.ts.map +1 -0
- package/dist/types/protocol.js +11 -0
- package/dist/types/protocol.js.map +1 -0
- package/dist/types/tools.d.ts +67 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +16 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/transport.d.ts +250 -0
- package/dist/types/transport.d.ts.map +1 -0
- package/dist/types/transport.js +18 -0
- package/dist/types/transport.js.map +1 -0
- package/dist/types/zod-tools.d.ts +198 -0
- package/dist/types/zod-tools.d.ts.map +1 -0
- package/dist/types/zod-tools.js +14 -0
- package/dist/types/zod-tools.js.map +1 -0
- package/dist/utils/StdioMessageReader.d.ts +122 -0
- package/dist/utils/StdioMessageReader.d.ts.map +1 -0
- package/dist/utils/StdioMessageReader.js +209 -0
- package/dist/utils/StdioMessageReader.js.map +1 -0
- package/dist/utils/StdioMessageWriter.d.ts +104 -0
- package/dist/utils/StdioMessageWriter.d.ts.map +1 -0
- package/dist/utils/StdioMessageWriter.js +162 -0
- package/dist/utils/StdioMessageWriter.js.map +1 -0
- package/dist/validation/SchemaValidator.d.ts +208 -0
- package/dist/validation/SchemaValidator.d.ts.map +1 -0
- package/dist/validation/SchemaValidator.js +411 -0
- package/dist/validation/SchemaValidator.js.map +1 -0
- package/dist/validation/index.d.ts +11 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +10 -0
- package/dist/validation/index.js.map +1 -0
- package/package.json +70 -5
- package/agent.json +0 -18
- package/broker.js +0 -214
- package/index.js +0 -370
- package/ipc.js +0 -220
- package/ipcInterfaces/pythonAbilityIPC.py +0 -177
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio Message Reader
|
|
3
|
+
*
|
|
4
|
+
* Reads Content-Length framed messages from a stream (LSP-style).
|
|
5
|
+
* Handles partial messages across multiple chunks and ignores non-framed output.
|
|
6
|
+
*
|
|
7
|
+
* Message format:
|
|
8
|
+
* ```
|
|
9
|
+
* Content-Length: 67\r\n
|
|
10
|
+
* \r\n
|
|
11
|
+
* {"jsonrpc":"2.0","id":1,"method":"invoke","params":{...}}
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @module utils/StdioMessageReader
|
|
15
|
+
*/
|
|
16
|
+
import { EventEmitter } from 'events';
|
|
17
|
+
/**
|
|
18
|
+
* Message reader for Content-Length framed messages
|
|
19
|
+
*
|
|
20
|
+
* Implements the LSP (Language Server Protocol) message framing format.
|
|
21
|
+
* This allows reliable JSON-RPC communication over stdio even when the
|
|
22
|
+
* ability writes logs or debug output to stdout.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const reader = new StdioMessageReader();
|
|
27
|
+
*
|
|
28
|
+
* reader.on('message', (message) => {
|
|
29
|
+
* console.log('Received:', message);
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* reader.on('error', (error) => {
|
|
33
|
+
* console.error('Parse error:', error);
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Feed data chunks
|
|
37
|
+
* process.stdout.on('data', (chunk) => {
|
|
38
|
+
* reader.onData(chunk);
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare class StdioMessageReader extends EventEmitter {
|
|
43
|
+
/**
|
|
44
|
+
* Buffer for accumulating incoming data
|
|
45
|
+
*/
|
|
46
|
+
private buffer;
|
|
47
|
+
/**
|
|
48
|
+
* Whether the reader has been destroyed
|
|
49
|
+
*/
|
|
50
|
+
private destroyed;
|
|
51
|
+
/**
|
|
52
|
+
* Header end marker
|
|
53
|
+
*/
|
|
54
|
+
private static readonly HEADER_END;
|
|
55
|
+
/**
|
|
56
|
+
* Content-Length header regex
|
|
57
|
+
* Note: No multiline flag - header must be clean (no garbage before it)
|
|
58
|
+
*/
|
|
59
|
+
private static readonly CONTENT_LENGTH_PATTERN;
|
|
60
|
+
/**
|
|
61
|
+
* Process incoming data chunk
|
|
62
|
+
*
|
|
63
|
+
* Appends chunk to buffer and attempts to parse complete messages.
|
|
64
|
+
* May emit multiple 'message' events if buffer contains multiple messages.
|
|
65
|
+
*
|
|
66
|
+
* @param chunk - Incoming data chunk
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* stream.on('data', (chunk) => {
|
|
71
|
+
* reader.onData(chunk);
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
onData(chunk: Buffer): void;
|
|
76
|
+
/**
|
|
77
|
+
* Attempt to read and emit complete messages from buffer
|
|
78
|
+
*
|
|
79
|
+
* Continues reading until no complete message can be extracted.
|
|
80
|
+
* Handles multiple messages in a single buffer.
|
|
81
|
+
*/
|
|
82
|
+
private tryReadMessages;
|
|
83
|
+
/**
|
|
84
|
+
* Attempt to read a single complete message
|
|
85
|
+
*
|
|
86
|
+
* @returns Parsed message object, or null if no complete message available
|
|
87
|
+
* @throws {Error} If header is malformed or JSON is invalid
|
|
88
|
+
*/
|
|
89
|
+
private tryReadSingleMessage;
|
|
90
|
+
/**
|
|
91
|
+
* Skip to next potential header in buffer
|
|
92
|
+
*
|
|
93
|
+
* Used for error recovery when a malformed message is encountered.
|
|
94
|
+
* Searches for the next "Content-Length:" pattern.
|
|
95
|
+
*/
|
|
96
|
+
private skipToNextHeader;
|
|
97
|
+
/**
|
|
98
|
+
* Get current buffer size (for debugging/monitoring)
|
|
99
|
+
*
|
|
100
|
+
* @returns Number of bytes in buffer
|
|
101
|
+
*/
|
|
102
|
+
getBufferSize(): number;
|
|
103
|
+
/**
|
|
104
|
+
* Clear the internal buffer
|
|
105
|
+
*
|
|
106
|
+
* Useful for resetting state after errors or for cleanup.
|
|
107
|
+
*/
|
|
108
|
+
clearBuffer(): void;
|
|
109
|
+
/**
|
|
110
|
+
* Destroy the reader
|
|
111
|
+
*
|
|
112
|
+
* Cleans up resources and prevents further processing.
|
|
113
|
+
*/
|
|
114
|
+
destroy(): void;
|
|
115
|
+
/**
|
|
116
|
+
* Check if reader is destroyed
|
|
117
|
+
*
|
|
118
|
+
* @returns true if destroyed
|
|
119
|
+
*/
|
|
120
|
+
isDestroyed(): boolean;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=StdioMessageReader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StdioMessageReader.d.ts","sourceRoot":"","sources":["../../src/utils/StdioMessageReader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAmB;IAEjC;;OAEG;IACH,OAAO,CAAC,SAAS,CAAS;IAE1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAc;IAEhD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAmC;IAEjF;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAY3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAqBvB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAmD5B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;OAIG;IACH,aAAa,IAAI,MAAM;IAIvB;;;;OAIG;IACH,WAAW,IAAI,IAAI;IAInB;;;;OAIG;IACH,OAAO,IAAI,IAAI;IAMf;;;;OAIG;IACH,WAAW,IAAI,OAAO;CAGvB"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio Message Reader
|
|
3
|
+
*
|
|
4
|
+
* Reads Content-Length framed messages from a stream (LSP-style).
|
|
5
|
+
* Handles partial messages across multiple chunks and ignores non-framed output.
|
|
6
|
+
*
|
|
7
|
+
* Message format:
|
|
8
|
+
* ```
|
|
9
|
+
* Content-Length: 67\r\n
|
|
10
|
+
* \r\n
|
|
11
|
+
* {"jsonrpc":"2.0","id":1,"method":"invoke","params":{...}}
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @module utils/StdioMessageReader
|
|
15
|
+
*/
|
|
16
|
+
import { EventEmitter } from 'events';
|
|
17
|
+
/**
|
|
18
|
+
* Message reader for Content-Length framed messages
|
|
19
|
+
*
|
|
20
|
+
* Implements the LSP (Language Server Protocol) message framing format.
|
|
21
|
+
* This allows reliable JSON-RPC communication over stdio even when the
|
|
22
|
+
* ability writes logs or debug output to stdout.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const reader = new StdioMessageReader();
|
|
27
|
+
*
|
|
28
|
+
* reader.on('message', (message) => {
|
|
29
|
+
* console.log('Received:', message);
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* reader.on('error', (error) => {
|
|
33
|
+
* console.error('Parse error:', error);
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Feed data chunks
|
|
37
|
+
* process.stdout.on('data', (chunk) => {
|
|
38
|
+
* reader.onData(chunk);
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export class StdioMessageReader extends EventEmitter {
|
|
43
|
+
/**
|
|
44
|
+
* Buffer for accumulating incoming data
|
|
45
|
+
*/
|
|
46
|
+
buffer = Buffer.alloc(0);
|
|
47
|
+
/**
|
|
48
|
+
* Whether the reader has been destroyed
|
|
49
|
+
*/
|
|
50
|
+
destroyed = false;
|
|
51
|
+
/**
|
|
52
|
+
* Header end marker
|
|
53
|
+
*/
|
|
54
|
+
static HEADER_END = '\r\n\r\n';
|
|
55
|
+
/**
|
|
56
|
+
* Content-Length header regex
|
|
57
|
+
* Note: No multiline flag - header must be clean (no garbage before it)
|
|
58
|
+
*/
|
|
59
|
+
static CONTENT_LENGTH_PATTERN = /^Content-Length:\s*(\d+)\s*$/i;
|
|
60
|
+
/**
|
|
61
|
+
* Process incoming data chunk
|
|
62
|
+
*
|
|
63
|
+
* Appends chunk to buffer and attempts to parse complete messages.
|
|
64
|
+
* May emit multiple 'message' events if buffer contains multiple messages.
|
|
65
|
+
*
|
|
66
|
+
* @param chunk - Incoming data chunk
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* stream.on('data', (chunk) => {
|
|
71
|
+
* reader.onData(chunk);
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
onData(chunk) {
|
|
76
|
+
if (this.destroyed) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Append to buffer
|
|
80
|
+
this.buffer = Buffer.concat([this.buffer, chunk]);
|
|
81
|
+
// Try to extract messages
|
|
82
|
+
this.tryReadMessages();
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Attempt to read and emit complete messages from buffer
|
|
86
|
+
*
|
|
87
|
+
* Continues reading until no complete message can be extracted.
|
|
88
|
+
* Handles multiple messages in a single buffer.
|
|
89
|
+
*/
|
|
90
|
+
tryReadMessages() {
|
|
91
|
+
while (true) {
|
|
92
|
+
try {
|
|
93
|
+
const message = this.tryReadSingleMessage();
|
|
94
|
+
if (!message) {
|
|
95
|
+
// No complete message available
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
// Emit the message
|
|
99
|
+
this.emit('message', message);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
// Emit error but continue processing
|
|
103
|
+
this.emit('error', error);
|
|
104
|
+
// Try to recover by skipping to next potential header
|
|
105
|
+
this.skipToNextHeader();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Attempt to read a single complete message
|
|
111
|
+
*
|
|
112
|
+
* @returns Parsed message object, or null if no complete message available
|
|
113
|
+
* @throws {Error} If header is malformed or JSON is invalid
|
|
114
|
+
*/
|
|
115
|
+
tryReadSingleMessage() {
|
|
116
|
+
// Look for header end marker
|
|
117
|
+
const headerEndIndex = this.buffer.indexOf(StdioMessageReader.HEADER_END);
|
|
118
|
+
if (headerEndIndex === -1) {
|
|
119
|
+
// No complete header yet
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
// Extract header
|
|
123
|
+
const headerBytes = this.buffer.slice(0, headerEndIndex);
|
|
124
|
+
const header = headerBytes.toString('utf8');
|
|
125
|
+
// Parse Content-Length
|
|
126
|
+
const match = header.match(StdioMessageReader.CONTENT_LENGTH_PATTERN);
|
|
127
|
+
if (!match || !match[1]) {
|
|
128
|
+
throw new Error(`Invalid message header: missing or malformed Content-Length\nHeader: ${header}`);
|
|
129
|
+
}
|
|
130
|
+
const contentLength = parseInt(match[1], 10);
|
|
131
|
+
if (isNaN(contentLength) || contentLength < 0) {
|
|
132
|
+
throw new Error(`Invalid Content-Length value: ${match[1]}`);
|
|
133
|
+
}
|
|
134
|
+
// Check if we have the complete message
|
|
135
|
+
const messageStart = headerEndIndex + StdioMessageReader.HEADER_END.length;
|
|
136
|
+
const messageEnd = messageStart + contentLength;
|
|
137
|
+
if (this.buffer.length < messageEnd) {
|
|
138
|
+
// Need more data - message is incomplete
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
// Extract message bytes
|
|
142
|
+
const messageBytes = this.buffer.slice(messageStart, messageEnd);
|
|
143
|
+
const messageJson = messageBytes.toString('utf8');
|
|
144
|
+
// Parse JSON
|
|
145
|
+
let message;
|
|
146
|
+
try {
|
|
147
|
+
message = JSON.parse(messageJson);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
throw new Error(`Invalid JSON in message body: ${error instanceof Error ? error.message : String(error)}\nJSON: ${messageJson.substring(0, 200)}`);
|
|
151
|
+
}
|
|
152
|
+
// Remove processed data from buffer
|
|
153
|
+
this.buffer = this.buffer.slice(messageEnd);
|
|
154
|
+
return message;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Skip to next potential header in buffer
|
|
158
|
+
*
|
|
159
|
+
* Used for error recovery when a malformed message is encountered.
|
|
160
|
+
* Searches for the next "Content-Length:" pattern.
|
|
161
|
+
*/
|
|
162
|
+
skipToNextHeader() {
|
|
163
|
+
const searchString = this.buffer.toString('utf8');
|
|
164
|
+
const nextHeaderIndex = searchString.indexOf('Content-Length:', 1);
|
|
165
|
+
if (nextHeaderIndex === -1) {
|
|
166
|
+
// No next header found - clear buffer
|
|
167
|
+
this.buffer = Buffer.alloc(0);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
// Skip to next header
|
|
171
|
+
this.buffer = this.buffer.slice(nextHeaderIndex);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get current buffer size (for debugging/monitoring)
|
|
176
|
+
*
|
|
177
|
+
* @returns Number of bytes in buffer
|
|
178
|
+
*/
|
|
179
|
+
getBufferSize() {
|
|
180
|
+
return this.buffer.length;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Clear the internal buffer
|
|
184
|
+
*
|
|
185
|
+
* Useful for resetting state after errors or for cleanup.
|
|
186
|
+
*/
|
|
187
|
+
clearBuffer() {
|
|
188
|
+
this.buffer = Buffer.alloc(0);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Destroy the reader
|
|
192
|
+
*
|
|
193
|
+
* Cleans up resources and prevents further processing.
|
|
194
|
+
*/
|
|
195
|
+
destroy() {
|
|
196
|
+
this.destroyed = true;
|
|
197
|
+
this.buffer = Buffer.alloc(0);
|
|
198
|
+
this.removeAllListeners();
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Check if reader is destroyed
|
|
202
|
+
*
|
|
203
|
+
* @returns true if destroyed
|
|
204
|
+
*/
|
|
205
|
+
isDestroyed() {
|
|
206
|
+
return this.destroyed;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=StdioMessageReader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StdioMessageReader.js","sourceRoot":"","sources":["../../src/utils/StdioMessageReader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio Message Writer
|
|
3
|
+
*
|
|
4
|
+
* Writes Content-Length framed messages to a stream (LSP-style).
|
|
5
|
+
* Ensures reliable message delivery even when other output is written to the stream.
|
|
6
|
+
*
|
|
7
|
+
* Message format:
|
|
8
|
+
* ```
|
|
9
|
+
* Content-Length: 67\r\n
|
|
10
|
+
* \r\n
|
|
11
|
+
* {"jsonrpc":"2.0","id":1,"result":{"value":42}}
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @module utils/StdioMessageWriter
|
|
15
|
+
*/
|
|
16
|
+
import type { Writable } from 'stream';
|
|
17
|
+
/**
|
|
18
|
+
* Message writer for Content-Length framed messages
|
|
19
|
+
*
|
|
20
|
+
* Implements the LSP (Language Server Protocol) message framing format.
|
|
21
|
+
* Automatically calculates content length and formats headers.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const writer = new StdioMessageWriter(process.stdout);
|
|
26
|
+
*
|
|
27
|
+
* // Write a JSON-RPC message
|
|
28
|
+
* await writer.write({
|
|
29
|
+
* jsonrpc: '2.0',
|
|
30
|
+
* id: 1,
|
|
31
|
+
* result: { value: 42 }
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare class StdioMessageWriter {
|
|
36
|
+
/**
|
|
37
|
+
* Output stream
|
|
38
|
+
*/
|
|
39
|
+
private readonly stream;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the writer has been destroyed
|
|
42
|
+
*/
|
|
43
|
+
private destroyed;
|
|
44
|
+
/**
|
|
45
|
+
* Header separator
|
|
46
|
+
*/
|
|
47
|
+
private static readonly HEADER_SEPARATOR;
|
|
48
|
+
/**
|
|
49
|
+
* Create a new message writer
|
|
50
|
+
*
|
|
51
|
+
* @param stream - Output stream (typically stdout)
|
|
52
|
+
*/
|
|
53
|
+
constructor(stream: Writable);
|
|
54
|
+
/**
|
|
55
|
+
* Write a framed message to the stream
|
|
56
|
+
*
|
|
57
|
+
* Serializes the message to JSON, calculates byte length, formats
|
|
58
|
+
* Content-Length header, and writes everything to the stream.
|
|
59
|
+
*
|
|
60
|
+
* @param message - Message object to write (will be JSON-stringified)
|
|
61
|
+
* @returns Promise that resolves when message is fully written
|
|
62
|
+
*
|
|
63
|
+
* @throws {Error} If writer is destroyed or write fails
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* await writer.write({
|
|
68
|
+
* jsonrpc: '2.0',
|
|
69
|
+
* id: 1,
|
|
70
|
+
* method: 'invoke',
|
|
71
|
+
* params: { toolName: 'add', toolInput: { a: 5, b: 3 } }
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
write(message: Record<string, unknown>): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Flush the stream
|
|
78
|
+
*
|
|
79
|
+
* Ensures all buffered data is written to the underlying stream.
|
|
80
|
+
*
|
|
81
|
+
* @returns Promise that resolves when flush is complete
|
|
82
|
+
*/
|
|
83
|
+
flush(): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Destroy the writer
|
|
86
|
+
*
|
|
87
|
+
* Cleans up resources. After calling destroy(), the writer cannot be used.
|
|
88
|
+
* Note: This does NOT close the underlying stream.
|
|
89
|
+
*/
|
|
90
|
+
destroy(): void;
|
|
91
|
+
/**
|
|
92
|
+
* Check if writer is destroyed
|
|
93
|
+
*
|
|
94
|
+
* @returns true if destroyed
|
|
95
|
+
*/
|
|
96
|
+
isDestroyed(): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Get the underlying stream
|
|
99
|
+
*
|
|
100
|
+
* @returns The writable stream
|
|
101
|
+
*/
|
|
102
|
+
getStream(): Writable;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=StdioMessageWriter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StdioMessageWriter.d.ts","sourceRoot":"","sources":["../../src/utils/StdioMessageWriter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,kBAAkB;IAC7B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAElC;;OAEG;IACH,OAAO,CAAC,SAAS,CAAS;IAE1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAElD;;;;OAIG;gBACS,MAAM,EAAE,QAAQ;IAI5B;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqC5D;;;;;;OAMG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB5B;;;;;OAKG;IACH,OAAO,IAAI,IAAI;IAIf;;;;OAIG;IACH,WAAW,IAAI,OAAO;IAItB;;;;OAIG;IACH,SAAS,IAAI,QAAQ;CAGtB"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio Message Writer
|
|
3
|
+
*
|
|
4
|
+
* Writes Content-Length framed messages to a stream (LSP-style).
|
|
5
|
+
* Ensures reliable message delivery even when other output is written to the stream.
|
|
6
|
+
*
|
|
7
|
+
* Message format:
|
|
8
|
+
* ```
|
|
9
|
+
* Content-Length: 67\r\n
|
|
10
|
+
* \r\n
|
|
11
|
+
* {"jsonrpc":"2.0","id":1,"result":{"value":42}}
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @module utils/StdioMessageWriter
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Message writer for Content-Length framed messages
|
|
18
|
+
*
|
|
19
|
+
* Implements the LSP (Language Server Protocol) message framing format.
|
|
20
|
+
* Automatically calculates content length and formats headers.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const writer = new StdioMessageWriter(process.stdout);
|
|
25
|
+
*
|
|
26
|
+
* // Write a JSON-RPC message
|
|
27
|
+
* await writer.write({
|
|
28
|
+
* jsonrpc: '2.0',
|
|
29
|
+
* id: 1,
|
|
30
|
+
* result: { value: 42 }
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export class StdioMessageWriter {
|
|
35
|
+
/**
|
|
36
|
+
* Output stream
|
|
37
|
+
*/
|
|
38
|
+
stream;
|
|
39
|
+
/**
|
|
40
|
+
* Whether the writer has been destroyed
|
|
41
|
+
*/
|
|
42
|
+
destroyed = false;
|
|
43
|
+
/**
|
|
44
|
+
* Header separator
|
|
45
|
+
*/
|
|
46
|
+
static HEADER_SEPARATOR = '\r\n';
|
|
47
|
+
/**
|
|
48
|
+
* Create a new message writer
|
|
49
|
+
*
|
|
50
|
+
* @param stream - Output stream (typically stdout)
|
|
51
|
+
*/
|
|
52
|
+
constructor(stream) {
|
|
53
|
+
this.stream = stream;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Write a framed message to the stream
|
|
57
|
+
*
|
|
58
|
+
* Serializes the message to JSON, calculates byte length, formats
|
|
59
|
+
* Content-Length header, and writes everything to the stream.
|
|
60
|
+
*
|
|
61
|
+
* @param message - Message object to write (will be JSON-stringified)
|
|
62
|
+
* @returns Promise that resolves when message is fully written
|
|
63
|
+
*
|
|
64
|
+
* @throws {Error} If writer is destroyed or write fails
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* await writer.write({
|
|
69
|
+
* jsonrpc: '2.0',
|
|
70
|
+
* id: 1,
|
|
71
|
+
* method: 'invoke',
|
|
72
|
+
* params: { toolName: 'add', toolInput: { a: 5, b: 3 } }
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
async write(message) {
|
|
77
|
+
if (this.destroyed) {
|
|
78
|
+
throw new Error('Cannot write: StdioMessageWriter has been destroyed');
|
|
79
|
+
}
|
|
80
|
+
// Serialize message to JSON
|
|
81
|
+
const messageJson = JSON.stringify(message);
|
|
82
|
+
// Calculate UTF-8 byte length (not character length!)
|
|
83
|
+
const messageBytes = Buffer.from(messageJson, 'utf8');
|
|
84
|
+
const contentLength = messageBytes.length;
|
|
85
|
+
// Format header
|
|
86
|
+
const header = `Content-Length: ${contentLength}${StdioMessageWriter.HEADER_SEPARATOR}${StdioMessageWriter.HEADER_SEPARATOR}`;
|
|
87
|
+
// Write header + message
|
|
88
|
+
const fullMessage = header + messageJson;
|
|
89
|
+
// Write to stream and handle backpressure
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const writeSucceeded = this.stream.write(fullMessage, 'utf8', (error) => {
|
|
92
|
+
if (error) {
|
|
93
|
+
reject(new Error(`Failed to write message: ${error.message}`));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
resolve();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// If write returned false, wait for drain event
|
|
100
|
+
if (!writeSucceeded) {
|
|
101
|
+
this.stream.once('drain', () => {
|
|
102
|
+
resolve();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Flush the stream
|
|
109
|
+
*
|
|
110
|
+
* Ensures all buffered data is written to the underlying stream.
|
|
111
|
+
*
|
|
112
|
+
* @returns Promise that resolves when flush is complete
|
|
113
|
+
*/
|
|
114
|
+
async flush() {
|
|
115
|
+
if (this.destroyed) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
return new Promise((resolve) => {
|
|
119
|
+
// Check if stream has end() method (for proper cleanup)
|
|
120
|
+
if (typeof this.stream.end === 'function') {
|
|
121
|
+
// Don't actually end the stream, just make sure it's flushed
|
|
122
|
+
// We'll use cork/uncork if available
|
|
123
|
+
if (typeof this.stream.uncork === 'function') {
|
|
124
|
+
this.stream.uncork();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Wait for drain if needed
|
|
128
|
+
if (this.stream.writableNeedDrain) {
|
|
129
|
+
this.stream.once('drain', () => resolve());
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
resolve();
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Destroy the writer
|
|
138
|
+
*
|
|
139
|
+
* Cleans up resources. After calling destroy(), the writer cannot be used.
|
|
140
|
+
* Note: This does NOT close the underlying stream.
|
|
141
|
+
*/
|
|
142
|
+
destroy() {
|
|
143
|
+
this.destroyed = true;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Check if writer is destroyed
|
|
147
|
+
*
|
|
148
|
+
* @returns true if destroyed
|
|
149
|
+
*/
|
|
150
|
+
isDestroyed() {
|
|
151
|
+
return this.destroyed;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get the underlying stream
|
|
155
|
+
*
|
|
156
|
+
* @returns The writable stream
|
|
157
|
+
*/
|
|
158
|
+
getStream() {
|
|
159
|
+
return this.stream;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=StdioMessageWriter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StdioMessageWriter.js","sourceRoot":"","sources":["../../src/utils/StdioMessageWriter.ts"],"names":[],"mappings":"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"}
|