@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.
- package/CLAUDE.md +1 -0
- package/dist/package.json +1 -1
- package/dist/src/cli/commands/peer.d.ts +49 -0
- package/dist/src/cli/commands/peer.d.ts.map +1 -0
- package/dist/src/cli/commands/peer.js +302 -0
- package/dist/src/cli/commands/peer.js.map +1 -0
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +81 -2
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/peer/client.d.ts +9 -0
- package/dist/src/peer/client.d.ts.map +1 -0
- package/dist/src/peer/client.js +51 -0
- package/dist/src/peer/client.js.map +1 -0
- package/dist/src/peer/daemon.d.ts +83 -0
- package/dist/src/peer/daemon.d.ts.map +1 -0
- package/dist/src/peer/daemon.js +516 -0
- package/dist/src/peer/daemon.js.map +1 -0
- package/dist/src/peer/errors.d.ts +2 -0
- package/dist/src/peer/errors.d.ts.map +1 -0
- package/dist/src/peer/errors.js +4 -0
- package/dist/src/peer/errors.js.map +1 -0
- package/dist/src/peer/feed.d.ts +103 -0
- package/dist/src/peer/feed.d.ts.map +1 -0
- package/dist/src/peer/feed.js +167 -0
- package/dist/src/peer/feed.js.map +1 -0
- package/dist/src/peer/index.d.ts +24 -0
- package/dist/src/peer/index.d.ts.map +1 -0
- package/dist/src/peer/index.js +14 -0
- package/dist/src/peer/index.js.map +1 -0
- package/dist/src/peer/keys.d.ts +26 -0
- package/dist/src/peer/keys.d.ts.map +1 -0
- package/dist/src/peer/keys.js +95 -0
- package/dist/src/peer/keys.js.map +1 -0
- package/dist/src/peer/locate.d.ts +44 -0
- package/dist/src/peer/locate.d.ts.map +1 -0
- package/dist/src/peer/locate.js +116 -0
- package/dist/src/peer/locate.js.map +1 -0
- package/dist/src/peer/lock.d.ts +32 -0
- package/dist/src/peer/lock.d.ts.map +1 -0
- package/dist/src/peer/lock.js +147 -0
- package/dist/src/peer/lock.js.map +1 -0
- package/dist/src/peer/mirror.d.ts +21 -0
- package/dist/src/peer/mirror.d.ts.map +1 -0
- package/dist/src/peer/mirror.js +68 -0
- package/dist/src/peer/mirror.js.map +1 -0
- package/dist/src/peer/network.d.ts +148 -0
- package/dist/src/peer/network.d.ts.map +1 -0
- package/dist/src/peer/network.js +809 -0
- package/dist/src/peer/network.js.map +1 -0
- package/dist/src/peer/paths.d.ts +23 -0
- package/dist/src/peer/paths.d.ts.map +1 -0
- package/dist/src/peer/paths.js +50 -0
- package/dist/src/peer/paths.js.map +1 -0
- package/dist/src/peer/protocol.d.ts +112 -0
- package/dist/src/peer/protocol.d.ts.map +1 -0
- package/dist/src/peer/protocol.js +8 -0
- package/dist/src/peer/protocol.js.map +1 -0
- package/dist/src/peer/redact.d.ts +30 -0
- package/dist/src/peer/redact.d.ts.map +1 -0
- package/dist/src/peer/redact.js +214 -0
- package/dist/src/peer/redact.js.map +1 -0
- package/dist/src/peer/relay.d.ts +70 -0
- package/dist/src/peer/relay.d.ts.map +1 -0
- package/dist/src/peer/relay.js +410 -0
- package/dist/src/peer/relay.js.map +1 -0
- package/dist/src/peer/roster.d.ts +89 -0
- package/dist/src/peer/roster.d.ts.map +1 -0
- package/dist/src/peer/roster.js +160 -0
- package/dist/src/peer/roster.js.map +1 -0
- package/dist/src/peer/seal.d.ts +37 -0
- package/dist/src/peer/seal.d.ts.map +1 -0
- package/dist/src/peer/seal.js +115 -0
- package/dist/src/peer/seal.js.map +1 -0
- package/dist/src/peer/share.d.ts +41 -0
- package/dist/src/peer/share.d.ts.map +1 -0
- package/dist/src/peer/share.js +70 -0
- package/dist/src/peer/share.js.map +1 -0
- package/dist/src/peer/state.d.ts +68 -0
- package/dist/src/peer/state.d.ts.map +1 -0
- package/dist/src/peer/state.js +161 -0
- package/dist/src/peer/state.js.map +1 -0
- package/dist/src/peer/tail.d.ts +55 -0
- package/dist/src/peer/tail.d.ts.map +1 -0
- package/dist/src/peer/tail.js +148 -0
- package/dist/src/peer/tail.js.map +1 -0
- package/dist/src/peer/transform.d.ts +79 -0
- package/dist/src/peer/transform.d.ts.map +1 -0
- package/dist/src/peer/transform.js +237 -0
- package/dist/src/peer/transform.js.map +1 -0
- package/dist/src/peer/transport.d.ts +89 -0
- package/dist/src/peer/transport.d.ts.map +1 -0
- package/dist/src/peer/transport.js +345 -0
- package/dist/src/peer/transport.js.map +1 -0
- package/dist/src/peer/viewer-html.d.ts +10 -0
- package/dist/src/peer/viewer-html.d.ts.map +1 -0
- package/dist/src/peer/viewer-html.js +165 -0
- package/dist/src/peer/viewer-html.js.map +1 -0
- package/dist/src/peer/viewer.d.ts +58 -0
- package/dist/src/peer/viewer.d.ts.map +1 -0
- package/dist/src/peer/viewer.js +249 -0
- package/dist/src/peer/viewer.js.map +1 -0
- package/dist/src/peer/wire.d.ts +90 -0
- package/dist/src/peer/wire.d.ts.map +1 -0
- package/dist/src/peer/wire.js +10 -0
- package/dist/src/peer/wire.js.map +1 -0
- package/dist/src/peer/ws.d.ts +47 -0
- package/dist/src/peer/ws.d.ts.map +1 -0
- package/dist/src/peer/ws.js +308 -0
- package/dist/src/peer/ws.js.map +1 -0
- package/package.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.mcp.json +1 -1
- 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": "gestalt",
|
|
3
|
-
"version": "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