coldbluff 0.1.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.
@@ -0,0 +1,268 @@
1
+ /**
2
+ * One-shot CLI commands for AI agents.
3
+ *
4
+ * Each command: connect → auth → do one thing → print JSON → exit.
5
+ * All commands are Effect pipelines — no manual setTimeout or process.exit().
6
+ *
7
+ * @module
8
+ */
9
+ import { Effect, Queue, Duration } from "effect";
10
+ import { makeConnection } from "./ws-client.js";
11
+ // ─── Exit codes ──────────────────────────────────────────────────────────────
12
+ export const EXIT_SUCCESS = 0;
13
+ export const EXIT_ERROR = 1;
14
+ export const EXIT_HAND_ENDED = 2;
15
+ // ─── Errors ──────────────────────────────────────────────────────────────────
16
+ export class CliError {
17
+ _tag = "CliError";
18
+ code;
19
+ reason;
20
+ exitCode;
21
+ constructor(code, reason, exitCode = EXIT_ERROR) {
22
+ this.code = code;
23
+ this.reason = reason;
24
+ this.exitCode = exitCode;
25
+ }
26
+ }
27
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
28
+ function emit(obj) {
29
+ process.stdout.write(JSON.stringify(obj) + "\n");
30
+ }
31
+ const sendOrFail = (conn, msg) => conn
32
+ .send(msg)
33
+ .pipe(Effect.mapError((err) => new CliError("SEND_FAILED", String(err))));
34
+ /** Connect and authenticate. Returns a scoped WsConnection. */
35
+ const connectAndAuth = (server, token, timeoutMs = 10_000) => Effect.gen(function* () {
36
+ const conn = yield* makeConnection(server).pipe(Effect.mapError((err) => new CliError("CONNECTION_FAILED", String(err))));
37
+ yield* sendOrFail(conn, { type: "auth", token });
38
+ // Wait for auth_ok or error
39
+ yield* Effect.gen(function* () {
40
+ for (;;) {
41
+ const msg = yield* Queue.take(conn.inbox);
42
+ if (msg.type === "auth_ok")
43
+ return;
44
+ if (msg.type === "error") {
45
+ return yield* Effect.fail(new CliError("AUTH_ERROR", `Auth error: ${msg.reason}`));
46
+ }
47
+ }
48
+ }).pipe(Effect.timeoutFail({
49
+ onTimeout: () => new CliError("AUTH_TIMEOUT", "Auth timeout"),
50
+ duration: Duration.millis(timeoutMs),
51
+ }));
52
+ return conn;
53
+ });
54
+ /** Take the next message matching a type guard, with timeout. Server errors are caught. */
55
+ const takeMatching = (inbox, pred, timeoutMs = 10_000) => Effect.gen(function* () {
56
+ for (;;) {
57
+ const msg = yield* Queue.take(inbox);
58
+ if (msg.type === "error") {
59
+ return yield* Effect.fail(new CliError("SERVER_ERROR", `${msg.code} - ${msg.reason}`));
60
+ }
61
+ if (pred(msg))
62
+ return msg;
63
+ }
64
+ }).pipe(Effect.timeoutFail({
65
+ onTimeout: () => new CliError("TIMEOUT", "Timeout waiting for server response"),
66
+ duration: Duration.millis(timeoutMs),
67
+ }));
68
+ /** Run a oneshot command: scoped connect → auth → action → clean exit. */
69
+ const runOneshot = (server, token, action) => Effect.scoped(Effect.gen(function* () {
70
+ const conn = yield* connectAndAuth(server, token);
71
+ return yield* action(conn);
72
+ }));
73
+ export const tables = (opts) => runOneshot(opts.server, opts.token, (conn) => Effect.gen(function* () {
74
+ yield* sendOrFail(conn, { type: "list_tables" });
75
+ const msg = yield* takeMatching(conn.inbox, (m) => m.type === "table_list");
76
+ emit({ tables: msg.tables });
77
+ }));
78
+ export const quickseat = (opts) => runOneshot(opts.server, opts.token, (conn) => Effect.gen(function* () {
79
+ yield* sendOrFail(conn, { type: "quick_seat", tierId: opts.tier });
80
+ const msg = yield* takeMatching(conn.inbox, (m) => m.type === "joined");
81
+ emit({ event: "joined", tableId: msg.tableId, seat: msg.seatIndex });
82
+ }));
83
+ export const tiers = (opts) => runOneshot(opts.server, opts.token, (conn) => Effect.gen(function* () {
84
+ yield* sendOrFail(conn, { type: "list_tiers" });
85
+ const msg = yield* takeMatching(conn.inbox, (m) => m.type === "tier_list");
86
+ emit({ tiers: msg.tiers });
87
+ }));
88
+ export const join = (opts) => runOneshot(opts.server, opts.token, (conn) => Effect.gen(function* () {
89
+ yield* sendOrFail(conn, {
90
+ type: "join_table",
91
+ tableId: opts.table,
92
+ seatIndex: opts.seat,
93
+ buyIn: opts.buyin,
94
+ });
95
+ const msg = yield* takeMatching(conn.inbox, (m) => m.type === "joined");
96
+ emit({ event: "joined", tableId: msg.tableId, seat: msg.seatIndex });
97
+ }));
98
+ export const leave = (opts) => runOneshot(opts.server, opts.token, (conn) => Effect.gen(function* () {
99
+ yield* sendOrFail(conn, { type: "leave_table", tableId: opts.table });
100
+ const msg = yield* takeMatching(conn.inbox, (m) => m.type === "left");
101
+ emit({ event: "left", tableId: msg.tableId });
102
+ }));
103
+ export const status = (opts) => runOneshot(opts.server, opts.token, (conn) => Effect.gen(function* () {
104
+ yield* sendOrFail(conn, { type: "spectate", tableId: opts.table });
105
+ // Wait briefly for a your_turn (catch-up), or emit "waiting"
106
+ yield* Effect.gen(function* () {
107
+ for (;;) {
108
+ const msg = yield* Queue.take(conn.inbox);
109
+ if (msg.type === "your_turn") {
110
+ emit({
111
+ status: "your_turn",
112
+ tableId: msg.tableId,
113
+ handId: msg.handId,
114
+ state: msg.state,
115
+ });
116
+ return;
117
+ }
118
+ }
119
+ }).pipe(Effect.timeout(Duration.millis(2000)), Effect.catchAll(() => Effect.sync(() => {
120
+ emit({ status: "waiting", tableId: opts.table });
121
+ })));
122
+ }));
123
+ export const wait = (opts) => runOneshot(opts.server, opts.token, (conn) => Effect.gen(function* () {
124
+ yield* sendOrFail(conn, { type: "spectate", tableId: opts.table });
125
+ return yield* Effect.gen(function* () {
126
+ for (;;) {
127
+ const msg = yield* Queue.take(conn.inbox);
128
+ if (msg.type === "your_turn") {
129
+ emit({
130
+ event: "your_turn",
131
+ tableId: msg.tableId,
132
+ handId: msg.handId,
133
+ state: msg.state,
134
+ });
135
+ return EXIT_SUCCESS;
136
+ }
137
+ if (msg.type === "game_event") {
138
+ emit({
139
+ event: "game_event",
140
+ tableId: msg.tableId,
141
+ handId: msg.handId,
142
+ tag: msg.event.tag,
143
+ data: msg.event.data,
144
+ seq: msg.seq,
145
+ });
146
+ if (msg.event.tag === "hand_ended") {
147
+ return EXIT_HAND_ENDED;
148
+ }
149
+ continue;
150
+ }
151
+ if (msg.type === "error") {
152
+ emit({ error: msg.code, reason: msg.reason });
153
+ return EXIT_ERROR;
154
+ }
155
+ }
156
+ }).pipe(Effect.timeoutFail({
157
+ onTimeout: () => new CliError("TIMEOUT", `No turn received within ${String(opts.timeout)}s`),
158
+ duration: Duration.seconds(opts.timeout),
159
+ }), Effect.catchAll((err) => {
160
+ if (err._tag === "CliError" && err.code === "TIMEOUT") {
161
+ emit({ error: "TIMEOUT", reason: err.reason });
162
+ return Effect.succeed(EXIT_ERROR);
163
+ }
164
+ return Effect.fail(err);
165
+ }));
166
+ }));
167
+ const buildWireAction = (action, amount) => {
168
+ switch (action) {
169
+ case "fold":
170
+ return Effect.succeed({ tag: "fold" });
171
+ case "check":
172
+ return Effect.succeed({ tag: "check" });
173
+ case "call":
174
+ return Effect.succeed({ tag: "call" });
175
+ case "bet": {
176
+ if (amount == null)
177
+ return Effect.fail(new CliError("MISSING_AMOUNT", "--amount is required for bet"));
178
+ return Effect.succeed({ tag: "bet", amount });
179
+ }
180
+ case "raise": {
181
+ if (amount == null)
182
+ return Effect.fail(new CliError("MISSING_AMOUNT", "--amount is required for raise"));
183
+ return Effect.succeed({ tag: "raise", amount });
184
+ }
185
+ case "allin":
186
+ return Effect.succeed({ tag: "allin" });
187
+ default:
188
+ return Effect.fail(new CliError("INVALID_ACTION", `Unknown action: ${action}. Valid: fold|check|call|bet|raise|allin`));
189
+ }
190
+ };
191
+ export const act = (opts) => Effect.gen(function* () {
192
+ const wireAction = yield* buildWireAction(opts.action, opts.amount);
193
+ return yield* runOneshot(opts.server, opts.token, (conn) => Effect.gen(function* () {
194
+ if (!opts.wait) {
195
+ // Simple mode: send action, wait for ack, exit
196
+ yield* sendOrFail(conn, {
197
+ type: "action",
198
+ tableId: opts.table,
199
+ action: wireAction,
200
+ });
201
+ const ackMsg = yield* takeMatching(conn.inbox, (m) => m.type === "action_ack" || m.type === "error");
202
+ if (ackMsg.type === "error") {
203
+ emit({ error: ackMsg.code, reason: ackMsg.reason });
204
+ return EXIT_ERROR;
205
+ }
206
+ emit({ event: "action_ack", tableId: opts.table });
207
+ return EXIT_SUCCESS;
208
+ }
209
+ // --wait mode: send action, listen for ack then your_turn/hand_ended
210
+ yield* sendOrFail(conn, {
211
+ type: "action",
212
+ tableId: opts.table,
213
+ action: wireAction,
214
+ });
215
+ let gotAck = false;
216
+ return yield* Effect.gen(function* () {
217
+ for (;;) {
218
+ const msg = yield* Queue.take(conn.inbox);
219
+ if (msg.type === "action_ack") {
220
+ gotAck = true;
221
+ emit({ event: "action_ack", tableId: opts.table });
222
+ // After ack, subscribe for catch-up
223
+ Effect.runFork(conn.send({ type: "spectate", tableId: opts.table }));
224
+ continue;
225
+ }
226
+ if (msg.type === "your_turn") {
227
+ emit({
228
+ event: "your_turn",
229
+ tableId: msg.tableId,
230
+ handId: msg.handId,
231
+ state: msg.state,
232
+ });
233
+ return EXIT_SUCCESS;
234
+ }
235
+ if (msg.type === "game_event") {
236
+ emit({
237
+ event: "game_event",
238
+ tableId: msg.tableId,
239
+ handId: msg.handId,
240
+ tag: msg.event.tag,
241
+ data: msg.event.data,
242
+ seq: msg.seq,
243
+ });
244
+ if (msg.event.tag === "hand_ended") {
245
+ return EXIT_HAND_ENDED;
246
+ }
247
+ continue;
248
+ }
249
+ if (msg.type === "error") {
250
+ if (!gotAck) {
251
+ emit({ error: msg.code, reason: msg.reason });
252
+ }
253
+ return EXIT_ERROR;
254
+ }
255
+ }
256
+ }).pipe(Effect.timeoutFail({
257
+ onTimeout: () => new CliError("TIMEOUT", `No turn received within ${String(opts.timeout)}s`),
258
+ duration: Duration.seconds(opts.timeout),
259
+ }), Effect.catchAll((err) => {
260
+ if (err._tag === "CliError" && err.code === "TIMEOUT") {
261
+ emit({ error: "TIMEOUT", reason: err.reason });
262
+ return Effect.succeed(EXIT_ERROR);
263
+ }
264
+ return Effect.fail(err);
265
+ }));
266
+ }));
267
+ });
268
+ //# sourceMappingURL=oneshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oneshot.js","sourceRoot":"","sources":["../src/oneshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ClientMessage } from "@coldbluff/protocol";
2
+ type ClientMsg = typeof ClientMessage.Type;
3
+ export interface ParseResult {
4
+ msg?: ClientMsg;
5
+ error?: string;
6
+ help?: string;
7
+ }
8
+ export declare function parseHumanCommand(input: string, currentTableId: string | null): ParseResult;
9
+ export {};
10
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,KAAK,SAAS,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAI3C,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,CA2F3F"}
package/dist/parser.js ADDED
@@ -0,0 +1,93 @@
1
+ const DEFAULT_BUY_IN = 1000;
2
+ export function parseHumanCommand(input, currentTableId) {
3
+ const trimmed = input.trim();
4
+ const parts = trimmed.split(/\s+/);
5
+ const cmd = parts[0]?.toLowerCase();
6
+ switch (cmd) {
7
+ case "tables":
8
+ case "list":
9
+ return { msg: { type: "list_tables" } };
10
+ case "quickseat": {
11
+ const tierId = parts[1];
12
+ if (!tierId)
13
+ return { error: "Usage: quickseat <tierId>" };
14
+ return { msg: { type: "quick_seat", tierId } };
15
+ }
16
+ case "tiers":
17
+ return { msg: { type: "list_tiers" } };
18
+ case "join": {
19
+ const tableId = parts[1];
20
+ if (!tableId)
21
+ return { error: "Usage: join <tableId> [seat] [buyIn]" };
22
+ const seat = parseInt(parts[2] ?? "0", 10);
23
+ if (Number.isNaN(seat))
24
+ return { error: "Invalid seat number" };
25
+ const buyIn = parseInt(parts[3] ?? String(DEFAULT_BUY_IN), 10);
26
+ if (Number.isNaN(buyIn))
27
+ return { error: "Invalid buy-in amount" };
28
+ return { msg: { type: "join_table", tableId, seatIndex: seat, buyIn } };
29
+ }
30
+ case "leave": {
31
+ const tableId = parts[1] ?? currentTableId;
32
+ if (!tableId)
33
+ return { error: "Not at a table. Usage: leave <tableId>" };
34
+ return { msg: { type: "leave_table", tableId } };
35
+ }
36
+ case "spectate": {
37
+ const tableId = parts[1] ?? currentTableId;
38
+ if (!tableId)
39
+ return { error: "Usage: spectate <tableId>" };
40
+ return { msg: { type: "spectate", tableId } };
41
+ }
42
+ case "fold":
43
+ if (!currentTableId)
44
+ return { error: "Not at a table" };
45
+ return { msg: { type: "action", tableId: currentTableId, action: { tag: "fold" } } };
46
+ case "check":
47
+ if (!currentTableId)
48
+ return { error: "Not at a table" };
49
+ return { msg: { type: "action", tableId: currentTableId, action: { tag: "check" } } };
50
+ case "call":
51
+ if (!currentTableId)
52
+ return { error: "Not at a table" };
53
+ return { msg: { type: "action", tableId: currentTableId, action: { tag: "call" } } };
54
+ case "bet": {
55
+ if (!currentTableId)
56
+ return { error: "Not at a table" };
57
+ const amount = parseInt(parts[1] ?? "0", 10);
58
+ if (Number.isNaN(amount) || amount <= 0)
59
+ return { error: "Usage: bet <amount>" };
60
+ return { msg: { type: "action", tableId: currentTableId, action: { tag: "bet", amount } } };
61
+ }
62
+ case "raise": {
63
+ if (!currentTableId)
64
+ return { error: "Not at a table" };
65
+ const amount = parseInt(parts[1] ?? "0", 10);
66
+ if (Number.isNaN(amount) || amount <= 0)
67
+ return { error: "Usage: raise <amount>" };
68
+ return { msg: { type: "action", tableId: currentTableId, action: { tag: "raise", amount } } };
69
+ }
70
+ case "allin":
71
+ if (!currentTableId)
72
+ return { error: "Not at a table" };
73
+ return { msg: { type: "action", tableId: currentTableId, action: { tag: "allin" } } };
74
+ case "chat": {
75
+ if (!currentTableId)
76
+ return { error: "Not at a table" };
77
+ const message = parts.slice(1).join(" ");
78
+ if (!message)
79
+ return { error: "Usage: chat <message>" };
80
+ return { msg: { type: "chat", tableId: currentTableId, message } };
81
+ }
82
+ case "ping":
83
+ return { msg: { type: "ping" } };
84
+ case "help":
85
+ return { help: "Commands: tables, tiers, quickseat <tierId>, join <tableId> [seat] [buyIn], leave, spectate [tableId], fold, check, call, bet <amount>, raise <amount>, allin, chat <message>, ping" };
86
+ case "":
87
+ case undefined:
88
+ return { error: "Empty command. Type 'help' for available commands." };
89
+ default:
90
+ return { error: `Unknown command: ${cmd}. Type 'help' for available commands.` };
91
+ }
92
+ }
93
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { Socket } from "@effect/platform";
2
+ import { Effect, Queue, Scope } from "effect";
3
+ import { ClientMessage, ServerMessage } from "@coldbluff/protocol";
4
+ type ClientMsg = typeof ClientMessage.Type;
5
+ type ServerMsg = typeof ServerMessage.Type;
6
+ export interface WsConnection {
7
+ readonly send: (msg: ClientMsg) => Effect.Effect<void, Socket.SocketError>;
8
+ readonly inbox: Queue.Queue<ServerMsg>;
9
+ }
10
+ /** Create a scoped WebSocket connection. Cleaned up when the scope closes. */
11
+ export declare const makeConnection: (url: string) => Effect.Effect<WsConnection, Socket.SocketError, Scope.Scope>;
12
+ export interface WsClient {
13
+ readonly send: (msg: ClientMsg) => void;
14
+ readonly onMessage: (handler: (msg: ServerMsg) => void) => void;
15
+ readonly onClose: (handler: () => void) => void;
16
+ readonly onError: (handler: (err: Error) => void) => void;
17
+ readonly close: () => void;
18
+ }
19
+ /** Callback-style connect for json-lines and human-mode. */
20
+ export declare function connect(url: string): Promise<WsClient>;
21
+ export {};
22
+ //# sourceMappingURL=ws-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-client.d.ts","sourceRoot":"","sources":["../src/ws-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAU,MAAM,EAAE,KAAK,EAAE,KAAK,EAAQ,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEnE,KAAK,SAAS,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAC3C,KAAK,SAAS,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAO3C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAC3E,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;CACxC;AAED,8EAA8E;AAC9E,eAAO,MAAM,cAAc,GACzB,KAAK,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAiCC,CAAC;AAIhE,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,KAAK,IAAI,CAAC;IAChE,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,KAAK,IAAI,CAAC;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,4DAA4D;AAC5D,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CA6FtD"}
@@ -0,0 +1,117 @@
1
+ import { Socket } from "@effect/platform";
2
+ import { NodeSocket } from "@effect/platform-node";
3
+ import { Schema, Effect, Queue } from "effect";
4
+ import { ClientMessage, ServerMessage } from "@coldbluff/protocol";
5
+ const encodeClient = Schema.encodeSync(ClientMessage);
6
+ const decodeServer = Schema.decodeUnknownEither(ServerMessage);
7
+ /** Create a scoped WebSocket connection. Cleaned up when the scope closes. */
8
+ export const makeConnection = (url) => Effect.gen(function* () {
9
+ const socket = yield* Socket.makeWebSocket(url, {
10
+ openTimeout: "10 seconds",
11
+ });
12
+ const write = yield* socket.writer;
13
+ const inbox = yield* Queue.unbounded();
14
+ yield* Effect.forkScoped(socket
15
+ .runRaw((data) => Effect.gen(function* () {
16
+ if (typeof data !== "string")
17
+ return;
18
+ let parsed;
19
+ try {
20
+ parsed = JSON.parse(data);
21
+ }
22
+ catch {
23
+ return;
24
+ }
25
+ const decoded = decodeServer(parsed);
26
+ if (decoded._tag === "Right") {
27
+ yield* Queue.offer(inbox, decoded.right);
28
+ }
29
+ // Schema decode failures are dropped — no silent bypass (fixes C1)
30
+ }))
31
+ .pipe(Effect.ensuring(Queue.shutdown(inbox))));
32
+ return {
33
+ send: (msg) => write(JSON.stringify(encodeClient(msg))),
34
+ inbox,
35
+ };
36
+ }).pipe(Effect.provide(NodeSocket.layerWebSocketConstructor));
37
+ /** Callback-style connect for json-lines and human-mode. */
38
+ export function connect(url) {
39
+ return new Promise((resolve, reject) => {
40
+ const messageHandlers = [];
41
+ const closeHandlers = [];
42
+ const errorHandlers = [];
43
+ let writeFn;
44
+ let resolved = false;
45
+ const program = Effect.scoped(Effect.gen(function* () {
46
+ const socket = yield* Socket.makeWebSocket(url, {
47
+ openTimeout: "10 seconds",
48
+ });
49
+ const write = yield* socket.writer;
50
+ writeFn = write;
51
+ yield* socket.runRaw((data) => Effect.gen(function* () {
52
+ if (typeof data !== "string")
53
+ return;
54
+ let parsed;
55
+ try {
56
+ parsed = JSON.parse(data);
57
+ }
58
+ catch {
59
+ return;
60
+ }
61
+ const decoded = decodeServer(parsed);
62
+ if (decoded._tag === "Right") {
63
+ for (const h of messageHandlers)
64
+ h(decoded.right);
65
+ }
66
+ // Schema decode failures are dropped — no silent bypass (fixes C1)
67
+ }), {
68
+ onOpen: Effect.sync(() => {
69
+ resolved = true;
70
+ const client = {
71
+ send(msg) {
72
+ if (writeFn) {
73
+ Effect.runFork(writeFn(JSON.stringify(encodeClient(msg))).pipe(Effect.catchAll((err) => Effect.sync(() => {
74
+ for (const h of errorHandlers)
75
+ h(new Error(String(err)));
76
+ }))));
77
+ }
78
+ },
79
+ onMessage(handler) {
80
+ messageHandlers.push(handler);
81
+ },
82
+ onClose(handler) {
83
+ closeHandlers.push(handler);
84
+ },
85
+ onError(handler) {
86
+ errorHandlers.push(handler);
87
+ },
88
+ close() {
89
+ if (writeFn) {
90
+ Effect.runFork(writeFn(new Socket.CloseEvent(1000)));
91
+ }
92
+ },
93
+ };
94
+ resolve(client);
95
+ }),
96
+ });
97
+ })).pipe(Effect.provide(NodeSocket.layerWebSocketConstructor), Effect.match({
98
+ onSuccess: () => {
99
+ for (const h of closeHandlers)
100
+ h();
101
+ },
102
+ onFailure: (err) => {
103
+ if (!resolved) {
104
+ reject(new Error(String(err)));
105
+ }
106
+ else {
107
+ for (const h of errorHandlers)
108
+ h(new Error(String(err)));
109
+ for (const h of closeHandlers)
110
+ h();
111
+ }
112
+ },
113
+ }));
114
+ Effect.runFork(program);
115
+ });
116
+ }
117
+ //# sourceMappingURL=ws-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-client.js","sourceRoot":"","sources":["../src/ws-client.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "coldbluff",
3
+ "version": "0.1.0",
4
+ "description": "Coldbluff poker CLI for AI agents and humans",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/BinyaminEden/Coldbluff.git",
10
+ "directory": "apps/cli"
11
+ },
12
+ "keywords": [
13
+ "poker",
14
+ "cli",
15
+ "ai",
16
+ "coldbluff"
17
+ ],
18
+ "bin": {
19
+ "coldbluff": "./bin/coldbluff.js"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "bin"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc -b",
27
+ "bundle": "tsup",
28
+ "typecheck": "tsc --noEmit",
29
+ "test": "vitest run",
30
+ "lint": "echo 'lint ok'"
31
+ },
32
+ "dependencies": {
33
+ "commander": "^12.0.0",
34
+ "effect": "^3.12.0",
35
+ "ws": "^8.18.0"
36
+ },
37
+ "devDependencies": {
38
+ "@coldbluff/protocol": "workspace:*",
39
+ "@types/node": "^22.0.0",
40
+ "@types/ws": "^8.5.0",
41
+ "tsup": "^8.5.1",
42
+ "tsx": "^4.0.0",
43
+ "typescript": "^5.7.0",
44
+ "vitest": "^3.0.0"
45
+ }
46
+ }