taskflow-mcp-core 0.3.0-beta.1.1 → 1.0.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/CONTROL_GUIDE.md +113 -0
- package/README.md +34 -25
- package/dist/control/admission-service.d.ts +15 -0
- package/dist/control/admission-service.d.ts.map +1 -0
- package/dist/control/admission-service.js +64 -0
- package/dist/control/admission-service.js.map +1 -0
- package/dist/control/approval-edits.d.ts +12 -0
- package/dist/control/approval-edits.d.ts.map +1 -0
- package/dist/control/approval-edits.js +66 -0
- package/dist/control/approval-edits.js.map +1 -0
- package/dist/control/approval-service.d.ts +173 -0
- package/dist/control/approval-service.d.ts.map +1 -0
- package/dist/control/approval-service.js +342 -0
- package/dist/control/approval-service.js.map +1 -0
- package/dist/control/authorization.d.ts +94 -0
- package/dist/control/authorization.d.ts.map +1 -0
- package/dist/control/authorization.js +302 -0
- package/dist/control/authorization.js.map +1 -0
- package/dist/control/control-cli.d.ts +3 -0
- package/dist/control/control-cli.d.ts.map +1 -0
- package/dist/control/control-cli.js +279 -0
- package/dist/control/control-cli.js.map +1 -0
- package/dist/control/control-console.d.ts +17 -0
- package/dist/control/control-console.d.ts.map +1 -0
- package/dist/control/control-console.js +67 -0
- package/dist/control/control-console.js.map +1 -0
- package/dist/control/control-host.d.ts +98 -0
- package/dist/control/control-host.d.ts.map +1 -0
- package/dist/control/control-host.js +459 -0
- package/dist/control/control-host.js.map +1 -0
- package/dist/control/control-mcp.d.ts +11 -0
- package/dist/control/control-mcp.d.ts.map +1 -0
- package/dist/control/control-mcp.js +78 -0
- package/dist/control/control-mcp.js.map +1 -0
- package/dist/control/errors.d.ts +44 -0
- package/dist/control/errors.d.ts.map +1 -0
- package/dist/control/errors.js +93 -0
- package/dist/control/errors.js.map +1 -0
- package/dist/control/hello.d.ts +39 -0
- package/dist/control/hello.d.ts.map +1 -0
- package/dist/control/hello.js +80 -0
- package/dist/control/hello.js.map +1 -0
- package/dist/control/host-runtime.d.ts +32 -0
- package/dist/control/host-runtime.d.ts.map +1 -0
- package/dist/control/host-runtime.js +542 -0
- package/dist/control/host-runtime.js.map +1 -0
- package/dist/control/index.d.ts +32 -0
- package/dist/control/index.d.ts.map +1 -0
- package/dist/control/index.js +32 -0
- package/dist/control/index.js.map +1 -0
- package/dist/control/legacy-conflict.d.ts +19 -0
- package/dist/control/legacy-conflict.d.ts.map +1 -0
- package/dist/control/legacy-conflict.js +176 -0
- package/dist/control/legacy-conflict.js.map +1 -0
- package/dist/control/local-bootstrap.d.ts +21 -0
- package/dist/control/local-bootstrap.d.ts.map +1 -0
- package/dist/control/local-bootstrap.js +224 -0
- package/dist/control/local-bootstrap.js.map +1 -0
- package/dist/control/modes.d.ts +60 -0
- package/dist/control/modes.d.ts.map +1 -0
- package/dist/control/modes.js +86 -0
- package/dist/control/modes.js.map +1 -0
- package/dist/control/project-admin-cli.d.ts +3 -0
- package/dist/control/project-admin-cli.d.ts.map +1 -0
- package/dist/control/project-admin-cli.js +155 -0
- package/dist/control/project-admin-cli.js.map +1 -0
- package/dist/control/project-registry.d.ts +20 -0
- package/dist/control/project-registry.d.ts.map +1 -0
- package/dist/control/project-registry.js +181 -0
- package/dist/control/project-registry.js.map +1 -0
- package/dist/control/runtime-checkpoint.d.ts +11 -0
- package/dist/control/runtime-checkpoint.d.ts.map +1 -0
- package/dist/control/runtime-checkpoint.js +39 -0
- package/dist/control/runtime-checkpoint.js.map +1 -0
- package/dist/control/runtime-provider.d.ts +100 -0
- package/dist/control/runtime-provider.d.ts.map +1 -0
- package/dist/control/runtime-provider.js +258 -0
- package/dist/control/runtime-provider.js.map +1 -0
- package/dist/control/schema/approval.d.ts +108 -0
- package/dist/control/schema/approval.d.ts.map +1 -0
- package/dist/control/schema/approval.js +65 -0
- package/dist/control/schema/approval.js.map +1 -0
- package/dist/control/schema/commands.d.ts +663 -0
- package/dist/control/schema/commands.d.ts.map +1 -0
- package/dist/control/schema/commands.js +147 -0
- package/dist/control/schema/commands.js.map +1 -0
- package/dist/control/schema/common.d.ts +24 -0
- package/dist/control/schema/common.d.ts.map +1 -0
- package/dist/control/schema/common.js +38 -0
- package/dist/control/schema/common.js.map +1 -0
- package/dist/control/schema/coordinator.d.ts +98 -0
- package/dist/control/schema/coordinator.d.ts.map +1 -0
- package/dist/control/schema/coordinator.js +87 -0
- package/dist/control/schema/coordinator.js.map +1 -0
- package/dist/control/schema/evidence.d.ts +140 -0
- package/dist/control/schema/evidence.d.ts.map +1 -0
- package/dist/control/schema/evidence.js +64 -0
- package/dist/control/schema/evidence.js.map +1 -0
- package/dist/control/schema/header.d.ts +79 -0
- package/dist/control/schema/header.d.ts.map +1 -0
- package/dist/control/schema/header.js +66 -0
- package/dist/control/schema/header.js.map +1 -0
- package/dist/control/schema/index.d.ts +31 -0
- package/dist/control/schema/index.d.ts.map +1 -0
- package/dist/control/schema/index.js +31 -0
- package/dist/control/schema/index.js.map +1 -0
- package/dist/control/schema/plan.d.ts +291 -0
- package/dist/control/schema/plan.d.ts.map +1 -0
- package/dist/control/schema/plan.js +80 -0
- package/dist/control/schema/plan.js.map +1 -0
- package/dist/control/schema/policy.d.ts +96 -0
- package/dist/control/schema/policy.d.ts.map +1 -0
- package/dist/control/schema/policy.js +73 -0
- package/dist/control/schema/policy.js.map +1 -0
- package/dist/control/schema/run.d.ts +61 -0
- package/dist/control/schema/run.d.ts.map +1 -0
- package/dist/control/schema/run.js +56 -0
- package/dist/control/schema/run.js.map +1 -0
- package/dist/control/schema/te-mirrors.d.ts +145 -0
- package/dist/control/schema/te-mirrors.d.ts.map +1 -0
- package/dist/control/schema/te-mirrors.js +145 -0
- package/dist/control/schema/te-mirrors.js.map +1 -0
- package/dist/control/schema/transport.d.ts +479 -0
- package/dist/control/schema/transport.d.ts.map +1 -0
- package/dist/control/schema/transport.js +181 -0
- package/dist/control/schema/transport.js.map +1 -0
- package/dist/control/singleton.d.ts +135 -0
- package/dist/control/singleton.d.ts.map +1 -0
- package/dist/control/singleton.js +607 -0
- package/dist/control/singleton.js.map +1 -0
- package/dist/control/store/coordinator-store.d.ts +143 -0
- package/dist/control/store/coordinator-store.d.ts.map +1 -0
- package/dist/control/store/coordinator-store.js +620 -0
- package/dist/control/store/coordinator-store.js.map +1 -0
- package/dist/control/store/evidence-adapter.d.ts +10 -0
- package/dist/control/store/evidence-adapter.d.ts.map +1 -0
- package/dist/control/store/evidence-adapter.js +114 -0
- package/dist/control/store/evidence-adapter.js.map +1 -0
- package/dist/control/store/evidence-explanation.d.ts +55 -0
- package/dist/control/store/evidence-explanation.d.ts.map +1 -0
- package/dist/control/store/evidence-explanation.js +50 -0
- package/dist/control/store/evidence-explanation.js.map +1 -0
- package/dist/control/store/evidence-store.d.ts +143 -0
- package/dist/control/store/evidence-store.d.ts.map +1 -0
- package/dist/control/store/evidence-store.js +437 -0
- package/dist/control/store/evidence-store.js.map +1 -0
- package/dist/control/store/index.d.ts +3 -0
- package/dist/control/store/index.d.ts.map +1 -0
- package/dist/control/store/index.js +2 -0
- package/dist/control/store/index.js.map +1 -0
- package/dist/control/store/journal.d.ts +270 -0
- package/dist/control/store/journal.d.ts.map +1 -0
- package/dist/control/store/journal.js +50 -0
- package/dist/control/store/journal.js.map +1 -0
- package/dist/control/store/project-lifecycle.d.ts +49 -0
- package/dist/control/store/project-lifecycle.d.ts.map +1 -0
- package/dist/control/store/project-lifecycle.js +288 -0
- package/dist/control/store/project-lifecycle.js.map +1 -0
- package/dist/control/store/store.d.ts +93 -0
- package/dist/control/store/store.d.ts.map +1 -0
- package/dist/control/store/store.js +873 -0
- package/dist/control/store/store.js.map +1 -0
- package/dist/control/te-provider.d.ts +86 -0
- package/dist/control/te-provider.d.ts.map +1 -0
- package/dist/control/te-provider.js +131 -0
- package/dist/control/te-provider.js.map +1 -0
- package/dist/control/uds.d.ts +114 -0
- package/dist/control/uds.d.ts.map +1 -0
- package/dist/control/uds.js +456 -0
- package/dist/control/uds.js.map +1 -0
- package/dist/control/web-console/view.d.ts +5 -0
- package/dist/control/web-console/view.d.ts.map +1 -0
- package/dist/control/web-console/view.js +122 -0
- package/dist/control/web-console/view.js.map +1 -0
- package/dist/control/web-console.d.ts +50 -0
- package/dist/control/web-console.d.ts.map +1 -0
- package/dist/control/web-console.js +317 -0
- package/dist/control/web-console.js.map +1 -0
- package/dist/mcp/jsonrpc.d.ts.map +1 -1
- package/dist/mcp/jsonrpc.js +12 -3
- package/dist/mcp/jsonrpc.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +26 -17
- package/dist/mcp/server.js.map +1 -1
- package/package.json +13 -5
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unix domain socket transport for the ControlHost (beta.2 S2 收口 — A2/A2b).
|
|
3
|
+
*
|
|
4
|
+
* The winner of the user singleton lock `listen`s on `singletonPaths().endpointPath`;
|
|
5
|
+
* every other process `connect`s as a client. The wire is newline-delimited
|
|
6
|
+
* JSON (one frame per line):
|
|
7
|
+
*
|
|
8
|
+
* {"type":"hello","hello":<NegotiationHandshake>}
|
|
9
|
+
* {"type":"hello-ack","ok":true,"serverHello":<...>,"fencingEpoch":N}
|
|
10
|
+
* {"type":"hello-ack","ok":false,"error":<ErrorEnvelope>}
|
|
11
|
+
* {"type":"rpc","id":N,"method":"control.probe","params":...,"fencingEpoch":N}
|
|
12
|
+
* {"type":"rpc-result","id":N,"ok":true,"result":...}
|
|
13
|
+
* {"type":"rpc-result","id":N,"ok":false,"error":<ErrorEnvelope>}
|
|
14
|
+
*
|
|
15
|
+
* Hello-before-RPC (P4) is enforced per connection: the first frame MUST be a
|
|
16
|
+
* hello, a failed hello closes the socket, and a `protocolMajor` mismatch is
|
|
17
|
+
* rejected on the wire (TF_PROTOCOL_INCOMPATIBLE). The socket permission is
|
|
18
|
+
* explicitly chmod'ed to 0o600 — never umask luck (plan §4.1).
|
|
19
|
+
*
|
|
20
|
+
* Unix-only transport: Windows named pipe is explicitly NON-GA in 0.3-C.
|
|
21
|
+
*/
|
|
22
|
+
import * as fs from "node:fs";
|
|
23
|
+
import * as net from "node:net";
|
|
24
|
+
import { Value } from "typebox/value";
|
|
25
|
+
import { bootstrapFailed, ControlError, errorFromEnvelope, errorToEnvelope, protocolError } from "./errors.js";
|
|
26
|
+
import { createHelloGate } from "./hello.js";
|
|
27
|
+
import { ErrorEnvelopeSchema, NegotiationHandshakeSchema } from "./schema/transport.js";
|
|
28
|
+
/** Per-frame UTF-8 limit; large plans/evidence can use up to 16 MiB by default. */
|
|
29
|
+
export const UDS_MAX_FRAME_BYTES = 16 * 1024 * 1024;
|
|
30
|
+
function frameLimit(value = UDS_MAX_FRAME_BYTES) {
|
|
31
|
+
if (!Number.isSafeInteger(value) || value < 1)
|
|
32
|
+
throw new RangeError("maxFrameBytes must be a positive safe integer");
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function isWireCounter(value) {
|
|
36
|
+
return Number.isSafeInteger(value) && value >= 0;
|
|
37
|
+
}
|
|
38
|
+
function encodeFrame(frame, maxBytes = UDS_MAX_FRAME_BYTES) {
|
|
39
|
+
const encoded = JSON.stringify(frame);
|
|
40
|
+
if (Buffer.byteLength(encoded, "utf8") > maxBytes)
|
|
41
|
+
throw new Error(`control wire frame exceeds ${maxBytes} bytes`);
|
|
42
|
+
return encoded + "\n";
|
|
43
|
+
}
|
|
44
|
+
/** Bound each frame before appending; coalesced frames have independent budgets. */
|
|
45
|
+
function frameReader(maxBytes) {
|
|
46
|
+
let buffer = "";
|
|
47
|
+
let bytes = 0;
|
|
48
|
+
const clear = () => { buffer = ""; bytes = 0; };
|
|
49
|
+
return {
|
|
50
|
+
clear,
|
|
51
|
+
push(chunk, onLine) {
|
|
52
|
+
let start = 0;
|
|
53
|
+
while (start < chunk.length) {
|
|
54
|
+
const end = chunk.indexOf("\n", start);
|
|
55
|
+
const part = chunk.slice(start, end < 0 ? undefined : end);
|
|
56
|
+
const addedBytes = Buffer.byteLength(part, "utf8");
|
|
57
|
+
if (bytes + addedBytes > maxBytes)
|
|
58
|
+
throw new Error(`control wire frame exceeds ${maxBytes} bytes`);
|
|
59
|
+
buffer += part;
|
|
60
|
+
bytes += addedBytes;
|
|
61
|
+
if (end < 0)
|
|
62
|
+
return;
|
|
63
|
+
const line = buffer.trim();
|
|
64
|
+
clear();
|
|
65
|
+
if (line && !onLine(line))
|
|
66
|
+
return;
|
|
67
|
+
start = end + 1;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function parseFrame(line) {
|
|
73
|
+
const raw = JSON.parse(line);
|
|
74
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
75
|
+
throw new Error("control wire frame must be a JSON object");
|
|
76
|
+
}
|
|
77
|
+
return raw;
|
|
78
|
+
}
|
|
79
|
+
/** Control is unreachable/not answering → TF_JOURNAL_UNAVAILABLE (fail closed). */
|
|
80
|
+
function controlUnavailable(message) {
|
|
81
|
+
return new ControlError("TF_JOURNAL_UNAVAILABLE", message, { recoveryAction: "refresh", sideEffects: "none" });
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Start listening on a Unix socket. The socket file is chmod'ed to 0o600
|
|
85
|
+
* immediately after bind (plan §4.1). Listen failure (e.g. a live foreign
|
|
86
|
+
* socket already bound) fails closed with TF_BOOTSTRAP_FAILED — the caller
|
|
87
|
+
* owns the singleton lock and must release it.
|
|
88
|
+
*/
|
|
89
|
+
export function startUdsServer(options) {
|
|
90
|
+
frameLimit(options.maxFrameBytes);
|
|
91
|
+
const sockets = new Set();
|
|
92
|
+
const server = net.createServer((socket) => {
|
|
93
|
+
sockets.add(socket);
|
|
94
|
+
socket.on("close", () => sockets.delete(socket));
|
|
95
|
+
handleServerConnection(socket, options);
|
|
96
|
+
});
|
|
97
|
+
return new Promise((resolve, reject) => {
|
|
98
|
+
const onError = (error) => {
|
|
99
|
+
server.removeListener("listening", onListening);
|
|
100
|
+
reject(bootstrapFailed(`cannot listen on control endpoint ${options.endpointPath}: ${error.message}`));
|
|
101
|
+
};
|
|
102
|
+
const onListening = () => {
|
|
103
|
+
server.removeListener("error", onError);
|
|
104
|
+
try {
|
|
105
|
+
fs.chmodSync(options.endpointPath, 0o600);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
server.close();
|
|
109
|
+
reject(bootstrapFailed(`cannot set 0o600 on control endpoint ${options.endpointPath}: ${error instanceof Error ? error.message : String(error)}`));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// Post-listen server errors (EMFILE etc.) must not crash the winner.
|
|
113
|
+
server.on("error", () => { });
|
|
114
|
+
resolve({
|
|
115
|
+
endpointPath: options.endpointPath,
|
|
116
|
+
close: () => new Promise((closeResolve) => {
|
|
117
|
+
for (const socket of sockets)
|
|
118
|
+
socket.destroy();
|
|
119
|
+
server.close(() => closeResolve());
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
server.once("error", onError);
|
|
124
|
+
server.once("listening", onListening);
|
|
125
|
+
server.listen(options.endpointPath);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
function handleServerConnection(socket, options) {
|
|
129
|
+
// Per-connection hello gate (P4): the first frame must be a hello.
|
|
130
|
+
const gate = createHelloGate(options.serverHello, { requiredFeatures: options.requiredFeatures });
|
|
131
|
+
let greeted = false;
|
|
132
|
+
let inFlight = 0;
|
|
133
|
+
const maxFrameBytes = frameLimit(options.maxFrameBytes);
|
|
134
|
+
const reader = frameReader(maxFrameBytes);
|
|
135
|
+
let destroyed = false;
|
|
136
|
+
let clientHello;
|
|
137
|
+
const connection = Object.freeze({ token: Object.freeze({}), get closed() { return destroyed; }, get hello() { return clientHello; } });
|
|
138
|
+
const helloTimer = setTimeout(() => {
|
|
139
|
+
destroyed = true;
|
|
140
|
+
reader.clear();
|
|
141
|
+
socket.destroy();
|
|
142
|
+
}, options.helloTimeoutMs ?? 5_000);
|
|
143
|
+
const send = (frame) => {
|
|
144
|
+
if (destroyed)
|
|
145
|
+
return;
|
|
146
|
+
socket.write(encodeFrame(frame, maxFrameBytes));
|
|
147
|
+
};
|
|
148
|
+
const failClosed = (frame) => {
|
|
149
|
+
try {
|
|
150
|
+
send(frame);
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
destroyed = true;
|
|
154
|
+
reader.clear();
|
|
155
|
+
socket.destroy();
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
socket.setEncoding("utf8");
|
|
159
|
+
socket.on("data", (chunk) => {
|
|
160
|
+
if (destroyed)
|
|
161
|
+
return;
|
|
162
|
+
try {
|
|
163
|
+
reader.push(chunk, (line) => {
|
|
164
|
+
const raw = parseFrame(line);
|
|
165
|
+
// Synchronous negotiation completes before a pipelined frame is read.
|
|
166
|
+
void handleFrame(raw).catch(() => {
|
|
167
|
+
destroyed = true;
|
|
168
|
+
reader.clear();
|
|
169
|
+
socket.destroy();
|
|
170
|
+
});
|
|
171
|
+
return !destroyed;
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
try {
|
|
176
|
+
failClosed({ type: greeted ? "rpc-result" : "hello-ack", ...(greeted ? { id: 0 } : {}), ok: false, error: errorToEnvelope(error) });
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// Even encoding a rejection must remain local to the offending socket.
|
|
180
|
+
socket.destroy();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
socket.on("close", () => {
|
|
185
|
+
clearTimeout(helloTimer);
|
|
186
|
+
destroyed = true;
|
|
187
|
+
try {
|
|
188
|
+
options.onDisconnect?.(connection);
|
|
189
|
+
}
|
|
190
|
+
catch { /* isolate trusted cleanup failure to this connection */ }
|
|
191
|
+
reader.clear();
|
|
192
|
+
});
|
|
193
|
+
socket.on("error", () => {
|
|
194
|
+
destroyed = true;
|
|
195
|
+
reader.clear();
|
|
196
|
+
socket.destroy();
|
|
197
|
+
});
|
|
198
|
+
const handleFrame = async (raw) => {
|
|
199
|
+
if (destroyed)
|
|
200
|
+
return;
|
|
201
|
+
try {
|
|
202
|
+
if (raw.type === "hello") {
|
|
203
|
+
if (greeted) {
|
|
204
|
+
failClosed({ type: "hello-ack", ok: false, error: errorToEnvelope(protocolError("duplicate hello on a control channel")) });
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const verdict = gate.hello(raw.hello);
|
|
208
|
+
if (!verdict.ok) {
|
|
209
|
+
failClosed({ type: "hello-ack", ok: false, error: verdict.error.toEnvelope() });
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const fencingEpoch = options.getFencingEpoch();
|
|
213
|
+
greeted = true;
|
|
214
|
+
clientHello = raw.hello;
|
|
215
|
+
clearTimeout(helloTimer);
|
|
216
|
+
send({
|
|
217
|
+
type: "hello-ack",
|
|
218
|
+
ok: true,
|
|
219
|
+
serverHello: gate.serverHello,
|
|
220
|
+
fencingEpoch,
|
|
221
|
+
});
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (raw.type === "rpc") {
|
|
225
|
+
if (!greeted) {
|
|
226
|
+
failClosed({
|
|
227
|
+
type: "rpc-result",
|
|
228
|
+
id: typeof raw.id === "number" ? raw.id : 0,
|
|
229
|
+
ok: false,
|
|
230
|
+
error: errorToEnvelope(protocolError("hello must precede any RPC on this control channel")),
|
|
231
|
+
});
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const id = raw.id;
|
|
235
|
+
if (!isWireCounter(id)) {
|
|
236
|
+
failClosed({ type: "rpc-result", id: 0, ok: false, error: errorToEnvelope(protocolError("rpc frame requires a non-negative safe integer id")) });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const method = typeof raw.method === "string" ? raw.method : "";
|
|
240
|
+
if (!method) {
|
|
241
|
+
failClosed({ type: "rpc-result", id, ok: false, error: errorToEnvelope(protocolError("rpc frame requires a method name")) });
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
// Preserve the legacy omitted-epoch default, not malformed values.
|
|
245
|
+
const fencingEpoch = raw.fencingEpoch === undefined ? 0 : raw.fencingEpoch;
|
|
246
|
+
if (!isWireCounter(fencingEpoch)) {
|
|
247
|
+
failClosed({ type: "rpc-result", id, ok: false, error: errorToEnvelope(protocolError("rpc frame requires a non-negative safe integer fencingEpoch")) });
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (inFlight >= 64) {
|
|
251
|
+
failClosed({ type: "rpc-result", id, ok: false, error: errorToEnvelope(protocolError("too many concurrent RPCs on one control channel")) });
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
inFlight++;
|
|
255
|
+
try {
|
|
256
|
+
const result = await options.handleRpc(method, raw.params, fencingEpoch, connection);
|
|
257
|
+
send({ type: "rpc-result", id, ok: true, result });
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
send({ type: "rpc-result", id, ok: false, error: errorToEnvelope(error) });
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
inFlight--;
|
|
264
|
+
}
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
failClosed({
|
|
268
|
+
type: greeted ? "rpc-result" : "hello-ack",
|
|
269
|
+
...(greeted ? { id: 0 } : {}),
|
|
270
|
+
ok: false,
|
|
271
|
+
error: errorToEnvelope(protocolError(`unknown control wire frame type ${JSON.stringify(raw.type)}`)),
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
// Catch synchronous negotiation failures before the data loop can
|
|
276
|
+
// dispatch another pipelined frame on this failed connection.
|
|
277
|
+
failClosed({
|
|
278
|
+
type: greeted ? "rpc-result" : "hello-ack",
|
|
279
|
+
...(greeted ? { id: typeof raw.id === "number" ? raw.id : 0 } : {}),
|
|
280
|
+
ok: false,
|
|
281
|
+
error: errorToEnvelope(error),
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Connect to the winner's Unix socket, perform the online hello, and return a
|
|
288
|
+
* client bound to the winner's fencing epoch. A protocol/schema/feature
|
|
289
|
+
* rejection on the wire rejects with the corresponding ControlError
|
|
290
|
+
* (e.g. TF_PROTOCOL_INCOMPATIBLE); an unreachable endpoint fails closed with
|
|
291
|
+
* TF_JOURNAL_UNAVAILABLE.
|
|
292
|
+
*/
|
|
293
|
+
export function connectUdsClient(options) {
|
|
294
|
+
const connectTimeoutMs = options.connectTimeoutMs ?? 5_000;
|
|
295
|
+
const rpcTimeoutMs = options.rpcTimeoutMs ?? 10_000;
|
|
296
|
+
const maxFrameBytes = frameLimit(options.maxFrameBytes);
|
|
297
|
+
return new Promise((resolve, reject) => {
|
|
298
|
+
const socket = net.connect(options.endpointPath);
|
|
299
|
+
const reader = frameReader(maxFrameBytes);
|
|
300
|
+
let settled = false;
|
|
301
|
+
let closed = false;
|
|
302
|
+
let nextId = 1;
|
|
303
|
+
let wireEpoch = 0;
|
|
304
|
+
let wireServerHello;
|
|
305
|
+
const pending = new Map();
|
|
306
|
+
const rejectPending = (error) => {
|
|
307
|
+
for (const [, entry] of pending)
|
|
308
|
+
entry.reject(error);
|
|
309
|
+
pending.clear();
|
|
310
|
+
};
|
|
311
|
+
const failClosed = (error) => {
|
|
312
|
+
closed = true;
|
|
313
|
+
reader.clear();
|
|
314
|
+
clearTimeout(timer);
|
|
315
|
+
if (!settled) {
|
|
316
|
+
settled = true;
|
|
317
|
+
reject(error);
|
|
318
|
+
}
|
|
319
|
+
rejectPending(error);
|
|
320
|
+
socket.destroy();
|
|
321
|
+
};
|
|
322
|
+
const timer = setTimeout(() => {
|
|
323
|
+
if (settled)
|
|
324
|
+
return;
|
|
325
|
+
settled = true;
|
|
326
|
+
rejectPending(controlUnavailable(`control endpoint ${options.endpointPath} did not answer hello within ${connectTimeoutMs}ms`));
|
|
327
|
+
socket.destroy();
|
|
328
|
+
reject(controlUnavailable(`control endpoint ${options.endpointPath} did not answer hello within ${connectTimeoutMs}ms`));
|
|
329
|
+
}, connectTimeoutMs);
|
|
330
|
+
socket.on("connect", () => {
|
|
331
|
+
try {
|
|
332
|
+
socket.write(encodeFrame({ type: "hello", hello: options.clientHello }, maxFrameBytes));
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
failClosed(controlUnavailable(`control hello could not be sent: ${error instanceof Error ? error.message : String(error)}`));
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
socket.on("error", (error) => {
|
|
339
|
+
if (!settled) {
|
|
340
|
+
settled = true;
|
|
341
|
+
clearTimeout(timer);
|
|
342
|
+
reject(controlUnavailable(`cannot connect to control endpoint ${options.endpointPath}: ${error.message}`));
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
rejectPending(controlUnavailable(`control endpoint ${options.endpointPath} closed: ${error.message}`));
|
|
346
|
+
});
|
|
347
|
+
socket.setEncoding("utf8");
|
|
348
|
+
socket.on("data", (chunk) => {
|
|
349
|
+
if (closed)
|
|
350
|
+
return;
|
|
351
|
+
try {
|
|
352
|
+
reader.push(chunk, (line) => {
|
|
353
|
+
const raw = parseFrame(line);
|
|
354
|
+
if (raw.type !== "hello-ack" && raw.type !== "rpc-result")
|
|
355
|
+
throw new Error("unexpected frame type");
|
|
356
|
+
if (typeof raw.ok !== "boolean" || (raw.ok === false && !Value.Check(ErrorEnvelopeSchema, raw.error))) {
|
|
357
|
+
throw new Error("failure reply must match ErrorEnvelope and have a boolean ok");
|
|
358
|
+
}
|
|
359
|
+
// Reject opposite-branch members without forbidding future metadata.
|
|
360
|
+
// Void successful RPCs may omit result, and null is a valid result.
|
|
361
|
+
if ((raw.ok && Object.hasOwn(raw, "error")) || (!raw.ok && (raw.type === "hello-ack"
|
|
362
|
+
? Object.hasOwn(raw, "serverHello") || Object.hasOwn(raw, "fencingEpoch")
|
|
363
|
+
: Object.hasOwn(raw, "result"))))
|
|
364
|
+
throw new Error("reply contains contradictory success and failure members");
|
|
365
|
+
if (raw.type === "hello-ack") {
|
|
366
|
+
if (settled)
|
|
367
|
+
throw new Error("duplicate hello-ack");
|
|
368
|
+
if (raw.ok === false) {
|
|
369
|
+
failClosed(errorFromEnvelope(raw.error));
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
if (!isWireCounter(raw.fencingEpoch) || !Value.Check(NegotiationHandshakeSchema, raw.serverHello)) {
|
|
373
|
+
throw new Error("malformed hello-ack");
|
|
374
|
+
}
|
|
375
|
+
settled = true;
|
|
376
|
+
clearTimeout(timer);
|
|
377
|
+
wireEpoch = raw.fencingEpoch;
|
|
378
|
+
wireServerHello = raw.serverHello;
|
|
379
|
+
resolve({
|
|
380
|
+
endpointPath: options.endpointPath,
|
|
381
|
+
get fencingEpoch() { return wireEpoch; },
|
|
382
|
+
get serverHello() { return wireServerHello; },
|
|
383
|
+
rpc: (method, params, fencingEpoch) => rpc(socket, pending, () => closed, () => wireEpoch, () => nextId++, rpcTimeoutMs, maxFrameBytes, method, params, fencingEpoch),
|
|
384
|
+
close: () => failClosed(controlUnavailable(`control client for ${options.endpointPath} is closed`)),
|
|
385
|
+
});
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
if (!settled || !isWireCounter(raw.id))
|
|
389
|
+
throw new Error("malformed rpc-result");
|
|
390
|
+
const id = raw.id;
|
|
391
|
+
const entry = pending.get(id);
|
|
392
|
+
if (entry) {
|
|
393
|
+
pending.delete(id);
|
|
394
|
+
if (raw.ok === true)
|
|
395
|
+
entry.resolve(raw.result);
|
|
396
|
+
else
|
|
397
|
+
entry.reject(errorFromEnvelope(raw.error));
|
|
398
|
+
}
|
|
399
|
+
return true;
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
catch (error) {
|
|
403
|
+
failClosed(controlUnavailable(`control endpoint ${options.endpointPath} sent a malformed frame: ${error instanceof Error ? error.message : String(error)}`));
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
socket.on("close", () => {
|
|
407
|
+
closed = true;
|
|
408
|
+
reader.clear();
|
|
409
|
+
if (!settled) {
|
|
410
|
+
settled = true;
|
|
411
|
+
clearTimeout(timer);
|
|
412
|
+
reject(controlUnavailable(`control endpoint ${options.endpointPath} closed before hello`));
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
rejectPending(controlUnavailable(`control endpoint ${options.endpointPath} closed`));
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
function rpc(socket, pending, isClosed, getEpoch, nextId, rpcTimeoutMs, maxFrameBytes, method, params, fencingEpoch) {
|
|
420
|
+
if (isClosed()) {
|
|
421
|
+
return Promise.reject(controlUnavailable(`control client for ${socket.remoteAddress ?? "unix"} is closed`));
|
|
422
|
+
}
|
|
423
|
+
const id = nextId();
|
|
424
|
+
return new Promise((resolve, reject) => {
|
|
425
|
+
const rpcTimer = setTimeout(() => {
|
|
426
|
+
pending.delete(id);
|
|
427
|
+
reject(controlUnavailable(`control RPC ${JSON.stringify(method)} timed out after ${rpcTimeoutMs}ms`));
|
|
428
|
+
}, rpcTimeoutMs);
|
|
429
|
+
pending.set(id, {
|
|
430
|
+
resolve: (value) => {
|
|
431
|
+
clearTimeout(rpcTimer);
|
|
432
|
+
resolve(value);
|
|
433
|
+
},
|
|
434
|
+
reject: (error) => {
|
|
435
|
+
clearTimeout(rpcTimer);
|
|
436
|
+
reject(error);
|
|
437
|
+
},
|
|
438
|
+
});
|
|
439
|
+
const frame = {
|
|
440
|
+
type: "rpc",
|
|
441
|
+
id,
|
|
442
|
+
method,
|
|
443
|
+
...(params !== undefined ? { params } : {}),
|
|
444
|
+
fencingEpoch: fencingEpoch ?? getEpoch(),
|
|
445
|
+
};
|
|
446
|
+
try {
|
|
447
|
+
socket.write(encodeFrame(frame, maxFrameBytes));
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
pending.delete(id);
|
|
451
|
+
clearTimeout(rpcTimer);
|
|
452
|
+
reject(controlUnavailable(`control RPC ${JSON.stringify(method)} could not be sent: ${error instanceof Error ? error.message : String(error)}`));
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
//# sourceMappingURL=uds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uds.js","sourceRoot":"","sources":["../../../taskflow-control/src/uds.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Static shell only. All owner-provided content is inserted with textContent. */
|
|
2
|
+
export declare const CONSOLE_HTML = "<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Taskflow \u00B7 Operator console</title><link rel=\"stylesheet\" href=\"/style.css\"><script src=\"/app.js\" defer></script></head>\n<body><header><div><strong>Taskflow</strong><span class=\"subtitle\">Operator console</span></div><span id=\"connection\" role=\"status\">Disconnected</span></header>\n<section id=\"login\" class=\"login\"><h1>Connect to your local control service</h1><p>Enter the one-use session token provided by your trusted launcher. The token stays on this machine.</p><label for=\"token\">Launcher session token</label><input id=\"token\" type=\"password\" autocomplete=\"off\" spellcheck=\"false\"><button id=\"connect\">Connect</button><p id=\"login-error\" role=\"alert\"></p></section>\n<div id=\"console\" hidden><aside><div class=\"section-heading\"><h2>Projects</h2><button id=\"refresh-projects\" class=\"quiet\">Refresh</button></div><div id=\"projects\"></div><button id=\"logout\" class=\"quiet\">End browser session</button></aside>\n<main><div class=\"section-heading\"><div><h1 id=\"project-title\">Select a project</h1><p id=\"project-context\" class=\"mono muted\"></p></div><button id=\"refresh\" class=\"quiet\">Refresh view</button></div>\n<p id=\"notice\" role=\"status\" aria-live=\"polite\"></p><nav aria-label=\"Project views\"><button data-tab=\"runs\" class=\"selected\">Runs</button><button data-tab=\"approvals\">Approvals</button><button data-tab=\"evidence\">Receipt & evidence</button></nav>\n<section id=\"runs-panel\"><h2>Runs</h2><p class=\"muted\">Status and stage are reported by the project ledger.</p><div id=\"runs\"></div><pre id=\"run-detail\" hidden></pre></section>\n<section id=\"approvals-panel\" hidden><h2>Approval inbox</h2><p id=\"edit-capability\" class=\"muted\"></p><div id=\"approvals\"></div></section>\n<section id=\"evidence-panel\" hidden><h2>Receipt & evidence</h2><label for=\"run-choice\">Run</label><select id=\"run-choice\"></select><div class=\"actions\"><button id=\"receipt\">View receipt</button><button id=\"why-stale\" class=\"quiet\">Why stale</button><input id=\"effect-id\" placeholder=\"Effect ID\" aria-label=\"Effect ID\"><input id=\"phase-id\" placeholder=\"Phase ID (optional)\" aria-label=\"Phase ID\"><button id=\"why-effect\" class=\"quiet\">Why effect</button></div><p class=\"muted\">Receipts are issued by control after final settlement. Missing evidence is never treated as verified.</p><pre id=\"evidence-output\">Choose a run to inspect its committed evidence.</pre></section>\n<details><summary>Control connection details</summary><pre id=\"control-status\"></pre></details></main></div>\n<footer>Local operator session \u00B7 Live authorization remains with ControlHost</footer></body></html>";
|
|
3
|
+
export declare const CONSOLE_CSS = ":root{color-scheme:light;--ink:#192a30;--muted:#67777c;--line:#dce4e6;--accent:#146a60;--canvas:#f6f8f8}*{box-sizing:border-box}body{margin:0;background:var(--canvas);color:var(--ink);font:14px/1.55 -apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif}header{height:68px;padding:0 30px;background:white;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between}header strong{font-size:20px;letter-spacing:-.6px}.subtitle{margin-left:18px;color:var(--muted)}#connection{font-size:12px;border:1px solid var(--line);padding:4px 10px;border-radius:20px}.login{max-width:610px;margin:70px auto;padding:32px;background:#fff;border:1px solid var(--line);border-radius:12px}h1{font-size:23px;letter-spacing:-.5px;margin:0 0 8px}h2{font-size:16px;margin:0}p{margin:8px 0 18px}.muted{color:var(--muted)}.mono,pre{font-family:ui-monospace,SFMono-Regular,monospace}label{display:block;margin:14px 0 6px;font-weight:600}input,select,textarea{font:inherit;padding:8px 10px;background:white;border:1px solid #b8c8cc;border-radius:6px;color:var(--ink)}input:focus,select:focus,textarea:focus{outline:2px solid #8ac5bb;outline-offset:2px}#token{width:100%;margin-bottom:14px}button{font:inherit;font-weight:600;cursor:pointer;background:var(--accent);color:white;border:1px solid var(--accent);border-radius:6px;padding:7px 13px}button:hover{filter:brightness(.95)}button:disabled{cursor:not-allowed;opacity:.48}.quiet{background:white;color:var(--ink);border-color:var(--line)}#console{display:grid;grid-template-columns:246px minmax(0,1fr);min-height:calc(100vh - 110px)}#console[hidden]{display:none}aside{padding:25px 18px;border-right:1px solid var(--line);background:#eef3f2}main{padding:30px 36px;max-width:1400px;width:100%}.section-heading{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:20px}.section-heading p{margin-bottom:0;font-size:11px;overflow-wrap:anywhere}.project{display:block;width:100%;text-align:left;margin:8px 0;padding:12px;background:transparent;border:1px solid transparent;color:var(--ink);overflow-wrap:anywhere}.project.selected{background:white;border-color:#c5d7d2;box-shadow:0 1px 3px #163c3010}.project small{display:block;color:var(--muted);font-weight:400;margin-top:5px}#logout{margin-top:28px;width:100%}nav{display:flex;gap:6px;border-bottom:1px solid var(--line);margin:20px 0 25px;padding-bottom:10px}nav button{background:transparent;color:var(--muted);border-color:transparent}nav button.selected{background:#e4efeb;color:#155f53}#notice{min-height:22px;margin:0;color:var(--muted)}#notice.error,#login-error{color:#9c3131}.card{background:white;border:1px solid var(--line);border-radius:9px;padding:17px;margin:12px 0}.card h3{margin:0 0 6px;font-size:14px;overflow-wrap:anywhere}.row{display:flex;align-items:center;justify-content:space-between;gap:16px}.tag{display:inline-block;background:#edf1f2;color:#385158;font-size:12px;border-radius:4px;padding:2px 7px;margin-right:6px}.actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:15px}.actions input{width:180px}.empty{padding:28px;border:1px dashed #c6d3d5;border-radius:8px;color:var(--muted);background:#fcfdfd}pre{white-space:pre-wrap;overflow-wrap:anywhere;padding:18px;border:1px solid var(--line);border-radius:8px;background:#fff;font-size:12px}textarea{display:block;width:100%;min-height:70px;margin:12px 0}details{margin-top:30px;color:var(--muted)}summary{cursor:pointer}footer{padding:10px 30px;font-size:11px;color:var(--muted);border-top:1px solid var(--line)}[hidden]{display:none!important}@media(max-width:800px){#console{grid-template-columns:1fr}aside{border-right:0;border-bottom:1px solid var(--line)}main{padding:24px 18px}.subtitle{display:none}.row{align-items:flex-start}.section-heading{align-items:flex-start}.login{margin:30px 15px}header{padding:0 18px}}";
|
|
4
|
+
export declare const CONSOLE_JS: string;
|
|
5
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../../taskflow-control/src/web-console/view.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,eAAO,MAAM,YAAY,iyFAW2E,CAAC;AAErG,eAAO,MAAM,WAAW,ixHAA+wH,CAAC;AAExyH,eAAO,MAAM,UAAU,QA0GtB,CAAC"}
|