@gonzih/cc-wire 0.2.0 → 0.3.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/README.md +56 -6
- package/dist/cjs/index.cjs +1 -0
- package/dist/cjs/runtime.cjs +166 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/runtime.d.ts +90 -0
- package/dist/esm/runtime.d.ts.map +1 -0
- package/dist/esm/runtime.js +164 -0
- package/dist/esm/runtime.js.map +1 -0
- package/package.json +16 -3
package/README.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# @gonzih/cc-wire
|
|
2
2
|
|
|
3
|
-
Single source of truth for Redis channel names, key patterns,
|
|
3
|
+
Single source of truth for Redis channel names, key patterns, message shapes, and
|
|
4
|
+
storage runtime across the cc-suite (`cc-agent`, `cc-discord`, `cc-tg`, `cc-agent-ui`).
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
v0.3.0+: ships a typed storage runtime — services call `createCcWire(redis)` and
|
|
7
|
+
never touch raw Redis or import key builders directly.
|
|
6
8
|
|
|
7
9
|
## Install
|
|
8
10
|
|
|
9
11
|
```sh
|
|
10
|
-
npm install @gonzih/cc-wire
|
|
12
|
+
npm install @gonzih/cc-wire ioredis
|
|
11
13
|
```
|
|
12
14
|
|
|
13
15
|
## Architecture — Service Ownership
|
|
@@ -39,7 +41,53 @@ npm install @gonzih/cc-wire
|
|
|
39
41
|
no sessions, and no state. cc-agent is a pure job runner; it no longer manages meta-agent
|
|
40
42
|
lifecycle.
|
|
41
43
|
|
|
42
|
-
##
|
|
44
|
+
## Runtime — `createCcWire(redis)`
|
|
45
|
+
|
|
46
|
+
Pass an [ioredis](https://github.com/redis/ioredis) `Redis` instance and get back
|
|
47
|
+
fully-typed storage APIs per service. No raw Redis commands, no key string management.
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { createClient } from "ioredis";
|
|
51
|
+
import { createCcWire } from "@gonzih/cc-wire";
|
|
52
|
+
|
|
53
|
+
const redis = new Redis(process.env.REDIS_URL);
|
|
54
|
+
const wire = createCcWire(redis);
|
|
55
|
+
|
|
56
|
+
// cc-discord: per-namespace session management
|
|
57
|
+
await wire.discord.enqueue("simorgh", { id: "...", source: "discord", ... });
|
|
58
|
+
const msg = await wire.discord.dequeue("simorgh"); // ChatMessage | null
|
|
59
|
+
await wire.discord.publishOutgoing("simorgh", msg); // PUBLISH + log + LTRIM
|
|
60
|
+
wire.discord.subscribeOutgoing("simorgh", (msg) => console.log(msg)); // live stream
|
|
61
|
+
await wire.discord.setStatus("simorgh", { isTyping: true, ... });
|
|
62
|
+
const status = await wire.discord.getStatus("simorgh"); // MetaAgentStatus | null
|
|
63
|
+
await wire.discord.writeChatLog("simorgh", msg);
|
|
64
|
+
const history = await wire.discord.getChatLog("simorgh", 50); // chronological
|
|
65
|
+
await wire.discord.notify("simorgh", { text: "job done" });
|
|
66
|
+
const notif = await wire.discord.pollNotify("simorgh"); // NotificationPayload | null
|
|
67
|
+
await wire.discord.registerChannel("1234567890", "simorgh", repoUrl);
|
|
68
|
+
const chan = await wire.discord.getChannel("1234567890");
|
|
69
|
+
const channels = await wire.discord.listChannels();
|
|
70
|
+
|
|
71
|
+
// cc-tg: single money-brain session
|
|
72
|
+
await wire.tg.publishOutgoing(msg);
|
|
73
|
+
wire.tg.subscribeOutgoing((msg) => console.log(msg));
|
|
74
|
+
await wire.tg.notify({ text: "job done" });
|
|
75
|
+
const tgNotif = await wire.tg.pollNotify();
|
|
76
|
+
|
|
77
|
+
// cc-agent: job queue
|
|
78
|
+
await wire.jobs.enqueue({ id: "job-001", repoUrl: "...", task: "..." });
|
|
79
|
+
const job = await wire.jobs.getStatus("job-001");
|
|
80
|
+
await wire.jobs.publishDone("job-001", { status: "done", score: 1.0 });
|
|
81
|
+
|
|
82
|
+
// shared master token
|
|
83
|
+
await wire.token.setMaster("my-token");
|
|
84
|
+
const token = await wire.token.getMaster();
|
|
85
|
+
|
|
86
|
+
// raw redis escape hatch (migration only)
|
|
87
|
+
const raw = wire._redis;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Key builders (v0.2.x compat, use runtime in new code)
|
|
43
91
|
|
|
44
92
|
```typescript
|
|
45
93
|
import {
|
|
@@ -241,8 +289,10 @@ The deprecated exports remain in v0.2.x for migration; they will be removed in v
|
|
|
241
289
|
## Development
|
|
242
290
|
|
|
243
291
|
```sh
|
|
244
|
-
npm run build
|
|
245
|
-
npm test
|
|
292
|
+
npm run build # compile ESM + CJS
|
|
293
|
+
npm test # run all tests (channels: node --test; runtime: vitest)
|
|
294
|
+
npm run test:channels # key builder tests only (node --test + tsx)
|
|
295
|
+
npm run test:runtime # runtime tests only (vitest + ioredis-mock)
|
|
246
296
|
```
|
|
247
297
|
|
|
248
298
|
## License
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -24,3 +24,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
__exportStar(require("./channels.cjs"), exports);
|
|
26
26
|
__exportStar(require("./types.cjs"), exports);
|
|
27
|
+
__exportStar(require("./runtime.cjs"), exports);
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCcWire = createCcWire;
|
|
4
|
+
const channels_js_1 = require("./channels.cjs");
|
|
5
|
+
// ─── Private key helpers (not exported) ──────────────────────────────────────
|
|
6
|
+
const channelHashKey = (channelId) => `cca:discord:channel:${channelId}`;
|
|
7
|
+
const CHANNELS_SET = "cca:discord:channels:index";
|
|
8
|
+
const discordNotifyLogKey = (ns) => `cca:discord:notify-log:${ns}`;
|
|
9
|
+
const TG_NOTIFY_LOG = "cca:tg:notify-log";
|
|
10
|
+
const SPAWN_QUEUE = "cca:spawn:queue";
|
|
11
|
+
const MASTER_TOKEN_KEY = "cca:token:master";
|
|
12
|
+
// ─── Factory ──────────────────────────────────────────────────────────────────
|
|
13
|
+
function createCcWire(redis) {
|
|
14
|
+
return {
|
|
15
|
+
// ── discord ──────────────────────────────────────────────────────────────
|
|
16
|
+
discord: {
|
|
17
|
+
async enqueue(ns, msg) {
|
|
18
|
+
await redis.rpush((0, channels_js_1.discordMetaInputKey)(ns), JSON.stringify(msg));
|
|
19
|
+
},
|
|
20
|
+
async dequeue(ns) {
|
|
21
|
+
const val = await redis.rpop((0, channels_js_1.discordMetaInputKey)(ns));
|
|
22
|
+
return val ? JSON.parse(val) : null;
|
|
23
|
+
},
|
|
24
|
+
async publishOutgoing(ns, msg) {
|
|
25
|
+
const json = JSON.stringify(msg);
|
|
26
|
+
const pl = redis.pipeline();
|
|
27
|
+
pl.publish((0, channels_js_1.discordChatOutgoing)(ns), json);
|
|
28
|
+
pl.lpush((0, channels_js_1.discordChatLog)(ns), json);
|
|
29
|
+
pl.ltrim((0, channels_js_1.discordChatLog)(ns), 0, channels_js_1.CAP.CHAT_LOG - 1);
|
|
30
|
+
await pl.exec();
|
|
31
|
+
},
|
|
32
|
+
subscribeOutgoing(ns, cb) {
|
|
33
|
+
const sub = redis.duplicate();
|
|
34
|
+
sub.subscribe((0, channels_js_1.discordChatOutgoing)(ns));
|
|
35
|
+
sub.on("message", (channel, message) => {
|
|
36
|
+
if (channel === (0, channels_js_1.discordChatOutgoing)(ns)) {
|
|
37
|
+
cb(JSON.parse(message));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
async setStatus(ns, status) {
|
|
42
|
+
await redis.set((0, channels_js_1.discordMetaStatusKey)(ns), JSON.stringify(status), "EX", channels_js_1.TTL.JOB_SECONDS);
|
|
43
|
+
},
|
|
44
|
+
async getStatus(ns) {
|
|
45
|
+
const val = await redis.get((0, channels_js_1.discordMetaStatusKey)(ns));
|
|
46
|
+
return val ? JSON.parse(val) : null;
|
|
47
|
+
},
|
|
48
|
+
async writeChatLog(ns, msg) {
|
|
49
|
+
const pl = redis.pipeline();
|
|
50
|
+
pl.lpush((0, channels_js_1.discordChatLog)(ns), JSON.stringify(msg));
|
|
51
|
+
pl.ltrim((0, channels_js_1.discordChatLog)(ns), 0, channels_js_1.CAP.CHAT_LOG - 1);
|
|
52
|
+
await pl.exec();
|
|
53
|
+
},
|
|
54
|
+
async getChatLog(ns, limit = 50) {
|
|
55
|
+
const items = await redis.lrange((0, channels_js_1.discordChatLog)(ns), 0, limit - 1);
|
|
56
|
+
return items
|
|
57
|
+
.map((i) => JSON.parse(i))
|
|
58
|
+
.reverse();
|
|
59
|
+
},
|
|
60
|
+
async notify(ns, payload) {
|
|
61
|
+
const json = JSON.stringify(payload);
|
|
62
|
+
const pl = redis.pipeline();
|
|
63
|
+
pl.publish((0, channels_js_1.discordNotify)(ns), json);
|
|
64
|
+
pl.rpush((0, channels_js_1.discordNotify)(ns), json);
|
|
65
|
+
pl.lpush(discordNotifyLogKey(ns), json);
|
|
66
|
+
pl.ltrim(discordNotifyLogKey(ns), 0, channels_js_1.CAP.NOTIFY_LOG - 1);
|
|
67
|
+
await pl.exec();
|
|
68
|
+
},
|
|
69
|
+
async pollNotify(ns) {
|
|
70
|
+
const val = await redis.rpop((0, channels_js_1.discordNotify)(ns));
|
|
71
|
+
return val ? JSON.parse(val) : null;
|
|
72
|
+
},
|
|
73
|
+
async registerChannel(channelId, ns, repoUrl) {
|
|
74
|
+
const pl = redis.pipeline();
|
|
75
|
+
pl.hset(channelHashKey(channelId), { namespace: ns, repoUrl });
|
|
76
|
+
pl.sadd(CHANNELS_SET, channelId);
|
|
77
|
+
await pl.exec();
|
|
78
|
+
},
|
|
79
|
+
async getChannel(channelId) {
|
|
80
|
+
const data = await redis.hgetall(channelHashKey(channelId));
|
|
81
|
+
if (!data || !data["namespace"])
|
|
82
|
+
return null;
|
|
83
|
+
return { namespace: data["namespace"], repoUrl: data["repoUrl"] ?? "" };
|
|
84
|
+
},
|
|
85
|
+
async listChannels() {
|
|
86
|
+
const ids = await redis.smembers(CHANNELS_SET);
|
|
87
|
+
const rows = await Promise.all(ids.map(async (channelId) => {
|
|
88
|
+
const data = await redis.hgetall(channelHashKey(channelId));
|
|
89
|
+
if (!data || !data["namespace"])
|
|
90
|
+
return null;
|
|
91
|
+
return {
|
|
92
|
+
channelId,
|
|
93
|
+
namespace: data["namespace"],
|
|
94
|
+
repoUrl: data["repoUrl"] ?? "",
|
|
95
|
+
};
|
|
96
|
+
}));
|
|
97
|
+
return rows.filter((r) => r !== null);
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
// ── tg ───────────────────────────────────────────────────────────────────
|
|
101
|
+
tg: {
|
|
102
|
+
async publishOutgoing(msg) {
|
|
103
|
+
const json = JSON.stringify(msg);
|
|
104
|
+
const pl = redis.pipeline();
|
|
105
|
+
pl.publish((0, channels_js_1.tgChatOutgoing)(), json);
|
|
106
|
+
pl.lpush("cca:tg:chat:log", json);
|
|
107
|
+
pl.ltrim("cca:tg:chat:log", 0, channels_js_1.CAP.CHAT_LOG - 1);
|
|
108
|
+
await pl.exec();
|
|
109
|
+
},
|
|
110
|
+
subscribeOutgoing(cb) {
|
|
111
|
+
const sub = redis.duplicate();
|
|
112
|
+
sub.subscribe((0, channels_js_1.tgChatOutgoing)());
|
|
113
|
+
sub.on("message", (_channel, message) => {
|
|
114
|
+
cb(JSON.parse(message));
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
async notify(payload) {
|
|
118
|
+
const json = JSON.stringify(payload);
|
|
119
|
+
const pl = redis.pipeline();
|
|
120
|
+
pl.publish((0, channels_js_1.tgNotify)(), json);
|
|
121
|
+
pl.rpush((0, channels_js_1.tgNotify)(), json);
|
|
122
|
+
pl.lpush(TG_NOTIFY_LOG, json);
|
|
123
|
+
pl.ltrim(TG_NOTIFY_LOG, 0, channels_js_1.CAP.NOTIFY_LOG - 1);
|
|
124
|
+
await pl.exec();
|
|
125
|
+
},
|
|
126
|
+
async pollNotify() {
|
|
127
|
+
const val = await redis.rpop((0, channels_js_1.tgNotify)());
|
|
128
|
+
return val ? JSON.parse(val) : null;
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
// ── jobs ─────────────────────────────────────────────────────────────────
|
|
132
|
+
jobs: {
|
|
133
|
+
async enqueue(job) {
|
|
134
|
+
const pl = redis.pipeline();
|
|
135
|
+
pl.set((0, channels_js_1.jobKey)(job.id), JSON.stringify({ ...job, status: "pending" }), "EX", channels_js_1.TTL.JOB_SECONDS);
|
|
136
|
+
pl.lpush(SPAWN_QUEUE, JSON.stringify(job));
|
|
137
|
+
await pl.exec();
|
|
138
|
+
},
|
|
139
|
+
async getStatus(jobId) {
|
|
140
|
+
const val = await redis.get((0, channels_js_1.jobKey)(jobId));
|
|
141
|
+
return val ? JSON.parse(val) : null;
|
|
142
|
+
},
|
|
143
|
+
async publishDone(jobId, result) {
|
|
144
|
+
const json = JSON.stringify(result);
|
|
145
|
+
const pl = redis.pipeline();
|
|
146
|
+
pl.publish((0, channels_js_1.jobDoneChannel)(jobId), json);
|
|
147
|
+
pl.lpush((0, channels_js_1.jobDoneQueueKey)(jobId), json);
|
|
148
|
+
pl.expire((0, channels_js_1.jobDoneQueueKey)(jobId), channels_js_1.TTL.JOB_SECONDS);
|
|
149
|
+
await pl.exec();
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
// ── token ─────────────────────────────────────────────────────────────────
|
|
153
|
+
token: {
|
|
154
|
+
async getMaster() {
|
|
155
|
+
const val = await redis.get(MASTER_TOKEN_KEY);
|
|
156
|
+
if (val === null)
|
|
157
|
+
throw new Error("cc-wire: master token not set");
|
|
158
|
+
return val;
|
|
159
|
+
},
|
|
160
|
+
async setMaster(token) {
|
|
161
|
+
await redis.set(MASTER_TOKEN_KEY, token);
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
_redis: redis,
|
|
165
|
+
};
|
|
166
|
+
}
|
package/dist/esm/index.d.ts
CHANGED
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
|
package/dist/esm/index.js
CHANGED
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cc-wire runtime — `createCcWire(redis)`
|
|
3
|
+
*
|
|
4
|
+
* The single entry point for all Redis I/O across the cc-suite.
|
|
5
|
+
* Services import this factory and call typed methods; they never
|
|
6
|
+
* write raw Redis commands or import key builders directly.
|
|
7
|
+
*/
|
|
8
|
+
import type { Redis } from "ioredis";
|
|
9
|
+
import type { ChatMessage, MetaAgentStatus, NotificationPayload, SpawnParams } from "./types.js";
|
|
10
|
+
export interface DiscordApi {
|
|
11
|
+
/** RPUSH message to the input queue for a namespace session. */
|
|
12
|
+
enqueue(ns: string, msg: ChatMessage): Promise<void>;
|
|
13
|
+
/** RPOP next message from the input queue; null when empty. */
|
|
14
|
+
dequeue(ns: string): Promise<ChatMessage | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Pipeline: PUBLISH to outgoing channel + LPUSH to chat log + LTRIM.
|
|
17
|
+
* Subscribers on the channel receive the message live; the log persists it.
|
|
18
|
+
*/
|
|
19
|
+
publishOutgoing(ns: string, msg: ChatMessage): Promise<void>;
|
|
20
|
+
/** Subscribe to outgoing messages for a namespace. Uses an internal duplicate connection. */
|
|
21
|
+
subscribeOutgoing(ns: string, cb: (msg: ChatMessage) => void): void;
|
|
22
|
+
/** SET session status with 7-day TTL. */
|
|
23
|
+
setStatus(ns: string, status: MetaAgentStatus): Promise<void>;
|
|
24
|
+
/** GET session status; null when key is absent or expired. */
|
|
25
|
+
getStatus(ns: string): Promise<MetaAgentStatus | null>;
|
|
26
|
+
/** LPUSH message to chat log + LTRIM to 500. */
|
|
27
|
+
writeChatLog(ns: string, msg: ChatMessage): Promise<void>;
|
|
28
|
+
/** LRANGE chat log, reversed to chronological order. Default limit 50. */
|
|
29
|
+
getChatLog(ns: string, limit?: number): Promise<ChatMessage[]>;
|
|
30
|
+
/** PUBLISH notify channel + RPUSH delivery list + log. */
|
|
31
|
+
notify(ns: string, payload: NotificationPayload): Promise<void>;
|
|
32
|
+
/** RPOP from notify delivery list; null when empty. */
|
|
33
|
+
pollNotify(ns: string): Promise<NotificationPayload | null>;
|
|
34
|
+
/** Register a Discord channel → namespace mapping. */
|
|
35
|
+
registerChannel(channelId: string, ns: string, repoUrl: string): Promise<void>;
|
|
36
|
+
/** Look up a channel registration; null if not found. */
|
|
37
|
+
getChannel(channelId: string): Promise<{
|
|
38
|
+
namespace: string;
|
|
39
|
+
repoUrl: string;
|
|
40
|
+
} | null>;
|
|
41
|
+
/** List all registered channel mappings. */
|
|
42
|
+
listChannels(): Promise<Array<{
|
|
43
|
+
channelId: string;
|
|
44
|
+
namespace: string;
|
|
45
|
+
repoUrl: string;
|
|
46
|
+
}>>;
|
|
47
|
+
}
|
|
48
|
+
export interface TgApi {
|
|
49
|
+
/** Pipeline: PUBLISH to outgoing channel + LPUSH log + LTRIM. */
|
|
50
|
+
publishOutgoing(msg: ChatMessage): Promise<void>;
|
|
51
|
+
/** Subscribe to outgoing messages. Uses an internal duplicate connection. */
|
|
52
|
+
subscribeOutgoing(cb: (msg: ChatMessage) => void): void;
|
|
53
|
+
/** PUBLISH notify channel + RPUSH delivery list + log. */
|
|
54
|
+
notify(payload: NotificationPayload): Promise<void>;
|
|
55
|
+
/** RPOP from notify delivery list; null when empty. */
|
|
56
|
+
pollNotify(): Promise<NotificationPayload | null>;
|
|
57
|
+
}
|
|
58
|
+
export interface JobsApi {
|
|
59
|
+
/** LPUSH job to spawn queue and write initial job record. */
|
|
60
|
+
enqueue(job: SpawnParams & {
|
|
61
|
+
id: string;
|
|
62
|
+
}): Promise<void>;
|
|
63
|
+
/** GET job record; null when job does not exist. */
|
|
64
|
+
getStatus(jobId: string): Promise<unknown>;
|
|
65
|
+
/** PUBLISH job-done channel + LPUSH to done queue. */
|
|
66
|
+
publishDone(jobId: string, result: unknown): Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
export interface TokenApi {
|
|
69
|
+
/** GET master token; throws if not set. */
|
|
70
|
+
getMaster(): Promise<string>;
|
|
71
|
+
/** SET master token (no TTL). */
|
|
72
|
+
setMaster(token: string): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
export interface CcWire {
|
|
75
|
+
/** cc-discord: per-namespace session management. */
|
|
76
|
+
discord: DiscordApi;
|
|
77
|
+
/** cc-tg: single money-brain session. */
|
|
78
|
+
tg: TgApi;
|
|
79
|
+
/** cc-agent: job queue. */
|
|
80
|
+
jobs: JobsApi;
|
|
81
|
+
/** Master token (shared across services). */
|
|
82
|
+
token: TokenApi;
|
|
83
|
+
/**
|
|
84
|
+
* Raw redis client escape hatch — for migration only.
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
87
|
+
_redis: Redis;
|
|
88
|
+
}
|
|
89
|
+
export declare function createCcWire(redis: Redis): CcWire;
|
|
90
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { discordMetaInputKey, discordMetaStatusKey, discordChatOutgoing, discordChatLog, discordNotify, tgChatOutgoing, tgNotify, jobKey, jobDoneChannel, jobDoneQueueKey, CAP, TTL, } from "./channels.js";
|
|
2
|
+
// ─── Private key helpers (not exported) ──────────────────────────────────────
|
|
3
|
+
const channelHashKey = (channelId) => `cca:discord:channel:${channelId}`;
|
|
4
|
+
const CHANNELS_SET = "cca:discord:channels:index";
|
|
5
|
+
const discordNotifyLogKey = (ns) => `cca:discord:notify-log:${ns}`;
|
|
6
|
+
const TG_NOTIFY_LOG = "cca:tg:notify-log";
|
|
7
|
+
const SPAWN_QUEUE = "cca:spawn:queue";
|
|
8
|
+
const MASTER_TOKEN_KEY = "cca:token:master";
|
|
9
|
+
// ─── Factory ──────────────────────────────────────────────────────────────────
|
|
10
|
+
export function createCcWire(redis) {
|
|
11
|
+
return {
|
|
12
|
+
// ── discord ──────────────────────────────────────────────────────────────
|
|
13
|
+
discord: {
|
|
14
|
+
async enqueue(ns, msg) {
|
|
15
|
+
await redis.rpush(discordMetaInputKey(ns), JSON.stringify(msg));
|
|
16
|
+
},
|
|
17
|
+
async dequeue(ns) {
|
|
18
|
+
const val = await redis.rpop(discordMetaInputKey(ns));
|
|
19
|
+
return val ? JSON.parse(val) : null;
|
|
20
|
+
},
|
|
21
|
+
async publishOutgoing(ns, msg) {
|
|
22
|
+
const json = JSON.stringify(msg);
|
|
23
|
+
const pl = redis.pipeline();
|
|
24
|
+
pl.publish(discordChatOutgoing(ns), json);
|
|
25
|
+
pl.lpush(discordChatLog(ns), json);
|
|
26
|
+
pl.ltrim(discordChatLog(ns), 0, CAP.CHAT_LOG - 1);
|
|
27
|
+
await pl.exec();
|
|
28
|
+
},
|
|
29
|
+
subscribeOutgoing(ns, cb) {
|
|
30
|
+
const sub = redis.duplicate();
|
|
31
|
+
sub.subscribe(discordChatOutgoing(ns));
|
|
32
|
+
sub.on("message", (channel, message) => {
|
|
33
|
+
if (channel === discordChatOutgoing(ns)) {
|
|
34
|
+
cb(JSON.parse(message));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
async setStatus(ns, status) {
|
|
39
|
+
await redis.set(discordMetaStatusKey(ns), JSON.stringify(status), "EX", TTL.JOB_SECONDS);
|
|
40
|
+
},
|
|
41
|
+
async getStatus(ns) {
|
|
42
|
+
const val = await redis.get(discordMetaStatusKey(ns));
|
|
43
|
+
return val ? JSON.parse(val) : null;
|
|
44
|
+
},
|
|
45
|
+
async writeChatLog(ns, msg) {
|
|
46
|
+
const pl = redis.pipeline();
|
|
47
|
+
pl.lpush(discordChatLog(ns), JSON.stringify(msg));
|
|
48
|
+
pl.ltrim(discordChatLog(ns), 0, CAP.CHAT_LOG - 1);
|
|
49
|
+
await pl.exec();
|
|
50
|
+
},
|
|
51
|
+
async getChatLog(ns, limit = 50) {
|
|
52
|
+
const items = await redis.lrange(discordChatLog(ns), 0, limit - 1);
|
|
53
|
+
return items
|
|
54
|
+
.map((i) => JSON.parse(i))
|
|
55
|
+
.reverse();
|
|
56
|
+
},
|
|
57
|
+
async notify(ns, payload) {
|
|
58
|
+
const json = JSON.stringify(payload);
|
|
59
|
+
const pl = redis.pipeline();
|
|
60
|
+
pl.publish(discordNotify(ns), json);
|
|
61
|
+
pl.rpush(discordNotify(ns), json);
|
|
62
|
+
pl.lpush(discordNotifyLogKey(ns), json);
|
|
63
|
+
pl.ltrim(discordNotifyLogKey(ns), 0, CAP.NOTIFY_LOG - 1);
|
|
64
|
+
await pl.exec();
|
|
65
|
+
},
|
|
66
|
+
async pollNotify(ns) {
|
|
67
|
+
const val = await redis.rpop(discordNotify(ns));
|
|
68
|
+
return val ? JSON.parse(val) : null;
|
|
69
|
+
},
|
|
70
|
+
async registerChannel(channelId, ns, repoUrl) {
|
|
71
|
+
const pl = redis.pipeline();
|
|
72
|
+
pl.hset(channelHashKey(channelId), { namespace: ns, repoUrl });
|
|
73
|
+
pl.sadd(CHANNELS_SET, channelId);
|
|
74
|
+
await pl.exec();
|
|
75
|
+
},
|
|
76
|
+
async getChannel(channelId) {
|
|
77
|
+
const data = await redis.hgetall(channelHashKey(channelId));
|
|
78
|
+
if (!data || !data["namespace"])
|
|
79
|
+
return null;
|
|
80
|
+
return { namespace: data["namespace"], repoUrl: data["repoUrl"] ?? "" };
|
|
81
|
+
},
|
|
82
|
+
async listChannels() {
|
|
83
|
+
const ids = await redis.smembers(CHANNELS_SET);
|
|
84
|
+
const rows = await Promise.all(ids.map(async (channelId) => {
|
|
85
|
+
const data = await redis.hgetall(channelHashKey(channelId));
|
|
86
|
+
if (!data || !data["namespace"])
|
|
87
|
+
return null;
|
|
88
|
+
return {
|
|
89
|
+
channelId,
|
|
90
|
+
namespace: data["namespace"],
|
|
91
|
+
repoUrl: data["repoUrl"] ?? "",
|
|
92
|
+
};
|
|
93
|
+
}));
|
|
94
|
+
return rows.filter((r) => r !== null);
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
// ── tg ───────────────────────────────────────────────────────────────────
|
|
98
|
+
tg: {
|
|
99
|
+
async publishOutgoing(msg) {
|
|
100
|
+
const json = JSON.stringify(msg);
|
|
101
|
+
const pl = redis.pipeline();
|
|
102
|
+
pl.publish(tgChatOutgoing(), json);
|
|
103
|
+
pl.lpush("cca:tg:chat:log", json);
|
|
104
|
+
pl.ltrim("cca:tg:chat:log", 0, CAP.CHAT_LOG - 1);
|
|
105
|
+
await pl.exec();
|
|
106
|
+
},
|
|
107
|
+
subscribeOutgoing(cb) {
|
|
108
|
+
const sub = redis.duplicate();
|
|
109
|
+
sub.subscribe(tgChatOutgoing());
|
|
110
|
+
sub.on("message", (_channel, message) => {
|
|
111
|
+
cb(JSON.parse(message));
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
async notify(payload) {
|
|
115
|
+
const json = JSON.stringify(payload);
|
|
116
|
+
const pl = redis.pipeline();
|
|
117
|
+
pl.publish(tgNotify(), json);
|
|
118
|
+
pl.rpush(tgNotify(), json);
|
|
119
|
+
pl.lpush(TG_NOTIFY_LOG, json);
|
|
120
|
+
pl.ltrim(TG_NOTIFY_LOG, 0, CAP.NOTIFY_LOG - 1);
|
|
121
|
+
await pl.exec();
|
|
122
|
+
},
|
|
123
|
+
async pollNotify() {
|
|
124
|
+
const val = await redis.rpop(tgNotify());
|
|
125
|
+
return val ? JSON.parse(val) : null;
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
// ── jobs ─────────────────────────────────────────────────────────────────
|
|
129
|
+
jobs: {
|
|
130
|
+
async enqueue(job) {
|
|
131
|
+
const pl = redis.pipeline();
|
|
132
|
+
pl.set(jobKey(job.id), JSON.stringify({ ...job, status: "pending" }), "EX", TTL.JOB_SECONDS);
|
|
133
|
+
pl.lpush(SPAWN_QUEUE, JSON.stringify(job));
|
|
134
|
+
await pl.exec();
|
|
135
|
+
},
|
|
136
|
+
async getStatus(jobId) {
|
|
137
|
+
const val = await redis.get(jobKey(jobId));
|
|
138
|
+
return val ? JSON.parse(val) : null;
|
|
139
|
+
},
|
|
140
|
+
async publishDone(jobId, result) {
|
|
141
|
+
const json = JSON.stringify(result);
|
|
142
|
+
const pl = redis.pipeline();
|
|
143
|
+
pl.publish(jobDoneChannel(jobId), json);
|
|
144
|
+
pl.lpush(jobDoneQueueKey(jobId), json);
|
|
145
|
+
pl.expire(jobDoneQueueKey(jobId), TTL.JOB_SECONDS);
|
|
146
|
+
await pl.exec();
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
// ── token ─────────────────────────────────────────────────────────────────
|
|
150
|
+
token: {
|
|
151
|
+
async getMaster() {
|
|
152
|
+
const val = await redis.get(MASTER_TOKEN_KEY);
|
|
153
|
+
if (val === null)
|
|
154
|
+
throw new Error("cc-wire: master token not set");
|
|
155
|
+
return val;
|
|
156
|
+
},
|
|
157
|
+
async setMaster(token) {
|
|
158
|
+
await redis.set(MASTER_TOKEN_KEY, token);
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
_redis: redis,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gonzih/cc-wire",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Single source of truth for Redis channel names, key patterns, and message shapes across the cc-suite (cc-tg, cc-agent, cc-agent-ui)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -27,12 +27,25 @@
|
|
|
27
27
|
"build": "rm -rf dist && npm run build:esm && npm run build:cjs",
|
|
28
28
|
"build:esm": "tsc -p tsconfig.json",
|
|
29
29
|
"build:cjs": "tsc -p tsconfig.cjs.json && node scripts/fix-cjs.mjs",
|
|
30
|
-
"test": "
|
|
30
|
+
"test": "npm run test:channels && npm run test:runtime",
|
|
31
|
+
"test:channels": "node --import tsx/esm --test src/channels.test.ts",
|
|
32
|
+
"test:runtime": "vitest run --reporter=verbose"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"ioredis": ">=4 <6"
|
|
36
|
+
},
|
|
37
|
+
"peerDependenciesMeta": {
|
|
38
|
+
"ioredis": {
|
|
39
|
+
"optional": true
|
|
40
|
+
}
|
|
31
41
|
},
|
|
32
42
|
"devDependencies": {
|
|
33
43
|
"@types/node": "22.15.21",
|
|
44
|
+
"ioredis": "5.11.1",
|
|
45
|
+
"ioredis-mock": "8.13.1",
|
|
34
46
|
"tsx": "4.22.4",
|
|
35
|
-
"typescript": "5.8.3"
|
|
47
|
+
"typescript": "5.8.3",
|
|
48
|
+
"vitest": "4.1.8"
|
|
36
49
|
},
|
|
37
50
|
"keywords": [
|
|
38
51
|
"redis",
|