ftown 0.20.6 → 0.20.7

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.
Files changed (77) hide show
  1. package/dist/attention-prompt-protocol.d.ts +2 -2
  2. package/dist/attention-prompt-protocol.js +1 -1
  3. package/dist/centrifugo-client.js +0 -1
  4. package/dist/centrifugo-client.js.map +1 -1
  5. package/dist/command-rpc.d.ts +0 -1
  6. package/dist/command-rpc.js +3 -24
  7. package/dist/command-rpc.js.map +1 -1
  8. package/dist/index.js +0 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/security/bridge/account-state.d.ts +0 -4
  11. package/dist/security/bridge/direct.js +0 -2
  12. package/dist/security/bridge/direct.js.map +1 -1
  13. package/dist/security/bridge/execute.js +1 -6
  14. package/dist/security/bridge/execute.js.map +1 -1
  15. package/dist/security/bridge/identity.d.ts +0 -3
  16. package/dist/security/bridge/metadata.d.ts +0 -2
  17. package/dist/security/bridge/metadata.js +1 -1
  18. package/dist/security/bridge/metadata.js.map +1 -1
  19. package/dist/security/bridge/permissions.js +3 -11
  20. package/dist/security/bridge/permissions.js.map +1 -1
  21. package/dist/security/bridge/policy.d.ts +4 -7
  22. package/dist/security/bridge/policy.js +35 -90
  23. package/dist/security/bridge/policy.js.map +1 -1
  24. package/dist/security/bridge/security.d.ts +1 -11
  25. package/dist/security/bridge/security.js +7 -79
  26. package/dist/security/bridge/security.js.map +1 -1
  27. package/dist/security/crypto.js +2 -2
  28. package/dist/security/crypto.js.map +1 -1
  29. package/dist/security/protocol.d.ts +5 -126
  30. package/dist/types.d.ts +1 -1
  31. package/dist/update-effects.js +1 -1
  32. package/dist/update-effects.js.map +1 -1
  33. package/package.json +4 -12
  34. package/skills/ftown/SKILL.md +9 -13
  35. package/skills/ftown/references/sessions.md +4 -20
  36. package/dist/mcp/fleet.d.ts +0 -67
  37. package/dist/mcp/fleet.js +0 -298
  38. package/dist/mcp/fleet.js.map +0 -1
  39. package/dist/mcp/http.d.ts +0 -42
  40. package/dist/mcp/http.js +0 -350
  41. package/dist/mcp/http.js.map +0 -1
  42. package/dist/mcp/legacy-relay.d.ts +0 -3
  43. package/dist/mcp/legacy-relay.js +0 -6
  44. package/dist/mcp/legacy-relay.js.map +0 -1
  45. package/dist/mcp/mcp-key-store.d.ts +0 -52
  46. package/dist/mcp/mcp-key-store.js +0 -207
  47. package/dist/mcp/mcp-key-store.js.map +0 -1
  48. package/dist/mcp/oauth-store.d.ts +0 -17
  49. package/dist/mcp/oauth-store.js +0 -58
  50. package/dist/mcp/oauth-store.js.map +0 -1
  51. package/dist/mcp/oauth.d.ts +0 -83
  52. package/dist/mcp/oauth.js +0 -311
  53. package/dist/mcp/oauth.js.map +0 -1
  54. package/dist/mcp/relay-handler.d.ts +0 -2
  55. package/dist/mcp/relay-handler.js +0 -8
  56. package/dist/mcp/relay-handler.js.map +0 -1
  57. package/dist/mcp/relay.d.ts +0 -13
  58. package/dist/mcp/relay.js +0 -95
  59. package/dist/mcp/relay.js.map +0 -1
  60. package/dist/mcp/secure-client.d.ts +0 -23
  61. package/dist/mcp/secure-client.js +0 -124
  62. package/dist/mcp/secure-client.js.map +0 -1
  63. package/dist/mcp/security-events.d.ts +0 -49
  64. package/dist/mcp/security-events.js +0 -211
  65. package/dist/mcp/security-events.js.map +0 -1
  66. package/dist/mcp/server.d.ts +0 -13
  67. package/dist/mcp/server.js +0 -858
  68. package/dist/mcp/server.js.map +0 -1
  69. package/dist/mcp/test-support.d.ts +0 -32
  70. package/dist/mcp/test-support.js +0 -120
  71. package/dist/mcp/test-support.js.map +0 -1
  72. package/dist/mcp-cli.d.ts +0 -2
  73. package/dist/mcp-cli.js +0 -105
  74. package/dist/mcp-cli.js.map +0 -1
  75. package/dist/security/bridge/audit.d.ts +0 -37
  76. package/dist/security/bridge/audit.js +0 -186
  77. package/dist/security/bridge/audit.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ftown",
3
- "version": "0.20.6",
3
+ "version": "0.20.7",
4
4
  "description": "CLI bridge for ftown — generic PTY-over-Centrifugo relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -9,8 +9,7 @@
9
9
  "ftown": "dist/ftown-cli.js",
10
10
  "ftown-harness": "dist/harness-cli.js",
11
11
  "ftown-env": "dist/ftown-env-cli.js",
12
- "ftown-sessions": "bin/ftown-sessions",
13
- "ftown-mcp": "dist/mcp-cli.js"
12
+ "ftown-sessions": "bin/ftown-sessions"
14
13
  },
15
14
  "files": [
16
15
  "dist",
@@ -28,8 +27,7 @@
28
27
  "prepublishOnly": "npm run build",
29
28
  "start": "tsx src/index.ts",
30
29
  "dev": "tsx watch src/index.ts",
31
- "harness": "tsx src/harness-cli.ts",
32
- "mcp": "tsx src/mcp-cli.ts"
30
+ "harness": "tsx src/harness-cli.ts"
33
31
  },
34
32
  "engines": {
35
33
  "node": "^22.23.4 || ^24.22.1 || >=26.12.1"
@@ -51,26 +49,20 @@
51
49
  "dependencies": {
52
50
  "@hpke/common": "1.10.1",
53
51
  "@hpke/core": "1.9.0",
54
- "@modelcontextprotocol/sdk": "^1.32.1",
55
52
  "@xterm/addon-serialize": "^0.14.0",
56
53
  "@xterm/headless": "^6.0.0",
57
54
  "centrifuge": "^5.2.2",
58
55
  "commander": "^13.1.0",
59
- "express": "^5.3.0",
60
- "express-rate-limit": "^8.7.1",
61
56
  "jsonwebtoken": "^9.0.3",
62
57
  "node-datachannel": "^0.32.3",
63
58
  "node-pty": "^1.2.0-beta.12",
64
- "pg": "^8.23.1",
65
59
  "uuid": "^11.1.0",
66
60
  "ws": "^8.18.0",
67
61
  "zod": "^4.6.7"
68
62
  },
69
63
  "devDependencies": {
70
- "@types/express": "^5.0.6",
71
64
  "@types/jsonwebtoken": "^9.0.10",
72
65
  "@types/node": "^22.13.0",
73
- "@types/pg": "^8.23.1",
74
66
  "@types/uuid": "^10.0.0",
75
67
  "@types/ws": "^8.5.14",
76
68
  "tsx": "^4.19.0",
@@ -80,5 +72,5 @@
80
72
  "overrides": {
81
73
  "qs": "6.16.1"
82
74
  },
83
- "gitHead": "eccd344488ad893042a5fe081fcb9c3badf7f986"
75
+ "gitHead": "5828f409f518cbb17ebc19aef0166dec90b7a04b"
84
76
  }
@@ -127,24 +127,20 @@ authorize a merge or other action. Both commands target trimmed
127
127
  `$FTOWN_SESSION_ID` unless you supply `--session-id <id>`; they never guess identity from the working directory.
128
128
  Older bridges report `bridge_upgrade_required` before mutation.
129
129
 
130
- Remote MCP callers use `attention_request` with explicit `machine` and
131
- `sessionId`, or `sessions_update` with `pullRequestUrl` (string to set, null to
132
- clear). Mutation tools require control access; remote callers have no automatic
133
- local self identity. To ask with options or free text, pass `questions` to
134
- `attention_request`, then poll `attention_get` (`eventId`, optional
135
- `waitSeconds` 0..25) until the event is resolved (`resolvedAt` set).
136
- `event.answer` holds the answer; a resolution without an answer means it was
137
- dismissed. Keep the returned attention event ID: the
138
- inbox, acknowledge and resolve operations never answer the agent's question.
130
+ To ask with options or free text, use `ftown sessions attention --option ...` or
131
+ `--questions-json`, then check the returned event ID with `ftown sessions
132
+ attention-status <event-id>` until it is resolved. `event.answer` holds the
133
+ answer; a resolution without an answer means it was dismissed. The inbox,
134
+ acknowledge and resolve operations never answer the agent's question.
139
135
 
140
136
  For tasks performed in an FTown session, associate the task's GitHub PR when
141
- created or updated, before the completion notice: use `ftown sessions pr <URL>`
142
- or MCP `sessions_update.pullRequestUrl`. Omit this step for tasks without a PR;
143
- never invent a PR or guess a session identity.
137
+ created or updated, before the completion notice: use `ftown sessions pr <URL>`.
138
+ Omit this step for tasks without a PR; never invent a PR or guess a session
139
+ identity.
144
140
 
145
141
  Once the task is complete, request user attention **once per completed task**,
146
142
  before the final handoff, using `ftown sessions attention --title 'Work complete'
147
- --message "<truthful outcome, checks and PR summary>"` or MCP `attention_request`.
143
+ --message "<truthful outcome, checks and PR summary>"`.
148
144
  Do not send a completion notice every turn; retain the uncertain-result guidance
149
145
  above. Children must still report their result to the parent as assigned; user
150
146
  attention does not replace that reporting. See the completion example in
@@ -79,8 +79,7 @@ printf 'First line\nSecond line\n' | ftown sessions preview-reply --message-file
79
79
  The target defaults to `FTOWN_SESSION_ID`; `--session-id` selects an explicit
80
80
  session. Replies are limited to 4096 UTF-8 bytes. Preserve the returned ID and
81
81
  pass it with `--id <uuid>` alongside the same text when retrying an uncertain
82
- result. An MCP controller can instead call `preview_chat_reply` with explicit
83
- machine and session ID. A queued message does not mean an agent has read it.
82
+ result. A queued message does not mean an agent has read it.
84
83
 
85
84
  ## Ask the human or associate a pull request
86
85
 
@@ -156,7 +155,7 @@ Without `--wait`, `attention` prints the event ID when questions are present, so
156
155
  the agent can check later with `attention-status`.
157
156
 
158
157
  Delivery: the human answers in the dashboard inbox. A live waiter (`--wait`,
159
- `attention-status --wait`, or MCP `attention_get` polling) receives the answer
158
+ or `attention-status --wait`) receives the answer
160
159
  directly. If nobody is waiting, the answer is sent as ftown mail from "You"
161
160
  (`fromName` "You", thread `attention:<id>`) whose body starts with
162
161
  `[ftown attention answer id=<id>]`. Claude Code `AskUserQuestion` calls inside an
@@ -171,19 +170,7 @@ Attaching/replacing/clearing is metadata-only; omitting it on an update preserve
171
170
  its value. New sessions/children do not implicitly inherit a parent's PR.
172
171
 
173
172
  New commands probe the exact bridge capability before writing; update old bridges
174
- with the exact version setup command in their readiness hint. For remote MCP,
175
- `attention_request` requires explicit `{machine, sessionId, message, title?}` and
176
- returns `{machine, sessionId, event}`; it also accepts optional `questions` (1 to
177
- 4 entries, shaped as above) when the bridge reports `prompt`. `attention_get`
178
- takes `{machine, sessionId, eventId, waitSeconds?}` (`waitSeconds` 0..25) and
179
- returns `{machine, sessionId, event}`. Poll it until the event is resolved
180
- (`resolvedAt` set): `event.answer` holds the answer, and a resolution without an
181
- answer means the question was dismissed.
182
-
183
- `sessions_update` accepts `pullRequestUrl` (string or null), alongside existing
184
- name/parent fields. A mixed PR+name update rejects an old bridge before changing
185
- either field. Read-only MCP clients cannot see these mutation tools; control
186
- authorization and machine ownership still apply.
173
+ with the exact version setup command in their readiness hint.
187
174
 
188
175
  ## Messaging (mail)
189
176
 
@@ -265,10 +252,7 @@ ftown sessions attention --title 'Work complete' \
265
252
  ```
266
253
 
267
254
  For tasks without a PR, omit the PR command and PR summary. Use the verified
268
- `FTOWN_SESSION_ID` or explicit `--session-id`; never guess a target. MCP callers
269
- instead use `sessions_update` with `pullRequestUrl` when applicable, then
270
- `attention_request` with title `Work complete` and the same truthful summary,
271
- always supplying explicit `machine` and `sessionId`.
255
+ `FTOWN_SESSION_ID` or explicit `--session-id`; never guess a target.
272
256
 
273
257
  Send one completion request per completed task, not repeated per-turn notices.
274
258
  Logical duplicate coalescing does not justify retries after an uncertain outcome;
@@ -1,67 +0,0 @@
1
- import { z } from "zod";
2
- import { type McpRequestContext } from './secure-client.js';
3
- export declare const configSchema: z.ZodObject<{
4
- concurrency: z.ZodDefault<z.ZodNumber>;
5
- timeoutMs: z.ZodDefault<z.ZodNumber>;
6
- machines: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
7
- transport: z.ZodLiteral<"relay">;
8
- userId: z.ZodString;
9
- id: z.ZodString;
10
- label: z.ZodOptional<z.ZodString>;
11
- }, z.core.$strict>, z.ZodObject<{
12
- transport: z.ZodLiteral<"local">;
13
- bridgeFile: z.ZodOptional<z.ZodString>;
14
- id: z.ZodString;
15
- label: z.ZodOptional<z.ZodString>;
16
- }, z.core.$strict>, z.ZodObject<{
17
- transport: z.ZodLiteral<"ssh">;
18
- host: z.ZodString;
19
- executable: z.ZodDefault<z.ZodString>;
20
- id: z.ZodString;
21
- label: z.ZodOptional<z.ZodString>;
22
- }, z.core.$strict>, z.ZodObject<{
23
- transport: z.ZodLiteral<"http">;
24
- url: z.ZodString;
25
- tokenEnv: z.ZodString;
26
- id: z.ZodString;
27
- label: z.ZodOptional<z.ZodString>;
28
- }, z.core.$strict>], "transport">>;
29
- }, z.core.$strict>;
30
- export type FleetConfig = z.infer<typeof configSchema>;
31
- export declare const requestSchema: z.ZodObject<{
32
- method: z.ZodEnum<{
33
- GET: "GET";
34
- POST: "POST";
35
- PATCH: "PATCH";
36
- DELETE: "DELETE";
37
- }>;
38
- path: z.ZodString;
39
- body: z.ZodOptional<z.ZodUnknown>;
40
- timeoutMs: z.ZodNumber;
41
- }, z.core.$strict>;
42
- export type BridgeRequest = z.infer<typeof requestSchema>;
43
- export declare class FleetError extends Error {
44
- readonly code: string;
45
- readonly outcomeUnknown: boolean;
46
- readonly status?: number | undefined;
47
- constructor(code: string, message: string, outcomeUnknown?: boolean, status?: number | undefined);
48
- }
49
- export declare function errorResult(error: unknown): {
50
- status?: number | undefined;
51
- code: string;
52
- message: string;
53
- outcomeUnknown: boolean;
54
- };
55
- export declare function httpRequest(origin: string, token: string, request: BridgeRequest, signal?: AbortSignal): Promise<any>;
56
- export declare function localRequest(request: BridgeRequest, bridgeFile?: string, signal?: AbortSignal, context?: McpRequestContext, machineId?: string): Promise<unknown>;
57
- export declare function loadConfig(path?: string): Promise<FleetConfig>;
58
- export declare function mapLimit<T, R>(items: T[], concurrency: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
59
- export declare class Fleet {
60
- readonly config: FleetConfig;
61
- private relay?;
62
- private active;
63
- private waiters;
64
- constructor(config: FleetConfig, relay?: ((userId: string, machineId: string, request: BridgeRequest, signal?: AbortSignal, context?: McpRequestContext) => Promise<unknown>) | undefined);
65
- scoped(context: McpRequestContext): Pick<Fleet, 'config' | 'request'>;
66
- request(machineId: string, method: BridgeRequest["method"], path: string, body?: unknown, signal?: AbortSignal, timeoutMs?: number, context?: McpRequestContext): Promise<any>;
67
- }
package/dist/mcp/fleet.js DELETED
@@ -1,298 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- import { homedir } from "node:os";
3
- import { join } from "node:path";
4
- import { z } from "zod";
5
- import { parseSecureEnvelope, MAX_ENVELOPE_BYTES, SecurityError } from '../security/crypto.js';
6
- import { SecureMcpClient } from './secure-client.js';
7
- const machineBase = {
8
- id: z.string().regex(/^[a-zA-Z0-9_-]+$/),
9
- label: z.string().optional(),
10
- };
11
- export const configSchema = z
12
- .object({
13
- concurrency: z.number().int().min(1).max(32).default(8),
14
- timeoutMs: z.number().int().min(1000).max(60000).default(15000),
15
- machines: z
16
- .array(z.discriminatedUnion("transport", [
17
- z
18
- .object({
19
- ...machineBase,
20
- transport: z.literal("relay"),
21
- userId: z.string().email(),
22
- })
23
- .strict(),
24
- z
25
- .object({
26
- ...machineBase,
27
- transport: z.literal("local"),
28
- bridgeFile: z.string().optional(),
29
- })
30
- .strict(),
31
- z
32
- .object({
33
- ...machineBase,
34
- transport: z.literal("ssh"),
35
- host: z.string().regex(/^[a-zA-Z0-9_][a-zA-Z0-9_.@:-]*$/),
36
- executable: z.string().min(1).default("ftown-mcp"),
37
- })
38
- .strict(),
39
- z
40
- .object({
41
- ...machineBase,
42
- transport: z.literal("http"),
43
- url: z.string().url(),
44
- tokenEnv: z.string().min(1),
45
- })
46
- .strict(),
47
- ]))
48
- .min(1)
49
- .max(1000),
50
- })
51
- .strict()
52
- .superRefine((config, ctx) => {
53
- if (new Set(config.machines.map((m) => m.id)).size !== config.machines.length)
54
- ctx.addIssue({ code: "custom", message: "Machine IDs must be unique" });
55
- for (const m of config.machines)
56
- if (m.transport === "http") {
57
- const u = new URL(m.url);
58
- if (u.username ||
59
- u.password ||
60
- u.search ||
61
- u.hash ||
62
- u.pathname !== "/" ||
63
- !(u.protocol === "https:" ||
64
- (u.protocol === "http:" &&
65
- ["localhost", "127.0.0.1", "[::1]"].includes(u.hostname)))) {
66
- ctx.addIssue({
67
- code: "custom",
68
- message: "HTTP machines require an HTTPS origin or loopback HTTP origin without embedded credentials",
69
- });
70
- }
71
- }
72
- });
73
- export const requestSchema = z
74
- .object({
75
- method: z.enum(["GET", "POST", "PATCH", "DELETE"]),
76
- path: z
77
- .string()
78
- .regex(/^\/api\/(?:archive|sessions(?:\/[a-zA-Z0-9_-]+(?:\/(?:screen|grep|keys|message|inbox|resize|usage|running|revive|stop|retry|preview-chat\/reply|attention(?:\/(?:ack|resolve))?))?)?)(?:\?[^#]*)?$/),
79
- body: z.unknown().optional(),
80
- timeoutMs: z.number().int().min(1000).max(60000),
81
- })
82
- .strict();
83
- export class FleetError extends Error {
84
- code;
85
- outcomeUnknown;
86
- status;
87
- constructor(code, message, outcomeUnknown = false, status) {
88
- super(message);
89
- this.code = code;
90
- this.outcomeUnknown = outcomeUnknown;
91
- this.status = status;
92
- }
93
- }
94
- export function errorResult(error) {
95
- if (error instanceof SecurityError)
96
- return { code: error.code, message: error.message, outcomeUnknown: error.code === 'outcome_unknown' };
97
- if (error instanceof FleetError)
98
- return {
99
- code: error.code,
100
- message: error.message,
101
- outcomeUnknown: error.outcomeUnknown,
102
- ...(error.status ? { status: error.status } : {}),
103
- };
104
- return {
105
- code: "internal_error",
106
- message: "Operation failed",
107
- outcomeUnknown: false,
108
- };
109
- }
110
- const maxBytes = 4 * 1024 * 1024;
111
- export async function httpRequest(origin, token, request, signal) {
112
- const timeout = AbortSignal.timeout(request.timeoutMs);
113
- try {
114
- const res = await fetch(new URL(request.path, origin), {
115
- method: request.method,
116
- redirect: "error",
117
- headers: {
118
- Authorization: `Bearer ${token}`,
119
- "Content-Type": "application/json",
120
- },
121
- body: request.body === undefined ? undefined : JSON.stringify(request.body),
122
- signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
123
- });
124
- const reader = res.body?.getReader();
125
- let size = 0;
126
- const chunks = [];
127
- if (reader)
128
- try {
129
- while (true) {
130
- const { done, value } = await reader.read();
131
- if (done)
132
- break;
133
- size += value.byteLength;
134
- if (size > maxBytes) {
135
- await reader.cancel();
136
- throw new FleetError("response_too_large", "Bridge response exceeds 4 MiB; narrow the request", request.method !== "GET");
137
- }
138
- chunks.push(value);
139
- }
140
- }
141
- finally {
142
- reader.releaseLock();
143
- }
144
- const data = JSON.parse(Buffer.concat(chunks).toString("utf8"));
145
- if (!res.ok) {
146
- const detail = typeof data?.error === "string"
147
- ? data.error.replaceAll(token, "[redacted]").slice(0, 1000)
148
- : "Bridge request rejected";
149
- throw new FleetError(typeof data?.code === "string" && ["unknown_session", "invalid_cursor", "unknown_attention", "attention_not_found", "attention_storage_error", "cancelled", "attention_not_ready"].includes(data.code) ? data.code : "bridge_error", `${detail} (HTTP ${res.status})`, request.method !== "GET" && res.status >= 500, res.status);
150
- }
151
- return data;
152
- }
153
- catch (error) {
154
- if (error instanceof FleetError)
155
- throw error;
156
- throw new FleetError(signal?.aborted
157
- ? "cancelled"
158
- : timeout.aborted
159
- ? "timeout"
160
- : "connection_error", "Bridge request failed; check machine connectivity and credentials", request.method !== "GET");
161
- }
162
- }
163
- export async function localRequest(request, bridgeFile = join(homedir(), ".ftown", "bridge.json"), signal, context, machineId) {
164
- if (!context || !machineId)
165
- throw new FleetError('upgrade_required', 'Legacy MCP proxy requests require an approved encrypted endpoint');
166
- let credentials;
167
- try {
168
- credentials = z
169
- .object({
170
- port: z.number().int().min(1).max(65535),
171
- })
172
- .parse(JSON.parse(await readFile(bridgeFile, "utf8")));
173
- }
174
- catch {
175
- throw new FleetError("configuration_error", "Cannot read bridge credentials; start ftown-bridge on this machine");
176
- }
177
- return secureHttpRequest(`http://127.0.0.1:${credentials.port}`, context, machineId, requestSchema.parse(request), signal);
178
- }
179
- async function secureHttpRequest(origin, context, machineId, request, signal) {
180
- const client = new SecureMcpClient(context, machineId, `local-http:${machineId}`, async (packet, deadline, mutating, abort) => {
181
- let sent = false;
182
- try {
183
- if (abort?.aborted || Date.now() >= deadline)
184
- throw new FleetError('cancelled', 'Encrypted request cancelled before dispatch');
185
- sent = true;
186
- const timeout = AbortSignal.timeout(Math.max(1, deadline - Date.now()));
187
- const response = await fetch(new URL('/api/security/envelope', origin), { method: 'POST', redirect: 'error', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(packet), signal: abort ? AbortSignal.any([abort, timeout]) : timeout });
188
- if (!response.ok)
189
- throw new FleetError([404, 426].includes(response.status) ? 'upgrade_required' : 'bridge_error', 'Bridge encrypted endpoint is unavailable', mutating && response.status >= 500, response.status);
190
- const reader = response.body?.getReader();
191
- if (!reader)
192
- throw new FleetError('bridge_error', 'Bridge encrypted response is missing', mutating);
193
- let size = 0;
194
- const chunks = [];
195
- try {
196
- while (true) {
197
- const chunk = await reader.read();
198
- if (chunk.done)
199
- break;
200
- size += chunk.value.byteLength;
201
- if (size > MAX_ENVELOPE_BYTES) {
202
- await reader.cancel();
203
- throw new FleetError('response_too_large', 'Encrypted bridge response is too large', mutating);
204
- }
205
- chunks.push(chunk.value);
206
- }
207
- }
208
- finally {
209
- reader.releaseLock();
210
- }
211
- return parseSecureEnvelope(JSON.parse(Buffer.concat(chunks).toString('utf8')));
212
- }
213
- catch (error) {
214
- if (error instanceof FleetError)
215
- throw error;
216
- throw new FleetError(abort?.aborted ? 'cancelled' : 'connection_error', 'Encrypted bridge request failed', sent && mutating);
217
- }
218
- });
219
- return client.request(request, signal);
220
- }
221
- export async function loadConfig(path) {
222
- return configSchema.parse(path
223
- ? JSON.parse(await readFile(path, "utf8"))
224
- : { machines: [{ id: "local", transport: "local" }] });
225
- }
226
- export async function mapLimit(items, concurrency, fn) {
227
- const results = new Array(items.length);
228
- let next = 0;
229
- await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, async () => {
230
- while (next < items.length) {
231
- const index = next++;
232
- results[index] = await fn(items[index], index);
233
- }
234
- }));
235
- return results;
236
- }
237
- export class Fleet {
238
- config;
239
- relay;
240
- active = 0;
241
- waiters = [];
242
- constructor(config, relay) {
243
- this.config = config;
244
- this.relay = relay;
245
- }
246
- scoped(context) {
247
- return { config: this.config, request: (machineId, method, path, body, signal, timeout) => this.request(machineId, method, path, body, signal, timeout, context) };
248
- }
249
- async request(machineId, method, path, body, signal, timeoutMs = this.config.timeoutMs, context) {
250
- const machine = this.config.machines.find((m) => m.id === machineId);
251
- if (!machine)
252
- throw new FleetError("unknown_machine", `Unknown machine: ${machineId}`);
253
- const request = requestSchema.parse({ method, path, body, timeoutMs });
254
- if (!context)
255
- throw new FleetError('approval_required', 'An encrypted MCP grant is required');
256
- if (this.active >= this.config.concurrency)
257
- await new Promise((resolve, reject) => {
258
- const acquire = () => { signal?.removeEventListener("abort", cancel); resolve(); };
259
- const cancel = () => {
260
- const index = this.waiters.indexOf(acquire);
261
- if (index !== -1)
262
- this.waiters.splice(index, 1);
263
- signal?.removeEventListener("abort", cancel);
264
- reject(new FleetError("cancelled", "Request cancelled before dispatch"));
265
- };
266
- this.waiters.push(acquire);
267
- signal?.addEventListener("abort", cancel, { once: true });
268
- if (signal?.aborted)
269
- cancel();
270
- });
271
- else
272
- this.active++;
273
- try {
274
- await context.revalidate?.();
275
- if (signal?.aborted)
276
- throw new FleetError("cancelled", "Request cancelled before dispatch");
277
- if (machine.transport === "relay") {
278
- if (!this.relay)
279
- throw new FleetError("configuration_error", "Relay transport is not configured");
280
- return await this.relay(machine.userId, machine.id, request, signal, context);
281
- }
282
- if (machine.transport === "local")
283
- return await localRequest(request, machine.bridgeFile, signal, context, machine.id);
284
- if (machine.transport === "http") {
285
- return await secureHttpRequest(machine.url, context, machine.id, request, signal);
286
- }
287
- throw new FleetError('upgrade_required', 'Legacy SSH MCP adapters do not negotiate encrypted endpoint framing');
288
- }
289
- finally {
290
- const next = this.waiters.shift();
291
- if (next)
292
- next();
293
- else
294
- this.active--;
295
- }
296
- }
297
- }
298
- //# sourceMappingURL=fleet.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fleet.js","sourceRoot":"","sources":["../../src/mcp/fleet.ts"],"names":[],"mappings":"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"}
@@ -1,42 +0,0 @@
1
- import { z } from "zod";
2
- import type { FleetRelay } from "./relay.js";
3
- import { FtownOAuthProvider } from "./oauth.js";
4
- import { SecurityEventStore } from './security-events.js';
5
- export declare const gatewayConfigSchema: z.ZodObject<{
6
- publicUrl: z.ZodString;
7
- loginUrl: z.ZodString;
8
- allowedOrigins: z.ZodDefault<z.ZodArray<z.ZodString>>;
9
- fleet: z.ZodObject<{
10
- concurrency: z.ZodDefault<z.ZodNumber>;
11
- timeoutMs: z.ZodDefault<z.ZodNumber>;
12
- machines: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
13
- transport: z.ZodLiteral<"relay">;
14
- userId: z.ZodString;
15
- id: z.ZodString;
16
- label: z.ZodOptional<z.ZodString>;
17
- }, z.core.$strict>, z.ZodObject<{
18
- transport: z.ZodLiteral<"local">;
19
- bridgeFile: z.ZodOptional<z.ZodString>;
20
- id: z.ZodString;
21
- label: z.ZodOptional<z.ZodString>;
22
- }, z.core.$strict>, z.ZodObject<{
23
- transport: z.ZodLiteral<"ssh">;
24
- host: z.ZodString;
25
- executable: z.ZodDefault<z.ZodString>;
26
- id: z.ZodString;
27
- label: z.ZodOptional<z.ZodString>;
28
- }, z.core.$strict>, z.ZodObject<{
29
- transport: z.ZodLiteral<"http">;
30
- url: z.ZodString;
31
- tokenEnv: z.ZodString;
32
- id: z.ZodString;
33
- label: z.ZodOptional<z.ZodString>;
34
- }, z.core.$strict>], "transport">>;
35
- }, z.core.$strict>;
36
- access: z.ZodArray<z.ZodObject<{
37
- subject: z.ZodString;
38
- machines: z.ZodArray<z.ZodString>;
39
- }, z.core.$strict>>;
40
- }, z.core.$strict>;
41
- export type GatewayConfig = z.infer<typeof gatewayConfigSchema>;
42
- export declare function createGateway(config: GatewayConfig, provider: FtownOAuthProvider, relay?: FleetRelay, audit?: Pick<SecurityEventStore, 'admit' | 'finish'>): import("express-serve-static-core").Express;