@tienne/gestalt 0.108.0 → 0.110.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/CLAUDE.md +1 -0
  2. package/dist/package.json +1 -1
  3. package/dist/src/cli/commands/peer.d.ts +49 -0
  4. package/dist/src/cli/commands/peer.d.ts.map +1 -0
  5. package/dist/src/cli/commands/peer.js +302 -0
  6. package/dist/src/cli/commands/peer.js.map +1 -0
  7. package/dist/src/cli/index.d.ts.map +1 -1
  8. package/dist/src/cli/index.js +81 -2
  9. package/dist/src/cli/index.js.map +1 -1
  10. package/dist/src/peer/client.d.ts +9 -0
  11. package/dist/src/peer/client.d.ts.map +1 -0
  12. package/dist/src/peer/client.js +51 -0
  13. package/dist/src/peer/client.js.map +1 -0
  14. package/dist/src/peer/daemon.d.ts +83 -0
  15. package/dist/src/peer/daemon.d.ts.map +1 -0
  16. package/dist/src/peer/daemon.js +516 -0
  17. package/dist/src/peer/daemon.js.map +1 -0
  18. package/dist/src/peer/errors.d.ts +2 -0
  19. package/dist/src/peer/errors.d.ts.map +1 -0
  20. package/dist/src/peer/errors.js +4 -0
  21. package/dist/src/peer/errors.js.map +1 -0
  22. package/dist/src/peer/feed.d.ts +103 -0
  23. package/dist/src/peer/feed.d.ts.map +1 -0
  24. package/dist/src/peer/feed.js +167 -0
  25. package/dist/src/peer/feed.js.map +1 -0
  26. package/dist/src/peer/index.d.ts +24 -0
  27. package/dist/src/peer/index.d.ts.map +1 -0
  28. package/dist/src/peer/index.js +14 -0
  29. package/dist/src/peer/index.js.map +1 -0
  30. package/dist/src/peer/keys.d.ts +26 -0
  31. package/dist/src/peer/keys.d.ts.map +1 -0
  32. package/dist/src/peer/keys.js +95 -0
  33. package/dist/src/peer/keys.js.map +1 -0
  34. package/dist/src/peer/locate.d.ts +44 -0
  35. package/dist/src/peer/locate.d.ts.map +1 -0
  36. package/dist/src/peer/locate.js +116 -0
  37. package/dist/src/peer/locate.js.map +1 -0
  38. package/dist/src/peer/lock.d.ts +32 -0
  39. package/dist/src/peer/lock.d.ts.map +1 -0
  40. package/dist/src/peer/lock.js +147 -0
  41. package/dist/src/peer/lock.js.map +1 -0
  42. package/dist/src/peer/mirror.d.ts +21 -0
  43. package/dist/src/peer/mirror.d.ts.map +1 -0
  44. package/dist/src/peer/mirror.js +68 -0
  45. package/dist/src/peer/mirror.js.map +1 -0
  46. package/dist/src/peer/network.d.ts +148 -0
  47. package/dist/src/peer/network.d.ts.map +1 -0
  48. package/dist/src/peer/network.js +809 -0
  49. package/dist/src/peer/network.js.map +1 -0
  50. package/dist/src/peer/paths.d.ts +23 -0
  51. package/dist/src/peer/paths.d.ts.map +1 -0
  52. package/dist/src/peer/paths.js +50 -0
  53. package/dist/src/peer/paths.js.map +1 -0
  54. package/dist/src/peer/protocol.d.ts +112 -0
  55. package/dist/src/peer/protocol.d.ts.map +1 -0
  56. package/dist/src/peer/protocol.js +8 -0
  57. package/dist/src/peer/protocol.js.map +1 -0
  58. package/dist/src/peer/redact.d.ts +30 -0
  59. package/dist/src/peer/redact.d.ts.map +1 -0
  60. package/dist/src/peer/redact.js +214 -0
  61. package/dist/src/peer/redact.js.map +1 -0
  62. package/dist/src/peer/relay.d.ts +70 -0
  63. package/dist/src/peer/relay.d.ts.map +1 -0
  64. package/dist/src/peer/relay.js +410 -0
  65. package/dist/src/peer/relay.js.map +1 -0
  66. package/dist/src/peer/roster.d.ts +89 -0
  67. package/dist/src/peer/roster.d.ts.map +1 -0
  68. package/dist/src/peer/roster.js +160 -0
  69. package/dist/src/peer/roster.js.map +1 -0
  70. package/dist/src/peer/seal.d.ts +37 -0
  71. package/dist/src/peer/seal.d.ts.map +1 -0
  72. package/dist/src/peer/seal.js +115 -0
  73. package/dist/src/peer/seal.js.map +1 -0
  74. package/dist/src/peer/share.d.ts +41 -0
  75. package/dist/src/peer/share.d.ts.map +1 -0
  76. package/dist/src/peer/share.js +70 -0
  77. package/dist/src/peer/share.js.map +1 -0
  78. package/dist/src/peer/state.d.ts +68 -0
  79. package/dist/src/peer/state.d.ts.map +1 -0
  80. package/dist/src/peer/state.js +161 -0
  81. package/dist/src/peer/state.js.map +1 -0
  82. package/dist/src/peer/tail.d.ts +55 -0
  83. package/dist/src/peer/tail.d.ts.map +1 -0
  84. package/dist/src/peer/tail.js +148 -0
  85. package/dist/src/peer/tail.js.map +1 -0
  86. package/dist/src/peer/transform.d.ts +79 -0
  87. package/dist/src/peer/transform.d.ts.map +1 -0
  88. package/dist/src/peer/transform.js +237 -0
  89. package/dist/src/peer/transform.js.map +1 -0
  90. package/dist/src/peer/transport.d.ts +89 -0
  91. package/dist/src/peer/transport.d.ts.map +1 -0
  92. package/dist/src/peer/transport.js +345 -0
  93. package/dist/src/peer/transport.js.map +1 -0
  94. package/dist/src/peer/viewer-html.d.ts +10 -0
  95. package/dist/src/peer/viewer-html.d.ts.map +1 -0
  96. package/dist/src/peer/viewer-html.js +165 -0
  97. package/dist/src/peer/viewer-html.js.map +1 -0
  98. package/dist/src/peer/viewer.d.ts +58 -0
  99. package/dist/src/peer/viewer.d.ts.map +1 -0
  100. package/dist/src/peer/viewer.js +249 -0
  101. package/dist/src/peer/viewer.js.map +1 -0
  102. package/dist/src/peer/wire.d.ts +90 -0
  103. package/dist/src/peer/wire.d.ts.map +1 -0
  104. package/dist/src/peer/wire.js +10 -0
  105. package/dist/src/peer/wire.js.map +1 -0
  106. package/dist/src/peer/ws.d.ts +47 -0
  107. package/dist/src/peer/ws.d.ts.map +1 -0
  108. package/dist/src/peer/ws.js +308 -0
  109. package/dist/src/peer/ws.js.map +1 -0
  110. package/package.json +1 -1
  111. package/plugin/.codex-plugin/plugin.json +1 -1
  112. package/plugin/.mcp.json +1 -1
  113. package/plugin/mcp.json +1 -1
@@ -0,0 +1,308 @@
1
+ import { createHash, randomBytes } from 'node:crypto';
2
+ import { EventEmitter } from 'node:events';
3
+ import { request as httpRequest } from 'node:http';
4
+ import { request as httpsRequest } from 'node:https';
5
+ /**
6
+ * 릴레이와 데몬이 쓰는 최소 WebSocket(RFC 6455). 글자 메시지만 주고받는다.
7
+ *
8
+ * 의존성을 더하지 않으려고 직접 짰다. Node 22에 클라이언트(`WebSocket` 전역)는 있지만
9
+ * 서버가 없어서 프레임 해석을 어차피 짜야 하고 양쪽이 같은 코드를 쓰면 밀린 양을
10
+ * `socket.writableLength`로 똑같이 잴 수 있다.
11
+ */
12
+ const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
13
+ /** 메시지 하나의 상한. 넘으면 1009로 닫는다 */
14
+ export const DEFAULT_MAX_MESSAGE_BYTES = 4 * 1024 * 1024;
15
+ const OP_CONT = 0x0;
16
+ const OP_TEXT = 0x1;
17
+ const OP_BINARY = 0x2;
18
+ const OP_CLOSE = 0x8;
19
+ const OP_PING = 0x9;
20
+ const OP_PONG = 0xa;
21
+ /**
22
+ * 연결 하나. 이벤트는 `message`(글자), `close`(코드, 이유), `pong`이다.
23
+ * `error`는 내보내지 않는다 — 소켓 오류는 1006 close로 바꿔 한 길로만 끝나게 한다.
24
+ */
25
+ export class WsConnection extends EventEmitter {
26
+ socket;
27
+ options;
28
+ buf = Buffer.alloc(0);
29
+ fragments = [];
30
+ fragmentBytes = 0;
31
+ closed = false;
32
+ closeSent = false;
33
+ maxMessageBytes;
34
+ constructor(socket, options, head) {
35
+ super();
36
+ this.socket = socket;
37
+ this.options = options;
38
+ this.maxMessageBytes = options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;
39
+ socket.on('data', (chunk) => this.onData(chunk));
40
+ socket.on('close', () => this.finish(1006, ''));
41
+ socket.on('error', () => this.finish(1006, ''));
42
+ socket.on('drain', () => this.emit('drain'));
43
+ // 핸드셰이크 응답과 같은 패킷에 실려 온 첫 프레임이다. 버퍼에 먼저 넣어 차례를 지키고
44
+ // 해석은 부른 쪽이 message 리스너를 붙인 뒤로 미룬다
45
+ if (head && head.length > 0) {
46
+ this.buf = Buffer.from(head);
47
+ setImmediate(() => this.onData(Buffer.alloc(0)));
48
+ }
49
+ }
50
+ /** 소켓 버퍼에 밀려 있는 바이트 */
51
+ get bufferedAmount() {
52
+ return this.socket.writableLength ?? 0;
53
+ }
54
+ get isOpen() {
55
+ return !this.closed && !this.closeSent;
56
+ }
57
+ send(text) {
58
+ if (!this.isOpen)
59
+ return false;
60
+ return this.writeFrame(OP_TEXT, Buffer.from(text, 'utf8'));
61
+ }
62
+ ping() {
63
+ if (this.isOpen)
64
+ this.writeFrame(OP_PING, Buffer.alloc(0));
65
+ }
66
+ close(code = 1000, reason = '') {
67
+ if (this.closed)
68
+ return;
69
+ if (!this.closeSent) {
70
+ this.closeSent = true;
71
+ const r = Buffer.from(reason.slice(0, 100), 'utf8');
72
+ const body = Buffer.alloc(2 + r.length);
73
+ body.writeUInt16BE(code, 0);
74
+ r.copy(body, 2);
75
+ this.writeFrame(OP_CLOSE, body);
76
+ }
77
+ // 상대가 close로 답하지 않아도 오래 붙잡지 않는다
78
+ const timer = setTimeout(() => this.socket.destroy(), 1_000);
79
+ timer.unref();
80
+ this.socket.end();
81
+ this.finish(code, reason);
82
+ }
83
+ /** 상대에게 알리지 않고 끊는다. 안 읽는 상대를 떼어낼 때 쓴다 */
84
+ terminate(code = 1006, reason = '') {
85
+ this.socket.destroy();
86
+ this.finish(code, reason);
87
+ }
88
+ finish(code, reason) {
89
+ if (this.closed)
90
+ return;
91
+ this.closed = true;
92
+ this.buf = Buffer.alloc(0);
93
+ this.fragments = [];
94
+ this.emit('close', code, reason);
95
+ }
96
+ writeFrame(op, payload) {
97
+ const mask = this.options.client;
98
+ const len = payload.length;
99
+ const lenBytes = len < 126 ? 0 : len < 65536 ? 2 : 8;
100
+ const header = Buffer.alloc(2 + lenBytes + (mask ? 4 : 0));
101
+ header[0] = 0x80 | op;
102
+ header[1] = (mask ? 0x80 : 0) | (lenBytes === 0 ? len : lenBytes === 2 ? 126 : 127);
103
+ if (lenBytes === 2)
104
+ header.writeUInt16BE(len, 2);
105
+ else if (lenBytes === 8)
106
+ header.writeBigUInt64BE(BigInt(len), 2);
107
+ let body = payload;
108
+ if (mask) {
109
+ const key = randomBytes(4);
110
+ key.copy(header, 2 + lenBytes);
111
+ body = Buffer.allocUnsafe(len);
112
+ for (let i = 0; i < len; i++)
113
+ body[i] = payload[i] ^ key[i & 3];
114
+ }
115
+ try {
116
+ return this.socket.write(Buffer.concat([header, body]));
117
+ }
118
+ catch {
119
+ return false;
120
+ }
121
+ }
122
+ onData(chunk) {
123
+ if (this.closed)
124
+ return;
125
+ this.buf = this.buf.length === 0 ? chunk : Buffer.concat([this.buf, chunk]);
126
+ while (!this.closed) {
127
+ const frame = this.readFrame();
128
+ if (!frame)
129
+ return;
130
+ this.onFrame(frame.fin, frame.op, frame.payload);
131
+ }
132
+ }
133
+ readFrame() {
134
+ const b = this.buf;
135
+ if (b.length < 2)
136
+ return null;
137
+ const fin = (b[0] & 0x80) !== 0;
138
+ const op = b[0] & 0x0f;
139
+ const masked = (b[1] & 0x80) !== 0;
140
+ let len = b[1] & 0x7f;
141
+ let off = 2;
142
+ if (len === 126) {
143
+ if (b.length < 4)
144
+ return null;
145
+ len = b.readUInt16BE(2);
146
+ off = 4;
147
+ }
148
+ else if (len === 127) {
149
+ if (b.length < 10)
150
+ return null;
151
+ const big = b.readBigUInt64BE(2);
152
+ if (big > BigInt(this.maxMessageBytes)) {
153
+ this.close(1009, 'too big');
154
+ return null;
155
+ }
156
+ len = Number(big);
157
+ off = 10;
158
+ }
159
+ if (len > this.maxMessageBytes) {
160
+ this.close(1009, 'too big');
161
+ return null;
162
+ }
163
+ // 서버는 가린 프레임만, 클라이언트는 안 가린 프레임만 받는다(RFC 6455 5.1)
164
+ if (masked === this.options.client) {
165
+ this.close(1002, 'mask');
166
+ return null;
167
+ }
168
+ const maskLen = masked ? 4 : 0;
169
+ if (b.length < off + maskLen + len)
170
+ return null;
171
+ let payload = b.subarray(off + maskLen, off + maskLen + len);
172
+ if (masked) {
173
+ const key = b.subarray(off, off + 4);
174
+ const out = Buffer.allocUnsafe(len);
175
+ for (let i = 0; i < len; i++)
176
+ out[i] = payload[i] ^ key[i & 3];
177
+ payload = out;
178
+ }
179
+ else {
180
+ payload = Buffer.from(payload);
181
+ }
182
+ this.buf = b.subarray(off + maskLen + len);
183
+ return { fin, op, payload };
184
+ }
185
+ onFrame(fin, op, payload) {
186
+ switch (op) {
187
+ case OP_PING:
188
+ if (this.isOpen)
189
+ this.writeFrame(OP_PONG, payload);
190
+ return;
191
+ case OP_PONG:
192
+ this.emit('pong');
193
+ return;
194
+ case OP_CLOSE: {
195
+ const code = payload.length >= 2 ? payload.readUInt16BE(0) : 1005;
196
+ const reason = payload.length > 2 ? payload.subarray(2).toString('utf8') : '';
197
+ this.close(code === 1005 ? 1000 : code, reason);
198
+ return;
199
+ }
200
+ case OP_BINARY:
201
+ this.close(1003, 'text only');
202
+ return;
203
+ case OP_TEXT:
204
+ case OP_CONT: {
205
+ if (op === OP_TEXT && this.fragments.length > 0) {
206
+ this.close(1002, 'fragment');
207
+ return;
208
+ }
209
+ if (op === OP_CONT && this.fragments.length === 0) {
210
+ this.close(1002, 'continuation');
211
+ return;
212
+ }
213
+ this.fragmentBytes += payload.length;
214
+ if (this.fragmentBytes > this.maxMessageBytes) {
215
+ this.close(1009, 'too big');
216
+ return;
217
+ }
218
+ this.fragments.push(payload);
219
+ if (!fin)
220
+ return;
221
+ const text = Buffer.concat(this.fragments).toString('utf8');
222
+ this.fragments = [];
223
+ this.fragmentBytes = 0;
224
+ try {
225
+ this.emit('message', text);
226
+ }
227
+ catch (err) {
228
+ // 리스너가 던지면 소켓 data 핸들러 밖으로 나가 프로세스가 죽는다
229
+ process.stderr.write(`[peer] ws message handler failed: ${String(err)}\n`);
230
+ }
231
+ return;
232
+ }
233
+ default:
234
+ this.close(1002, 'opcode');
235
+ }
236
+ }
237
+ }
238
+ /**
239
+ * http(s) 서버의 `upgrade` 이벤트에서 부른다. 핸드셰이크가 틀리면 400으로 닫고 null.
240
+ */
241
+ export function acceptUpgrade(req, socket, head, options = {}) {
242
+ const key = req.headers['sec-websocket-key'];
243
+ const upgrade = String(req.headers.upgrade ?? '').toLowerCase();
244
+ if (req.method !== 'GET' ||
245
+ upgrade !== 'websocket' ||
246
+ typeof key !== 'string' ||
247
+ !/^[A-Za-z0-9+/]{22}==$/.test(key) ||
248
+ req.headers['sec-websocket-version'] !== '13') {
249
+ socket.end('HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n');
250
+ return null;
251
+ }
252
+ socket.write('HTTP/1.1 101 Switching Protocols\r\n' +
253
+ 'Upgrade: websocket\r\n' +
254
+ 'Connection: Upgrade\r\n' +
255
+ `Sec-WebSocket-Accept: ${acceptKey(key)}\r\n\r\n`);
256
+ return new WsConnection(socket, { ...options, client: false }, head);
257
+ }
258
+ /** `ws://` 또는 `wss://`로 붙는다 */
259
+ export function connectWs(url, options = {}) {
260
+ return new Promise((resolve, reject) => {
261
+ const u = new URL(url);
262
+ if (u.protocol !== 'ws:' && u.protocol !== 'wss:') {
263
+ reject(new Error(`ws:// 또는 wss:// 주소여야 해요: ${url}`));
264
+ return;
265
+ }
266
+ const key = randomBytes(16).toString('base64');
267
+ const make = u.protocol === 'wss:' ? httpsRequest : httpRequest;
268
+ const req = make({
269
+ hostname: u.hostname,
270
+ port: u.port || (u.protocol === 'wss:' ? 443 : 80),
271
+ path: `${u.pathname}${u.search}`,
272
+ headers: {
273
+ Connection: 'Upgrade',
274
+ Upgrade: 'websocket',
275
+ 'Sec-WebSocket-Key': key,
276
+ 'Sec-WebSocket-Version': '13',
277
+ },
278
+ });
279
+ const timer = setTimeout(() => {
280
+ req.destroy(new Error(`릴레이가 ${options.timeoutMs ?? 10_000}ms 안에 답하지 않았어요`));
281
+ }, options.timeoutMs ?? 10_000);
282
+ req.once('upgrade', (res, socket, head) => {
283
+ clearTimeout(timer);
284
+ if (res.headers['sec-websocket-accept'] !== acceptKey(key)) {
285
+ socket.destroy();
286
+ reject(new Error('릴레이 핸드셰이크 응답이 맞지 않아요'));
287
+ return;
288
+ }
289
+ resolve(new WsConnection(socket, { ...options, client: true }, head));
290
+ });
291
+ req.once('response', (res) => {
292
+ clearTimeout(timer);
293
+ res.resume();
294
+ reject(new Error(`릴레이가 WebSocket을 거절했어요 (HTTP ${res.statusCode})`));
295
+ });
296
+ req.once('error', (err) => {
297
+ clearTimeout(timer);
298
+ reject(err);
299
+ });
300
+ req.end();
301
+ });
302
+ }
303
+ function acceptKey(key) {
304
+ return createHash('sha1')
305
+ .update(key + GUID)
306
+ .digest('base64');
307
+ }
308
+ //# sourceMappingURL=ws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws.js","sourceRoot":"","sources":["../../../src/peer/ws.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tienne/gestalt",
3
- "version": "0.108.0",
3
+ "version": "0.110.0",
4
4
  "description": "TypeScript AI Development Harness - Gestalt psychology-driven requirement clarification",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gestalt",
3
- "version": "0.108.0",
3
+ "version": "0.110.0",
4
4
  "description": "Gestalt psychology-driven AI development harness. Transforms scattered requirements into structured, validated specifications through interactive interviews.",
5
5
  "author": {
6
6
  "name": "tienne"
package/plugin/.mcp.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "mcpServers": {
3
3
  "gestalt": {
4
4
  "command": "npx",
5
- "args": ["-y", "@tienne/gestalt@0.108.0", "serve"],
5
+ "args": ["-y", "@tienne/gestalt@0.110.0", "serve"],
6
6
  "startup_timeout_sec": 180,
7
7
  "tool_timeout_sec": 900
8
8
  }
package/plugin/mcp.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "mcpServers": {
3
3
  "gestalt": {
4
4
  "command": "npx",
5
- "args": ["-y", "@tienne/gestalt@0.108.0", "serve"],
5
+ "args": ["-y", "@tienne/gestalt@0.110.0", "serve"],
6
6
  "startup_timeout_sec": 180,
7
7
  "tool_timeout_sec": 900
8
8
  }