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.
- package/dist/attention-prompt-protocol.d.ts +2 -2
- package/dist/attention-prompt-protocol.js +1 -1
- package/dist/centrifugo-client.js +0 -1
- package/dist/centrifugo-client.js.map +1 -1
- package/dist/command-rpc.d.ts +0 -1
- package/dist/command-rpc.js +3 -24
- package/dist/command-rpc.js.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/security/bridge/account-state.d.ts +0 -4
- package/dist/security/bridge/direct.js +0 -2
- package/dist/security/bridge/direct.js.map +1 -1
- package/dist/security/bridge/execute.js +1 -6
- package/dist/security/bridge/execute.js.map +1 -1
- package/dist/security/bridge/identity.d.ts +0 -3
- package/dist/security/bridge/metadata.d.ts +0 -2
- package/dist/security/bridge/metadata.js +1 -1
- package/dist/security/bridge/metadata.js.map +1 -1
- package/dist/security/bridge/permissions.js +3 -11
- package/dist/security/bridge/permissions.js.map +1 -1
- package/dist/security/bridge/policy.d.ts +4 -7
- package/dist/security/bridge/policy.js +35 -90
- package/dist/security/bridge/policy.js.map +1 -1
- package/dist/security/bridge/security.d.ts +1 -11
- package/dist/security/bridge/security.js +7 -79
- package/dist/security/bridge/security.js.map +1 -1
- package/dist/security/crypto.js +2 -2
- package/dist/security/crypto.js.map +1 -1
- package/dist/security/protocol.d.ts +5 -126
- package/dist/types.d.ts +1 -1
- package/dist/update-effects.js +1 -1
- package/dist/update-effects.js.map +1 -1
- package/package.json +4 -12
- package/skills/ftown/SKILL.md +9 -13
- package/skills/ftown/references/sessions.md +4 -20
- package/dist/mcp/fleet.d.ts +0 -67
- package/dist/mcp/fleet.js +0 -298
- package/dist/mcp/fleet.js.map +0 -1
- package/dist/mcp/http.d.ts +0 -42
- package/dist/mcp/http.js +0 -350
- package/dist/mcp/http.js.map +0 -1
- package/dist/mcp/legacy-relay.d.ts +0 -3
- package/dist/mcp/legacy-relay.js +0 -6
- package/dist/mcp/legacy-relay.js.map +0 -1
- package/dist/mcp/mcp-key-store.d.ts +0 -52
- package/dist/mcp/mcp-key-store.js +0 -207
- package/dist/mcp/mcp-key-store.js.map +0 -1
- package/dist/mcp/oauth-store.d.ts +0 -17
- package/dist/mcp/oauth-store.js +0 -58
- package/dist/mcp/oauth-store.js.map +0 -1
- package/dist/mcp/oauth.d.ts +0 -83
- package/dist/mcp/oauth.js +0 -311
- package/dist/mcp/oauth.js.map +0 -1
- package/dist/mcp/relay-handler.d.ts +0 -2
- package/dist/mcp/relay-handler.js +0 -8
- package/dist/mcp/relay-handler.js.map +0 -1
- package/dist/mcp/relay.d.ts +0 -13
- package/dist/mcp/relay.js +0 -95
- package/dist/mcp/relay.js.map +0 -1
- package/dist/mcp/secure-client.d.ts +0 -23
- package/dist/mcp/secure-client.js +0 -124
- package/dist/mcp/secure-client.js.map +0 -1
- package/dist/mcp/security-events.d.ts +0 -49
- package/dist/mcp/security-events.js +0 -211
- package/dist/mcp/security-events.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -13
- package/dist/mcp/server.js +0 -858
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/test-support.d.ts +0 -32
- package/dist/mcp/test-support.js +0 -120
- package/dist/mcp/test-support.js.map +0 -1
- package/dist/mcp-cli.d.ts +0 -2
- package/dist/mcp-cli.js +0 -105
- package/dist/mcp-cli.js.map +0 -1
- package/dist/security/bridge/audit.d.ts +0 -37
- package/dist/security/bridge/audit.js +0 -186
- 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.
|
|
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": "
|
|
75
|
+
"gitHead": "5828f409f518cbb17ebc19aef0166dec90b7a04b"
|
|
84
76
|
}
|
package/skills/ftown/SKILL.md
CHANGED
|
@@ -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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
143
|
-
|
|
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>"
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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;
|
package/dist/mcp/fleet.d.ts
DELETED
|
@@ -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
|
package/dist/mcp/fleet.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fleet.js","sourceRoot":"","sources":["../../src/mcp/fleet.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/http.d.ts
DELETED
|
@@ -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;
|