too-many-cooks 0.5.0 → 0.7.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 +47 -0
- package/build/bin/server.d.ts +3 -0
- package/build/bin/server.d.ts.map +1 -0
- package/build/bin/server.js +140 -104
- package/build/bin/server.js.map +1 -0
- package/build/src/backend.d.ts +6 -0
- package/build/src/backend.d.ts.map +1 -0
- package/build/src/backend.js +50 -0
- package/build/src/backend.js.map +1 -0
- package/build/src/cloud-config.d.ts +13 -0
- package/build/src/cloud-config.d.ts.map +1 -0
- package/build/src/cloud-config.js +48 -0
- package/build/src/cloud-config.js.map +1 -0
- package/build/src/config.d.ts +9 -0
- package/build/src/config.d.ts.map +1 -0
- package/build/src/config.js +9 -0
- package/build/src/config.js.map +1 -0
- package/build/src/crypto.d.ts +16 -0
- package/build/src/crypto.d.ts.map +1 -0
- package/build/src/crypto.js +90 -0
- package/build/src/crypto.js.map +1 -0
- package/build/src/db-cloud.d.ts +4 -0
- package/build/src/db-cloud.d.ts.map +1 -0
- package/build/src/db-cloud.js +142 -0
- package/build/src/db-cloud.js.map +1 -0
- package/build/src/db-sqlite.d.ts +4 -0
- package/build/src/db-sqlite.d.ts.map +1 -0
- package/build/src/db-sqlite.js +672 -0
- package/build/src/db-sqlite.js.map +1 -0
- package/build/src/encryption-middleware.d.ts +5 -0
- package/build/src/encryption-middleware.d.ts.map +1 -0
- package/build/src/encryption-middleware.js +144 -0
- package/build/src/encryption-middleware.js.map +1 -0
- package/build/src/index.d.ts +12 -0
- package/build/src/index.d.ts.map +1 -0
- package/build/src/index.js +16 -0
- package/build/src/index.js.map +1 -0
- package/build/src/migrate.d.ts +8 -0
- package/build/src/migrate.d.ts.map +1 -0
- package/build/src/migrate.js +101 -0
- package/build/src/migrate.js.map +1 -0
- package/build/src/server.d.ts +5 -0
- package/build/src/server.d.ts.map +1 -0
- package/build/src/server.js +27 -0
- package/build/src/server.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/config.ts.html +163 -0
- package/coverage/lcov-report/db-sqlite.ts.html +2695 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +146 -0
- package/coverage/lcov-report/migrate.ts.html +367 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/server.ts.html +220 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/src/db-sqlite.ts.html +2701 -0
- package/coverage/lcov-report/src/index.html +116 -0
- package/coverage/lcov.info +1135 -0
- package/coverage/tmp/coverage-20666-1773541946341-0.json +1 -0
- package/coverage/tmp/coverage-20667-1773541946743-1.json +1 -0
- package/coverage/tmp/coverage-20667-1773541946763-0.json +1 -0
- package/coverage/tmp/coverage-20671-1773541947001-1.json +1 -0
- package/coverage/tmp/coverage-20671-1773541947016-0.json +1 -0
- package/coverage/tmp/coverage-20676-1773541947999-1.json +1 -0
- package/coverage/tmp/coverage-20676-1773541948018-0.json +1 -0
- package/coverage/tmp/coverage-20693-1773541948312-1.json +1 -0
- package/coverage/tmp/coverage-20693-1773541948327-0.json +1 -0
- package/package.json +13 -40
- package/prisma/migrations/20260315013355_init/migration.sql +45 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +60 -0
- package/prisma.config.ts +11 -0
- package/src/backend.ts +88 -0
- package/src/cloud-config.ts +84 -0
- package/src/config.ts +26 -0
- package/src/crypto.ts +149 -0
- package/src/db-cloud.ts +305 -0
- package/src/db-sqlite.ts +1174 -0
- package/src/encryption-middleware.ts +244 -0
- package/src/index.ts +20 -0
- package/src/migrate.ts +128 -0
- package/src/server.ts +51 -0
- package/tsconfig.json +13 -0
- package/tsconfig.test.json +12 -0
- package/readme.md +0 -308
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Too Many Cooks
|
|
2
|
+
|
|
3
|
+
Multi-agent coordination MCP server. Lets multiple AI agents safely edit the same codebase simultaneously using file locking, messaging, and shared plans.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Add to Claude Code over HTTP (Streamable HTTP transport)
|
|
9
|
+
claude mcp add --transport http too-many-cooks http://localhost:4040/mcp
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Set `TMC_WORKSPACE` to target a specific workspace folder (defaults to `process.cwd()`).
|
|
13
|
+
|
|
14
|
+
## Packages
|
|
15
|
+
|
|
16
|
+
| Package | Description |
|
|
17
|
+
|---------|-------------|
|
|
18
|
+
| [too-many-cooks](too-many-cooks/) | MCP server + data layer (TypeScript/Node.js) |
|
|
19
|
+
| [too_many_cooks_vscode_extension](too_many_cooks_vscode_extension/) | VSCode extension for monitoring agent coordination |
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- **File locking** - agents acquire/release locks to prevent conflicting edits
|
|
24
|
+
- **Messaging** - agents communicate intent and coordinate via messages
|
|
25
|
+
- **Plans** - agents publish plans so others can see what's happening
|
|
26
|
+
- **Admin dashboard** - VSCode extension with tree views for agents, locks, messages, and plans
|
|
27
|
+
- **Real-time push** - state changes delivered via MCP Streamable HTTP transport
|
|
28
|
+
|
|
29
|
+
## Project Structure
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
too-many-cooks/ # MCP server (TypeScript/Node.js)
|
|
33
|
+
too_many_cooks_vscode_extension/ # VSCode extension (TypeScript)
|
|
34
|
+
docs/ # Specification
|
|
35
|
+
website/ # Documentation website (Eleventy)
|
|
36
|
+
scripts/ # Build/test scripts
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Documentation
|
|
40
|
+
|
|
41
|
+
See the [spec](docs/spec.md) for the full protocol specification.
|
|
42
|
+
|
|
43
|
+
[tmc-mcp.dev](https://tmc-mcp.dev)
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../bin/server.ts"],"names":[],"mappings":""}
|
package/build/bin/server.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
/// Entry point for Too Many Cooks MCP server.
|
|
2
3
|
///
|
|
3
4
|
/// Starts a single Express HTTP server on port 4040 with:
|
|
@@ -6,15 +7,12 @@
|
|
|
6
7
|
import crypto from "node:crypto";
|
|
7
8
|
import { execSync } from "node:child_process";
|
|
8
9
|
import fs from "node:fs";
|
|
10
|
+
import net from "node:net";
|
|
9
11
|
import express from "express";
|
|
10
12
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
13
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
12
|
-
import { LogLevel,
|
|
13
|
-
import {
|
|
14
|
-
import { createDb } from "../lib/src/data/db.js";
|
|
15
|
-
import { createAgentEventHub } from "../lib/src/notifications.js";
|
|
16
|
-
import { createAdminEventHub, registerAdminRoutes } from "../lib/src/admin_routes.js";
|
|
17
|
-
import { createMcpServerForDb } from "../lib/src/server.js";
|
|
14
|
+
import { LogLevel, createAdminEventHub, createAgentEventHub, createLoggerWithContext, createLoggingContext, createMcpServerForDb, defaultConfig, getServerPort, getWorkspaceFolder, logLevelName, logTransport, pathJoin, registerAdminRoutes, } from "too-many-cooks-core";
|
|
15
|
+
import { createBackend } from "../src/backend.js";
|
|
18
16
|
/** JSON-RPC bad request error response. */
|
|
19
17
|
const BAD_REQUEST_JSON = '{"jsonrpc":"2.0","error":{"code":-32000,"message":"Bad Request"},"id":null}';
|
|
20
18
|
/** JSON-RPC session-not-found error response (404). */
|
|
@@ -32,46 +30,55 @@ const main = async () => {
|
|
|
32
30
|
};
|
|
33
31
|
/** Maximum time to wait for port to become free after killing a process. */
|
|
34
32
|
const PORT_FREE_TIMEOUT_MS = 5000;
|
|
35
|
-
/**
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
};
|
|
33
|
+
/** Timeout for port check connection attempt (ms). */
|
|
34
|
+
const PORT_CHECK_TIMEOUT_MS = 500;
|
|
35
|
+
/** Delay between port-free polls in milliseconds. */
|
|
36
|
+
const PORT_POLL_DELAY_MS = 100;
|
|
37
|
+
/** Perform a raw TCP probe and return a Promise<boolean> (non-async to avoid require-await). */
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
39
|
+
const tcpProbe = (port) => new Promise((resolve) => {
|
|
40
|
+
const socket = net.createConnection({ port, host: "127.0.0.1" });
|
|
41
|
+
const timer = setTimeout(() => { socket.destroy(); resolve(false); }, PORT_CHECK_TIMEOUT_MS);
|
|
42
|
+
socket.once("connect", () => { clearTimeout(timer); socket.destroy(); resolve(true); });
|
|
43
|
+
socket.once("error", () => { clearTimeout(timer); resolve(false); });
|
|
44
|
+
});
|
|
45
|
+
/** Check whether a port is in use by attempting a TCP connection. */
|
|
46
|
+
const isPortInUse = async (port) => await tcpProbe(port);
|
|
45
47
|
/** Kill any existing process listening on the given port and wait for it to be freed. */
|
|
46
|
-
const killExistingProcess = (port, log) => {
|
|
48
|
+
const killExistingProcess = async (port, log) => {
|
|
49
|
+
const inUse = await isPortInUse(port);
|
|
50
|
+
if (!inUse) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
log.info("Port in use, killing existing process", { port });
|
|
47
54
|
try {
|
|
48
55
|
const output = execSync(`lsof -ti :${String(port)}`, { encoding: "utf8" }).trim();
|
|
49
56
|
if (output.length === 0) {
|
|
50
57
|
return;
|
|
51
58
|
}
|
|
52
|
-
const pids = output.split("\n").map((pid) => pid.trim()).filter((pid) => pid.length > 0);
|
|
59
|
+
const pids = output.split("\n").map((pid) => { return pid.trim(); }).filter((pid) => { return pid.length > 0; });
|
|
53
60
|
for (const pid of pids) {
|
|
54
|
-
log.info("Killing
|
|
61
|
+
log.info("Killing process", { port, pid });
|
|
55
62
|
execSync(`kill -9 ${pid}`);
|
|
56
63
|
}
|
|
57
64
|
const start = Date.now();
|
|
58
65
|
while (Date.now() - start < PORT_FREE_TIMEOUT_MS) {
|
|
59
|
-
if (
|
|
66
|
+
if (!(await isPortInUse(port))) {
|
|
60
67
|
log.info("Port is now free", { port });
|
|
61
68
|
return;
|
|
62
69
|
}
|
|
63
|
-
|
|
70
|
+
await new Promise((resolve) => { setTimeout(() => { resolve(undefined); }, PORT_POLL_DELAY_MS); });
|
|
64
71
|
}
|
|
65
72
|
log.warn("Port still in use after timeout — proceeding anyway", { port });
|
|
66
73
|
}
|
|
67
74
|
catch {
|
|
68
|
-
//
|
|
75
|
+
// Lsof exits non-zero when no process found — that's fine
|
|
69
76
|
}
|
|
70
77
|
};
|
|
71
78
|
const startServer = async (log) => {
|
|
72
79
|
log.info("Creating server...");
|
|
73
80
|
const cfg = defaultConfig;
|
|
74
|
-
const dbResult =
|
|
81
|
+
const dbResult = createBackend(cfg, log);
|
|
75
82
|
if (!dbResult.ok) {
|
|
76
83
|
throw new Error(dbResult.error);
|
|
77
84
|
}
|
|
@@ -92,7 +99,7 @@ const startServer = async (log) => {
|
|
|
92
99
|
app.get("/mcp", asyncHandler(mcpGetDeleteHandler(transports, agentHub), log));
|
|
93
100
|
app.delete("/mcp", asyncHandler(mcpGetDeleteHandler(transports, agentHub), log));
|
|
94
101
|
const port = getServerPort();
|
|
95
|
-
killExistingProcess(port, log);
|
|
102
|
+
await killExistingProcess(port, log);
|
|
96
103
|
app.listen(port, () => {
|
|
97
104
|
log.info("Server listening", { port });
|
|
98
105
|
});
|
|
@@ -101,12 +108,25 @@ const startServer = async (log) => {
|
|
|
101
108
|
setInterval(() => { }, KEEP_ALIVE_INTERVAL_MS);
|
|
102
109
|
await new Promise(() => { });
|
|
103
110
|
};
|
|
111
|
+
/** Extract the mcp-session-id header as a string, or undefined. */
|
|
112
|
+
const extractSessionId = (req) => {
|
|
113
|
+
const raw = req.headers["mcp-session-id"];
|
|
114
|
+
return Array.isArray(raw) ? raw[0] : raw;
|
|
115
|
+
};
|
|
116
|
+
/** Extract the request body as unknown. */
|
|
117
|
+
const extractBody = (req) => req.body;
|
|
118
|
+
/**
|
|
119
|
+
* Assert that a value satisfies both StreamableHTTPServerTransport and Transport.
|
|
120
|
+
* Required due to exactOptionalPropertyTypes incompatibility in @modelcontextprotocol/sdk:
|
|
121
|
+
* Transport.onclose is `() => void` but StreamableHTTPServerTransport.onclose is `(() => void) | undefined`.
|
|
122
|
+
*/
|
|
123
|
+
const assertMcpTransport = (_transport) => { };
|
|
104
124
|
/** Check if a parsed JSON body is an MCP initialize request. */
|
|
105
125
|
const isInitializeRequest = (body) => {
|
|
106
126
|
if (typeof body !== "object" || body === null) {
|
|
107
127
|
return false;
|
|
108
128
|
}
|
|
109
|
-
const
|
|
129
|
+
const method = "method" in body ? body.method : undefined;
|
|
110
130
|
return method === "initialize";
|
|
111
131
|
};
|
|
112
132
|
/** Wire up transport close handler for agent sessions. */
|
|
@@ -124,9 +144,9 @@ const wireAgentTransportClose = (transport, ctx) => {
|
|
|
124
144
|
};
|
|
125
145
|
/** Initialize an MCP agent session (POST /mcp with initialize body). */
|
|
126
146
|
const initializeMcpSession = async (req, res, ctx) => {
|
|
127
|
-
const
|
|
147
|
+
const body = extractBody(req);
|
|
128
148
|
const transport = new StreamableHTTPServerTransport({
|
|
129
|
-
sessionIdGenerator: () => crypto.randomUUID(),
|
|
149
|
+
sessionIdGenerator: () => { return crypto.randomUUID(); },
|
|
130
150
|
onsessioninitialized: (sid) => {
|
|
131
151
|
ctx.log.info("Session init", { sessionId: sid });
|
|
132
152
|
ctx.transports.set(sid, transport);
|
|
@@ -148,6 +168,7 @@ const initializeMcpSession = async (req, res, ctx) => {
|
|
|
148
168
|
throw new Error(serverResult.error);
|
|
149
169
|
}
|
|
150
170
|
const server = serverResult.value;
|
|
171
|
+
assertMcpTransport(transport);
|
|
151
172
|
await server.connect(transport);
|
|
152
173
|
await transport.handleRequest(req, res, body);
|
|
153
174
|
const sid = transport.sessionId;
|
|
@@ -156,46 +177,50 @@ const initializeMcpSession = async (req, res, ctx) => {
|
|
|
156
177
|
}
|
|
157
178
|
};
|
|
158
179
|
/** POST /mcp handler. */
|
|
159
|
-
const mcpPostHandler = (ctx) =>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
180
|
+
const mcpPostHandler = (ctx) => {
|
|
181
|
+
return async (req, res) => {
|
|
182
|
+
const sessionId = extractSessionId(req);
|
|
183
|
+
const body = extractBody(req);
|
|
184
|
+
if (sessionId !== undefined && ctx.transports.has(sessionId)) {
|
|
185
|
+
const existing = ctx.transports.get(sessionId);
|
|
186
|
+
if (existing !== undefined) {
|
|
187
|
+
await existing.handleRequest(req, res, body);
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
166
190
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
res.status(400).send(BAD_REQUEST_JSON);
|
|
191
|
+
if (sessionId !== undefined) {
|
|
192
|
+
res.status(404).send(SESSION_NOT_FOUND_JSON);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (isInitializeRequest(body)) {
|
|
196
|
+
await initializeMcpSession(req, res, ctx);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
res.status(400).send(BAD_REQUEST_JSON);
|
|
200
|
+
};
|
|
178
201
|
};
|
|
179
202
|
/** GET/DELETE /mcp handler. */
|
|
180
|
-
const mcpGetDeleteHandler = (transports, agentHub) =>
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
203
|
+
const mcpGetDeleteHandler = (transports, agentHub) => {
|
|
204
|
+
return async (req, res) => {
|
|
205
|
+
const sessionId = extractSessionId(req);
|
|
206
|
+
if (sessionId === undefined) {
|
|
207
|
+
res.status(400).send("Missing session ID");
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const transport = transports.get(sessionId);
|
|
211
|
+
if (transport === undefined) {
|
|
212
|
+
res.status(404).send(SESSION_NOT_FOUND_JSON);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
agentHub.activeStreamSessions.add(sessionId);
|
|
216
|
+
await transport.handleRequest(req, res);
|
|
217
|
+
};
|
|
193
218
|
};
|
|
194
219
|
/** Initialize an admin session (POST /admin/events with initialize body). */
|
|
195
220
|
const initializeAdminSession = async (req, res, hub, log) => {
|
|
196
|
-
const
|
|
221
|
+
const body = extractBody(req);
|
|
197
222
|
const transport = new StreamableHTTPServerTransport({
|
|
198
|
-
sessionIdGenerator: () => crypto.randomUUID(),
|
|
223
|
+
sessionIdGenerator: () => { return crypto.randomUUID(); },
|
|
199
224
|
onsessioninitialized: (sid) => {
|
|
200
225
|
log.info("Admin session init", { sessionId: sid });
|
|
201
226
|
hub.transports.set(sid, transport);
|
|
@@ -210,6 +235,7 @@ const initializeAdminSession = async (req, res, hub, log) => {
|
|
|
210
235
|
}
|
|
211
236
|
};
|
|
212
237
|
const server = new McpServer({ name: "too-many-cooks", version: "0.1.0" }, { capabilities: { logging: {} } });
|
|
238
|
+
assertMcpTransport(transport);
|
|
213
239
|
await server.connect(transport);
|
|
214
240
|
await transport.handleRequest(req, res, body);
|
|
215
241
|
const sid = transport.sessionId;
|
|
@@ -218,45 +244,51 @@ const initializeAdminSession = async (req, res, hub, log) => {
|
|
|
218
244
|
}
|
|
219
245
|
};
|
|
220
246
|
/** POST /admin/events handler. */
|
|
221
|
-
const adminPostHandler = (hub, log) =>
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
247
|
+
const adminPostHandler = (hub, log) => {
|
|
248
|
+
return async (req, res) => {
|
|
249
|
+
const sessionId = extractSessionId(req);
|
|
250
|
+
const body = extractBody(req);
|
|
251
|
+
if (sessionId !== undefined && hub.transports.has(sessionId)) {
|
|
252
|
+
const existing = hub.transports.get(sessionId);
|
|
253
|
+
if (existing !== undefined) {
|
|
254
|
+
await existing.handleRequest(req, res, body);
|
|
255
|
+
}
|
|
256
|
+
return;
|
|
228
257
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
res.status(400).send(BAD_REQUEST_JSON);
|
|
258
|
+
if (sessionId !== undefined) {
|
|
259
|
+
res.status(404).send(SESSION_NOT_FOUND_JSON);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (isInitializeRequest(body)) {
|
|
263
|
+
await initializeAdminSession(req, res, hub, log);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
res.status(400).send(BAD_REQUEST_JSON);
|
|
267
|
+
};
|
|
240
268
|
};
|
|
241
269
|
/** GET/DELETE /admin/events handler. */
|
|
242
|
-
const adminGetDeleteHandler = (hub) =>
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
270
|
+
const adminGetDeleteHandler = (hub) => {
|
|
271
|
+
return async (req, res) => {
|
|
272
|
+
const sessionId = extractSessionId(req);
|
|
273
|
+
if (sessionId === undefined) {
|
|
274
|
+
res.status(400).send("Missing session ID");
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const transport = hub.transports.get(sessionId);
|
|
278
|
+
if (transport === undefined) {
|
|
279
|
+
res.status(404).send(SESSION_NOT_FOUND_JSON);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
await transport.handleRequest(req, res);
|
|
283
|
+
};
|
|
254
284
|
};
|
|
255
285
|
/** Wrap an async handler for Express. */
|
|
256
|
-
const asyncHandler = (fn, log) =>
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
286
|
+
const asyncHandler = (fn, log) => {
|
|
287
|
+
return (req, res) => {
|
|
288
|
+
fn(req, res).catch((e) => {
|
|
289
|
+
log.error("Request error", { error: String(e) });
|
|
290
|
+
});
|
|
291
|
+
};
|
|
260
292
|
};
|
|
261
293
|
const resolveLogFilePath = () => {
|
|
262
294
|
const logsDir = pathJoin([getWorkspaceFolder(), "logs"]);
|
|
@@ -287,17 +319,21 @@ const formatLogLine = (message) => {
|
|
|
287
319
|
: "";
|
|
288
320
|
return `[TMC] [${message.timestamp.toISOString()}] [${level}] ${message.message}${dataStr}\n`;
|
|
289
321
|
};
|
|
290
|
-
const createConsoleTransport = () =>
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
322
|
+
const createConsoleTransport = () => {
|
|
323
|
+
return (message, minimumLogLevel) => {
|
|
324
|
+
if (message.logLevel < minimumLogLevel) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
console.error(formatLogLine(message).trimEnd());
|
|
328
|
+
};
|
|
295
329
|
};
|
|
296
|
-
const createFileTransport = (filePath) =>
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
330
|
+
const createFileTransport = (filePath) => {
|
|
331
|
+
return (message, minimumLogLevel) => {
|
|
332
|
+
if (message.logLevel < minimumLogLevel) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
fs.appendFileSync(filePath, formatLogLine(message));
|
|
336
|
+
};
|
|
301
337
|
};
|
|
302
338
|
main().catch((e) => {
|
|
303
339
|
console.error("Fatal:", e);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../bin/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Logger, type Result, type TooManyCooksDataConfig, type TooManyCooksDb } from "too-many-cooks-core";
|
|
2
|
+
/** Check whether cloud mode env vars are present. */
|
|
3
|
+
export declare const isCloudMode: (env: Record<string, string | undefined>) => boolean;
|
|
4
|
+
/** Create a TooManyCooksDb for the active backend (SQLite or cloud). */
|
|
5
|
+
export declare const createBackend: (config: TooManyCooksDataConfig, log: Logger, env?: Record<string, string | undefined>) => Result<TooManyCooksDb, string>;
|
|
6
|
+
//# sourceMappingURL=backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/backend.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EAGpB,MAAM,qBAAqB,CAAC;AAmB7B,qDAAqD;AACrD,eAAO,MAAM,WAAW,EAAE,CACxB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,KACpC,OAGJ,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,aAAa,EAAE,CAC1B,MAAM,EAAE,sBAAsB,EAC9B,GAAG,EAAE,MAAM,EACX,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,KACrC,MAAM,CAAC,cAAc,EAAE,MAAM,CAWjC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/// Backend abstraction — creates a TooManyCooksDb from environment.
|
|
2
|
+
///
|
|
3
|
+
/// If cloud env vars (TMC_API_KEY, TMC_WORKSPACE_ID, TMC_WORKSPACE_SECRET)
|
|
4
|
+
/// are present, creates an encrypted cloud backend. Otherwise, creates SQLite.
|
|
5
|
+
/// Tool handlers are identical regardless of backend.
|
|
6
|
+
import { error, success, } from "too-many-cooks-core";
|
|
7
|
+
import { parseConfig } from "./cloud-config.js";
|
|
8
|
+
import { createCloudDb } from "./db-cloud.js";
|
|
9
|
+
import { createDb } from "./db-sqlite.js";
|
|
10
|
+
import { withEncryption } from "./encryption-middleware.js";
|
|
11
|
+
/** Read process.env without type assertion. */
|
|
12
|
+
const processEnv = () => {
|
|
13
|
+
const result = {};
|
|
14
|
+
for (const key of Object.keys(process.env)) {
|
|
15
|
+
result[key] = process.env[key];
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
};
|
|
19
|
+
/** Environment variable that signals cloud mode. */
|
|
20
|
+
const CLOUD_MODE_ENV_KEY = "TMC_API_KEY";
|
|
21
|
+
/** Check whether cloud mode env vars are present. */
|
|
22
|
+
export const isCloudMode = (env) => {
|
|
23
|
+
const val = env[CLOUD_MODE_ENV_KEY];
|
|
24
|
+
return val !== undefined && val !== "";
|
|
25
|
+
};
|
|
26
|
+
/** Create a TooManyCooksDb for the active backend (SQLite or cloud). */
|
|
27
|
+
export const createBackend = (config, log, env) => {
|
|
28
|
+
const resolvedEnv = env ?? processEnv();
|
|
29
|
+
return isCloudMode(resolvedEnv)
|
|
30
|
+
? createCloudBackend(resolvedEnv, log)
|
|
31
|
+
: createLocalBackend(config, log);
|
|
32
|
+
};
|
|
33
|
+
/** Create a local SQLite backend. */
|
|
34
|
+
const createLocalBackend = (config, log) => {
|
|
35
|
+
log.info("Backend: SQLite (local mode)");
|
|
36
|
+
return createDb(config);
|
|
37
|
+
};
|
|
38
|
+
/** Create an encrypted cloud backend. */
|
|
39
|
+
const createCloudBackend = (env, log) => {
|
|
40
|
+
const configResult = parseConfig(env);
|
|
41
|
+
if (!configResult.ok) {
|
|
42
|
+
return error(configResult.error);
|
|
43
|
+
}
|
|
44
|
+
const cfg = configResult.value;
|
|
45
|
+
log.info("Backend: Cloud (encrypted)", { apiUrl: cfg.apiUrl });
|
|
46
|
+
const rawDb = createCloudDb(cfg.apiUrl, cfg.apiKey, cfg.workspaceId);
|
|
47
|
+
const db = withEncryption(rawDb, cfg.currentKey, cfg.keychain);
|
|
48
|
+
return success(db);
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/backend.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,GAAG;AACH,2EAA2E;AAC3E,+EAA+E;AAC/E,sDAAsD;AAEtD,OAAO,EAKL,KAAK,EACL,OAAO,GACR,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAyB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,+CAA+C;AAC/C,MAAM,UAAU,GAA6C,GAAuC,EAAE;IACpG,MAAM,MAAM,GAAuC,EAAE,CAAC;IACtD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,oDAAoD;AACpD,MAAM,kBAAkB,GAAW,aAAa,CAAC;AAEjD,qDAAqD;AACrD,MAAM,CAAC,MAAM,WAAW,GAET,CAAC,GAAuC,EAAW,EAAE;IAClE,MAAM,GAAG,GAAuB,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACxD,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,CAAC;AACzC,CAAC,CAAC;AAEF,wEAAwE;AACxE,MAAM,CAAC,MAAM,aAAa,GAIY,CACpC,MAA8B,EAC9B,GAAW,EACX,GAAwC,EACR,EAAE;IAClC,MAAM,WAAW,GACf,GAAG,IAAI,UAAU,EAAE,CAAC;IAEtB,OAAO,WAAW,CAAC,WAAW,CAAC;QAC7B,CAAC,CAAC,kBAAkB,CAAC,WAAW,EAAE,GAAG,CAAC;QACtC,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC,CAAC;AAEF,qCAAqC;AACrC,MAAM,kBAAkB,GAGc,CACpC,MAA8B,EAC9B,GAAW,EACqB,EAAE;IAClC,GAAG,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACzC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,yCAAyC;AACzC,MAAM,kBAAkB,GAGc,CACpC,GAAuC,EACvC,GAAW,EACqB,EAAE;IAClC,MAAM,YAAY,GAAqC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxE,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QAAC,OAAO,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC;IAC3D,MAAM,GAAG,GAAqB,YAAY,CAAC,KAAK,CAAC;IAEjD,GAAG,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAE/D,MAAM,KAAK,GAAmB,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IACrF,MAAM,EAAE,GAAmB,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/E,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;AACrB,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Result } from "too-many-cooks-core";
|
|
2
|
+
import { type Keychain, type WorkspaceKey } from "./crypto.js";
|
|
3
|
+
/** Cloud proxy configuration. */
|
|
4
|
+
export type CloudProxyConfig = {
|
|
5
|
+
readonly apiKey: string;
|
|
6
|
+
readonly workspaceId: string;
|
|
7
|
+
readonly apiUrl: string;
|
|
8
|
+
readonly keychain: Keychain;
|
|
9
|
+
readonly currentKey: WorkspaceKey;
|
|
10
|
+
};
|
|
11
|
+
/** Parse and validate cloud proxy config from environment. */
|
|
12
|
+
export declare const parseConfig: (env: Record<string, string | undefined>) => Result<CloudProxyConfig, string>;
|
|
13
|
+
//# sourceMappingURL=cloud-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-config.d.ts","sourceRoot":"","sources":["../../src/cloud-config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAkB,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAsB,MAAM,aAAa,CAAC;AAwBnF,iCAAiC;AACjC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC;CACnC,CAAC;AAuBF,8DAA8D;AAC9D,eAAO,MAAM,WAAW,EAAE,CACxB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,KACpC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAsBnC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// Cloud proxy configuration from environment variables.
|
|
2
|
+
import { error, success } from "too-many-cooks-core";
|
|
3
|
+
import { deriveWorkspaceKey } from "./crypto.js";
|
|
4
|
+
/** Environment variable name for the API key. */
|
|
5
|
+
const ENV_API_KEY = "TMC_API_KEY";
|
|
6
|
+
/** Environment variable name for the workspace ID. */
|
|
7
|
+
const ENV_WORKSPACE_ID = "TMC_WORKSPACE_ID";
|
|
8
|
+
/** Environment variable name for the workspace secret (current). */
|
|
9
|
+
const ENV_WORKSPACE_SECRET = "TMC_WORKSPACE_SECRET";
|
|
10
|
+
/** Environment variable name for the previous workspace secret (rotation). */
|
|
11
|
+
const ENV_WORKSPACE_SECRET_V1 = "TMC_WORKSPACE_SECRET_V1";
|
|
12
|
+
/** Environment variable name for the cloud API URL. */
|
|
13
|
+
const ENV_API_URL = "TMC_API_URL";
|
|
14
|
+
/** Error prefix for missing environment variables. */
|
|
15
|
+
const ERR_MISSING_ENV = "Missing required env var: ";
|
|
16
|
+
/** Default production API URL. */
|
|
17
|
+
const DEFAULT_API_URL = "https://your-project.supabase.co/functions/v1/tmc-api";
|
|
18
|
+
/** Build a keychain from current + optional previous passphrase. */
|
|
19
|
+
const buildKeychain = (currentPassphrase, workspaceId, previousPassphrase) => {
|
|
20
|
+
const currentKey = deriveWorkspaceKey(currentPassphrase, workspaceId);
|
|
21
|
+
const keys = [currentKey];
|
|
22
|
+
if (previousPassphrase !== undefined) {
|
|
23
|
+
keys.push({
|
|
24
|
+
...deriveWorkspaceKey(previousPassphrase, workspaceId),
|
|
25
|
+
version: currentKey.version - 1,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return { keychain: keys, currentKey };
|
|
29
|
+
};
|
|
30
|
+
/** Parse and validate cloud proxy config from environment. */
|
|
31
|
+
export const parseConfig = (env) => {
|
|
32
|
+
const apiKey = env[ENV_API_KEY];
|
|
33
|
+
if (apiKey === undefined || apiKey === "") {
|
|
34
|
+
return error(`${ERR_MISSING_ENV}${ENV_API_KEY}`);
|
|
35
|
+
}
|
|
36
|
+
const workspaceId = env[ENV_WORKSPACE_ID];
|
|
37
|
+
if (workspaceId === undefined || workspaceId === "") {
|
|
38
|
+
return error(`${ERR_MISSING_ENV}${ENV_WORKSPACE_ID}`);
|
|
39
|
+
}
|
|
40
|
+
const secret = env[ENV_WORKSPACE_SECRET];
|
|
41
|
+
if (secret === undefined || secret === "") {
|
|
42
|
+
return error(`${ERR_MISSING_ENV}${ENV_WORKSPACE_SECRET}`);
|
|
43
|
+
}
|
|
44
|
+
const apiUrl = env[ENV_API_URL] ?? DEFAULT_API_URL;
|
|
45
|
+
const { keychain, currentKey } = buildKeychain(secret, workspaceId, env[ENV_WORKSPACE_SECRET_V1]);
|
|
46
|
+
return success({ apiKey, workspaceId, apiUrl, keychain, currentKey });
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=cloud-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-config.js","sourceRoot":"","sources":["../../src/cloud-config.ts"],"names":[],"mappings":"AAAA,yDAAyD;AAEzD,OAAO,EAAe,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAoC,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEnF,iDAAiD;AACjD,MAAM,WAAW,GAAW,aAAa,CAAC;AAE1C,sDAAsD;AACtD,MAAM,gBAAgB,GAAW,kBAAkB,CAAC;AAEpD,oEAAoE;AACpE,MAAM,oBAAoB,GAAW,sBAAsB,CAAC;AAE5D,8EAA8E;AAC9E,MAAM,uBAAuB,GAAW,yBAAyB,CAAC;AAElE,uDAAuD;AACvD,MAAM,WAAW,GAAW,aAAa,CAAC;AAE1C,sDAAsD;AACtD,MAAM,eAAe,GAAW,4BAA4B,CAAC;AAE7D,kCAAkC;AAClC,MAAM,eAAe,GACnB,uDAAuD,CAAC;AAW1D,oEAAoE;AACpE,MAAM,aAAa,GAIuD,CACxE,iBAAyB,EACzB,WAAmB,EACnB,kBAAsC,EAC8B,EAAE;IACtE,MAAM,UAAU,GAAiB,kBAAkB,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;IACpF,MAAM,IAAI,GAAmB,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC;YACR,GAAG,kBAAkB,CAAC,kBAAkB,EAAE,WAAW,CAAC;YACtD,OAAO,EAAE,UAAU,CAAC,OAAO,GAAG,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AACxC,CAAC,CAAC;AAEF,8DAA8D;AAC9D,MAAM,CAAC,MAAM,WAAW,GAEgB,CACtC,GAAuC,EACL,EAAE;IACpC,MAAM,MAAM,GAAuB,GAAG,CAAC,WAAW,CAAC,CAAC;IACpD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC,GAAG,eAAe,GAAG,WAAW,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,MAAM,WAAW,GAAuB,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9D,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC,GAAG,eAAe,GAAG,gBAAgB,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,MAAM,GAAuB,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC7D,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC,GAAG,eAAe,GAAG,oBAAoB,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,MAAM,GAAW,GAAG,CAAC,WAAW,CAAC,IAAI,eAAe,CAAC;IAC3D,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAuE,aAAa,CAChH,MAAM,EACN,WAAW,EACX,GAAG,CAAC,uBAAuB,CAAC,CAC7B,CAAC;IACF,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;AACxE,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { type TooManyCooksDataConfig, createDataConfig, createDataConfigFromWorkspace, defaultConfig, DEFAULT_PORT as defaultPort, getServerPort, getWorkspaceFolder, resolveDbPath, pathJoin, } from "too-many-cooks-core";
|
|
2
|
+
import type { TooManyCooksDataConfig } from "too-many-cooks-core";
|
|
3
|
+
/** Server configuration type alias for backwards compatibility. */
|
|
4
|
+
export type TooManyCooksConfig = TooManyCooksDataConfig;
|
|
5
|
+
/** Server entry point relative path. */
|
|
6
|
+
export declare const SERVER_BINARY: string;
|
|
7
|
+
/** Node args needed to run the server (tsx loader for TypeScript). */
|
|
8
|
+
export declare const SERVER_NODE_ARGS: readonly string[];
|
|
9
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,6BAA6B,EAC7B,aAAa,EACb,YAAY,IAAI,WAAW,EAC3B,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAElE,mEAAmE;AACnE,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAExD,wCAAwC;AACxC,eAAO,MAAM,aAAa,EAAE,MAAwB,CAAC;AAErD,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAAiC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// Configuration for Too Many Cooks MCP server.
|
|
2
|
+
///
|
|
3
|
+
/// Re-exports core config and adds local-specific constants.
|
|
4
|
+
export { createDataConfig, createDataConfigFromWorkspace, defaultConfig, DEFAULT_PORT as defaultPort, getServerPort, getWorkspaceFolder, resolveDbPath, pathJoin, } from "too-many-cooks-core";
|
|
5
|
+
/** Server entry point relative path. */
|
|
6
|
+
export const SERVER_BINARY = "bin/server.ts";
|
|
7
|
+
/** Node args needed to run the server (tsx loader for TypeScript). */
|
|
8
|
+
export const SERVER_NODE_ARGS = ["--import", "tsx"];
|
|
9
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,GAAG;AACH,6DAA6D;AAE7D,OAAO,EAEL,gBAAgB,EAChB,6BAA6B,EAC7B,aAAa,EACb,YAAY,IAAI,WAAW,EAC3B,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAO7B,wCAAwC;AACxC,MAAM,CAAC,MAAM,aAAa,GAAW,eAAe,CAAC;AAErD,sEAAsE;AACtE,MAAM,CAAC,MAAM,gBAAgB,GAAsB,CAAC,UAAU,EAAE,KAAK,CAAU,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Result } from "too-many-cooks-core";
|
|
2
|
+
/** Workspace encryption key with version for key rotation. */
|
|
3
|
+
export type WorkspaceKey = {
|
|
4
|
+
readonly version: number;
|
|
5
|
+
readonly key: Buffer;
|
|
6
|
+
};
|
|
7
|
+
/** Keychain containing one or more workspace keys for decryption. */
|
|
8
|
+
export type Keychain = readonly WorkspaceKey[];
|
|
9
|
+
/** Derive a workspace key from a passphrase and workspace ID via HKDF. */
|
|
10
|
+
export declare const deriveWorkspaceKey: (passphrase: string, workspaceId: string) => WorkspaceKey;
|
|
11
|
+
/** Encrypt plaintext to a base64 ciphertext envelope.
|
|
12
|
+
* Format: [version:1][iv:12][authTag:16][ciphertext:N] */
|
|
13
|
+
export declare const encrypt: (plaintext: string, wk: WorkspaceKey) => string;
|
|
14
|
+
/** Decrypt a base64 ciphertext envelope back to plaintext. */
|
|
15
|
+
export declare const decrypt: (blob: string, keychain: Keychain) => Result<string, string>;
|
|
16
|
+
//# sourceMappingURL=crypto.d.ts.map
|