@zetaloop/chappie 0.4.1 → 1.0.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/.codex-plugin/plugin.json +13 -0
- package/README.md +26 -35
- package/dist/chunk-5CKVVDZ2.js +1042 -0
- package/dist/chunk-DM523QRR.js +148 -0
- package/dist/chunk-DN7OHZK6.js +110 -0
- package/dist/chunk-DQWC5GFN.js +1745 -0
- package/dist/chunk-EIPDEA3I.js +286 -0
- package/dist/chunk-GWYP7B66.js +8479 -0
- package/dist/chunk-GX4JWLHH.js +98 -0
- package/dist/chunk-K2VE2MDU.js +14916 -0
- package/dist/chunk-OWAAWZNT.js +56 -0
- package/dist/chunk-UOFCCHBS.js +94 -0
- package/dist/cli.js +47 -0
- package/dist/codex-RI2XL4HV.js +5144 -0
- package/dist/codex-plugin-NSKWB3WS.js +179 -0
- package/dist/codex.json +23 -0
- package/dist/index.js +4752 -0
- package/dist/instructions.md +13 -0
- package/dist/omp.js +240 -0
- package/dist/opencode.js +904 -0
- package/dist/promise-OHH5J44X.js +72 -0
- package/dist/stdio-KJVCYPXJ.js +1279 -0
- package/docs/setup.md +82 -0
- package/docs/tools.md +108 -100
- package/package.json +100 -56
- package/src/activity.ts +0 -21
- package/src/broker.ts +0 -1008
- package/src/config.ts +0 -21
- package/src/delivery.ts +0 -54
- package/src/history.ts +0 -123
- package/src/index.ts +0 -39
- package/src/instructions.md +0 -19
- package/src/ipc.ts +0 -477
- package/src/provider.ts +0 -194
- package/src/questions.ts +0 -95
- package/src/resources.ts +0 -189
- package/src/server.ts +0 -615
- package/src/session.ts +0 -603
- package/src/state.ts +0 -179
- package/src/stdio.ts +0 -58
- package/src/tools.ts +0 -91
- package/src/transfer.ts +0 -162
- /package/{src → dist}/question.html +0 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/ipc.ts
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import { once } from "node:events";
|
|
6
|
+
import { lstat, unlink } from "node:fs/promises";
|
|
7
|
+
import {
|
|
8
|
+
createConnection,
|
|
9
|
+
createServer
|
|
10
|
+
} from "node:net";
|
|
11
|
+
import { join, resolve } from "node:path";
|
|
12
|
+
var defaultPort = 24274;
|
|
13
|
+
function ipcEndpoint(root) {
|
|
14
|
+
const directory = resolve(root);
|
|
15
|
+
if (process.platform !== "win32") return join(directory, "broker.sock");
|
|
16
|
+
const identity = directory.replaceAll("\\", "/").toLowerCase();
|
|
17
|
+
return String.raw`\\.\pipe\chappie-${createHash("sha256").update(identity).digest("hex").slice(0, 16)}`;
|
|
18
|
+
}
|
|
19
|
+
var JsonLinePeer = class {
|
|
20
|
+
#socket;
|
|
21
|
+
#onMessage;
|
|
22
|
+
#onClose;
|
|
23
|
+
#buffer = "";
|
|
24
|
+
#closed = false;
|
|
25
|
+
constructor(socket, onMessage, onClose) {
|
|
26
|
+
this.#socket = socket;
|
|
27
|
+
this.#onMessage = onMessage;
|
|
28
|
+
this.#onClose = onClose;
|
|
29
|
+
socket.setEncoding("utf8");
|
|
30
|
+
socket.on("data", (chunk) => this.#receive(chunk));
|
|
31
|
+
socket.once("close", () => {
|
|
32
|
+
this.#closed = true;
|
|
33
|
+
this.#onClose();
|
|
34
|
+
});
|
|
35
|
+
socket.on("error", () => {
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
get closed() {
|
|
39
|
+
return this.#closed;
|
|
40
|
+
}
|
|
41
|
+
send(message) {
|
|
42
|
+
const line = `${JSON.stringify(message)}
|
|
43
|
+
`;
|
|
44
|
+
return new Promise((resolveWrite, rejectWrite) => {
|
|
45
|
+
if (this.#closed) {
|
|
46
|
+
rejectWrite(new Error("Chappie IPC connection is closed"));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
this.#socket.write(line, (error) => {
|
|
50
|
+
if (error) rejectWrite(error);
|
|
51
|
+
else resolveWrite();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
close() {
|
|
56
|
+
if (!this.#closed) this.#socket.end();
|
|
57
|
+
}
|
|
58
|
+
#receive(chunk) {
|
|
59
|
+
this.#buffer += chunk;
|
|
60
|
+
let end = this.#buffer.indexOf("\n");
|
|
61
|
+
while (end !== -1) {
|
|
62
|
+
const line = this.#buffer.slice(0, end);
|
|
63
|
+
this.#buffer = this.#buffer.slice(end + 1);
|
|
64
|
+
if (line.length > 0) {
|
|
65
|
+
void Promise.resolve().then(() => this.#onMessage(JSON.parse(line))).catch((error) => {
|
|
66
|
+
this.#socket.destroy(
|
|
67
|
+
error instanceof Error ? error : new Error(String(error))
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
end = this.#buffer.indexOf("\n");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var IpcServer = class {
|
|
76
|
+
#endpoint;
|
|
77
|
+
#onMessage;
|
|
78
|
+
#onClose;
|
|
79
|
+
#peers = /* @__PURE__ */ new Set();
|
|
80
|
+
#servers = /* @__PURE__ */ new Set();
|
|
81
|
+
constructor(directory, onMessage, onClose) {
|
|
82
|
+
this.#endpoint = ipcEndpoint(directory);
|
|
83
|
+
this.#onMessage = onMessage;
|
|
84
|
+
this.#onClose = onClose;
|
|
85
|
+
}
|
|
86
|
+
async start(network = false) {
|
|
87
|
+
if (this.#servers.size > 0) return;
|
|
88
|
+
if (process.platform !== "win32") await prepareUnixSocket(this.#endpoint);
|
|
89
|
+
try {
|
|
90
|
+
const local = this.#createServer();
|
|
91
|
+
await once(local.listen(this.#endpoint), "listening");
|
|
92
|
+
this.#servers.add(local);
|
|
93
|
+
if (!network) return;
|
|
94
|
+
const remote = this.#createServer();
|
|
95
|
+
await once(
|
|
96
|
+
remote.listen(network === true ? defaultPort : network),
|
|
97
|
+
"listening"
|
|
98
|
+
);
|
|
99
|
+
this.#servers.add(remote);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
await this.close();
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async close() {
|
|
106
|
+
for (const peer of this.#peers) peer.close();
|
|
107
|
+
this.#peers.clear();
|
|
108
|
+
const servers = [...this.#servers];
|
|
109
|
+
this.#servers.clear();
|
|
110
|
+
await Promise.all(servers.map(closeServer));
|
|
111
|
+
}
|
|
112
|
+
#createServer() {
|
|
113
|
+
return createServer((socket) => {
|
|
114
|
+
let peer;
|
|
115
|
+
peer = new JsonLinePeer(
|
|
116
|
+
socket,
|
|
117
|
+
(message) => this.#onMessage(peer, message),
|
|
118
|
+
() => {
|
|
119
|
+
this.#peers.delete(peer);
|
|
120
|
+
this.#onClose(peer);
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
this.#peers.add(peer);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
var IpcClient = class {
|
|
128
|
+
#endpoint;
|
|
129
|
+
#remote;
|
|
130
|
+
#callbacks;
|
|
131
|
+
#peer;
|
|
132
|
+
#opening;
|
|
133
|
+
#controller;
|
|
134
|
+
#retry;
|
|
135
|
+
#closed = false;
|
|
136
|
+
constructor(directory, remote, callbacks) {
|
|
137
|
+
this.#endpoint = ipcEndpoint(directory);
|
|
138
|
+
this.#remote = remote;
|
|
139
|
+
this.#callbacks = callbacks;
|
|
140
|
+
}
|
|
141
|
+
get connected() {
|
|
142
|
+
return this.#peer !== void 0 && !this.#peer.closed;
|
|
143
|
+
}
|
|
144
|
+
start() {
|
|
145
|
+
void this.connect().catch(() => {
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
connect() {
|
|
149
|
+
if (this.#closed)
|
|
150
|
+
return Promise.reject(new Error("Chappie IPC client is closed"));
|
|
151
|
+
if (this.connected) return Promise.resolve();
|
|
152
|
+
if (this.#opening) return this.#opening;
|
|
153
|
+
clearTimeout(this.#retry);
|
|
154
|
+
this.#retry = void 0;
|
|
155
|
+
const controller = new AbortController();
|
|
156
|
+
this.#controller = controller;
|
|
157
|
+
this.#opening = this.#open(controller.signal).finally(() => {
|
|
158
|
+
this.#opening = void 0;
|
|
159
|
+
if (this.#controller === controller) this.#controller = void 0;
|
|
160
|
+
});
|
|
161
|
+
return this.#opening;
|
|
162
|
+
}
|
|
163
|
+
send(message) {
|
|
164
|
+
const peer = this.#peer;
|
|
165
|
+
if (!peer || peer.closed)
|
|
166
|
+
return Promise.reject(new Error("Chappie broker is not running"));
|
|
167
|
+
return peer.send(message);
|
|
168
|
+
}
|
|
169
|
+
close() {
|
|
170
|
+
this.#closed = true;
|
|
171
|
+
clearTimeout(this.#retry);
|
|
172
|
+
this.#retry = void 0;
|
|
173
|
+
this.#controller?.abort(new Error("Chappie IPC client is closed"));
|
|
174
|
+
this.#controller = void 0;
|
|
175
|
+
this.#peer?.close();
|
|
176
|
+
this.#peer = void 0;
|
|
177
|
+
}
|
|
178
|
+
async #open(signal) {
|
|
179
|
+
let socket;
|
|
180
|
+
let failure = new Error("Chappie disconnected");
|
|
181
|
+
try {
|
|
182
|
+
socket = this.#remote ? createConnection(networkEndpoint(this.#remote)) : createConnection(this.#endpoint);
|
|
183
|
+
await once(socket, "connect", { signal });
|
|
184
|
+
} catch (error) {
|
|
185
|
+
socket?.destroy();
|
|
186
|
+
this.#scheduleReconnect();
|
|
187
|
+
signal.throwIfAborted();
|
|
188
|
+
throw error;
|
|
189
|
+
}
|
|
190
|
+
let peer;
|
|
191
|
+
peer = new JsonLinePeer(
|
|
192
|
+
socket,
|
|
193
|
+
(message) => this.#callbacks.onMessage(message),
|
|
194
|
+
() => {
|
|
195
|
+
if (this.#peer !== peer) return;
|
|
196
|
+
this.#peer = void 0;
|
|
197
|
+
if (!this.#closed) {
|
|
198
|
+
this.#callbacks.onClose(failure);
|
|
199
|
+
this.#scheduleReconnect();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
);
|
|
203
|
+
this.#peer = peer;
|
|
204
|
+
try {
|
|
205
|
+
await this.#callbacks.onOpen();
|
|
206
|
+
} catch (error) {
|
|
207
|
+
failure = error instanceof Error ? error : new Error(String(error));
|
|
208
|
+
peer.close();
|
|
209
|
+
throw failure;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
#scheduleReconnect() {
|
|
213
|
+
if (this.#closed || this.#retry) return;
|
|
214
|
+
this.#retry = setTimeout(() => {
|
|
215
|
+
this.#retry = void 0;
|
|
216
|
+
void this.connect().catch(() => {
|
|
217
|
+
});
|
|
218
|
+
}, 500);
|
|
219
|
+
this.#retry.unref();
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
function closeServer(server) {
|
|
223
|
+
return new Promise(
|
|
224
|
+
(resolveClose, rejectClose) => server.close((error) => error ? rejectClose(error) : resolveClose())
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
function networkEndpoint(value) {
|
|
228
|
+
const url = new URL(`tcp://${value}`);
|
|
229
|
+
if (url.username || url.password || url.pathname || url.search || url.hash)
|
|
230
|
+
throw new Error(`Invalid Chappie broker address: ${value}`);
|
|
231
|
+
const host = url.hostname.startsWith("[") ? url.hostname.slice(1, -1) : url.hostname;
|
|
232
|
+
if (!host) throw new Error(`Invalid Chappie broker address: ${value}`);
|
|
233
|
+
return { host, port: url.port ? Number(url.port) : defaultPort };
|
|
234
|
+
}
|
|
235
|
+
async function prepareUnixSocket(endpoint) {
|
|
236
|
+
try {
|
|
237
|
+
await lstat(endpoint);
|
|
238
|
+
} catch (error) {
|
|
239
|
+
if (error.code === "ENOENT") return;
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
if (await endpointAcceptsConnections(endpoint)) {
|
|
243
|
+
const error = new Error(
|
|
244
|
+
`Chappie broker is already listening at ${endpoint}`
|
|
245
|
+
);
|
|
246
|
+
error.code = "EADDRINUSE";
|
|
247
|
+
throw error;
|
|
248
|
+
}
|
|
249
|
+
await unlink(endpoint);
|
|
250
|
+
}
|
|
251
|
+
function endpointAcceptsConnections(endpoint) {
|
|
252
|
+
return new Promise((resolveProbe, rejectProbe) => {
|
|
253
|
+
const socket = createConnection(endpoint);
|
|
254
|
+
socket.once("connect", () => {
|
|
255
|
+
socket.end();
|
|
256
|
+
resolveProbe(true);
|
|
257
|
+
});
|
|
258
|
+
socket.once("error", (error) => {
|
|
259
|
+
socket.destroy();
|
|
260
|
+
if (error.code === "ECONNREFUSED" || error.code === "ENOENT")
|
|
261
|
+
resolveProbe(false);
|
|
262
|
+
else rejectProbe(error);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/activity.ts
|
|
268
|
+
function source(clientId, requestId, label = "ChatGPT") {
|
|
269
|
+
return {
|
|
270
|
+
clientId,
|
|
271
|
+
label,
|
|
272
|
+
...typeof requestId === "string" ? { requestId } : {}
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function sourceLabel({ clientId, label, requestId }) {
|
|
276
|
+
const workflow = requestId?.match(/^wfr_([^/]+)\//)?.[1];
|
|
277
|
+
return `${label} ${clientId.slice(-4)}${workflow ? `(${workflow.slice(-4)})` : ""}`;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export {
|
|
281
|
+
source,
|
|
282
|
+
sourceLabel,
|
|
283
|
+
ipcEndpoint,
|
|
284
|
+
IpcServer,
|
|
285
|
+
IpcClient
|
|
286
|
+
};
|