xiaotime 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/background.d.ts +47 -0
- package/dist/background.d.ts.map +1 -0
- package/dist/background.js +110 -0
- package/dist/background.js.map +1 -0
- package/dist/ink/runSessionInk.d.ts.map +1 -1
- package/dist/ink/runSessionInk.js +16 -2
- package/dist/ink/runSessionInk.js.map +1 -1
- package/dist/mcp.d.ts +94 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +282 -0
- package/dist/mcp.js.map +1 -0
- package/dist/settings.d.ts +9 -1
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +46 -4
- package/dist/settings.js.map +1 -1
- package/dist/skills.d.ts +14 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +112 -0
- package/dist/skills.js.map +1 -0
- package/dist/todos.d.ts +26 -0
- package/dist/todos.d.ts.map +1 -0
- package/dist/todos.js +55 -0
- package/dist/todos.js.map +1 -0
- package/dist/tools.d.ts +26 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +496 -1
- package/dist/tools.js.map +1 -1
- package/dist/ws.d.ts.map +1 -1
- package/dist/ws.js +23 -2
- package/dist/ws.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background / long-running command registry —
|
|
3
|
+
* SPRINT-CLI-CAPABILITY-PARITY-1 (#14608).
|
|
4
|
+
*
|
|
5
|
+
* The built-in `shell_command` blocks for up to 60s and returns once.
|
|
6
|
+
* A coding agent needs to kick off a long job (a build, a dev server, a
|
|
7
|
+
* test watcher) WITHOUT blocking the turn, then poll its output and kill
|
|
8
|
+
* it — the Claude-Code `run_in_background` / `BashOutput` / `KillShell`
|
|
9
|
+
* shape. This registry owns those child processes for the session:
|
|
10
|
+
* spawn detached from the turn, buffer stdout+stderr with a cap, expose
|
|
11
|
+
* an incremental read cursor, and kill on demand or at session close.
|
|
12
|
+
*/
|
|
13
|
+
import { type ChildProcess } from "child_process";
|
|
14
|
+
export type BgStatus = "running" | "exited" | "killed";
|
|
15
|
+
export interface BgProc {
|
|
16
|
+
id: string;
|
|
17
|
+
command: string;
|
|
18
|
+
child: ChildProcess;
|
|
19
|
+
output: string;
|
|
20
|
+
cursor: number;
|
|
21
|
+
status: BgStatus;
|
|
22
|
+
exitCode: number | null;
|
|
23
|
+
startedAt: number;
|
|
24
|
+
}
|
|
25
|
+
export declare class BackgroundRegistry {
|
|
26
|
+
private procs;
|
|
27
|
+
private seq;
|
|
28
|
+
start(command: string, cwd: string): BgProc;
|
|
29
|
+
get(id: string): BgProc | undefined;
|
|
30
|
+
/** Read output produced since the last read; advances the cursor. */
|
|
31
|
+
readNew(id: string): {
|
|
32
|
+
text: string;
|
|
33
|
+
status: BgStatus;
|
|
34
|
+
exitCode: number | null;
|
|
35
|
+
} | null;
|
|
36
|
+
kill(id: string): boolean;
|
|
37
|
+
list(): Array<{
|
|
38
|
+
id: string;
|
|
39
|
+
command: string;
|
|
40
|
+
status: BgStatus;
|
|
41
|
+
exitCode: number | null;
|
|
42
|
+
}>;
|
|
43
|
+
killAll(): void;
|
|
44
|
+
}
|
|
45
|
+
/** Session-global registry (one per CLI process). */
|
|
46
|
+
export declare const backgroundRegistry: BackgroundRegistry;
|
|
47
|
+
//# sourceMappingURL=background.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background.d.ts","sourceRoot":"","sources":["../src/background.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,GAAG,CAAK;IAEhB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAyC3C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInC,qEAAqE;IACrE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI;IAQvF,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAczB,IAAI,IAAI,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IASzF,OAAO,IAAI,IAAI;CAUhB;AAED,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,oBAA2B,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background / long-running command registry —
|
|
3
|
+
* SPRINT-CLI-CAPABILITY-PARITY-1 (#14608).
|
|
4
|
+
*
|
|
5
|
+
* The built-in `shell_command` blocks for up to 60s and returns once.
|
|
6
|
+
* A coding agent needs to kick off a long job (a build, a dev server, a
|
|
7
|
+
* test watcher) WITHOUT blocking the turn, then poll its output and kill
|
|
8
|
+
* it — the Claude-Code `run_in_background` / `BashOutput` / `KillShell`
|
|
9
|
+
* shape. This registry owns those child processes for the session:
|
|
10
|
+
* spawn detached from the turn, buffer stdout+stderr with a cap, expose
|
|
11
|
+
* an incremental read cursor, and kill on demand or at session close.
|
|
12
|
+
*/
|
|
13
|
+
import { spawn } from "child_process";
|
|
14
|
+
/** Per-process output cap — keep the tail so a chatty job can't grow unbounded. */
|
|
15
|
+
const MAX_OUTPUT = 200_000;
|
|
16
|
+
export class BackgroundRegistry {
|
|
17
|
+
procs = new Map();
|
|
18
|
+
seq = 0;
|
|
19
|
+
start(command, cwd) {
|
|
20
|
+
const id = `bg_${++this.seq}`;
|
|
21
|
+
const child = spawn(command, {
|
|
22
|
+
shell: true,
|
|
23
|
+
cwd,
|
|
24
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
25
|
+
});
|
|
26
|
+
const proc = {
|
|
27
|
+
id,
|
|
28
|
+
command,
|
|
29
|
+
child,
|
|
30
|
+
output: "",
|
|
31
|
+
cursor: 0,
|
|
32
|
+
status: "running",
|
|
33
|
+
exitCode: null,
|
|
34
|
+
startedAt: Date.now(),
|
|
35
|
+
};
|
|
36
|
+
const append = (d) => {
|
|
37
|
+
proc.output += d.toString();
|
|
38
|
+
if (proc.output.length > MAX_OUTPUT) {
|
|
39
|
+
// Keep the tail; move the read cursor with the drop so
|
|
40
|
+
// background_output never reports negative-length slices.
|
|
41
|
+
const dropped = proc.output.length - MAX_OUTPUT;
|
|
42
|
+
proc.output = proc.output.slice(dropped);
|
|
43
|
+
proc.cursor = Math.max(0, proc.cursor - dropped);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
child.stdout?.on("data", append);
|
|
47
|
+
child.stderr?.on("data", append);
|
|
48
|
+
child.on("exit", (code) => {
|
|
49
|
+
if (proc.status !== "killed")
|
|
50
|
+
proc.status = "exited";
|
|
51
|
+
proc.exitCode = code;
|
|
52
|
+
});
|
|
53
|
+
child.on("error", (e) => {
|
|
54
|
+
append(Buffer.from(`\n[spawn error] ${e.message}\n`));
|
|
55
|
+
if (proc.status !== "killed")
|
|
56
|
+
proc.status = "exited";
|
|
57
|
+
});
|
|
58
|
+
this.procs.set(id, proc);
|
|
59
|
+
return proc;
|
|
60
|
+
}
|
|
61
|
+
get(id) {
|
|
62
|
+
return this.procs.get(id);
|
|
63
|
+
}
|
|
64
|
+
/** Read output produced since the last read; advances the cursor. */
|
|
65
|
+
readNew(id) {
|
|
66
|
+
const p = this.procs.get(id);
|
|
67
|
+
if (!p)
|
|
68
|
+
return null;
|
|
69
|
+
const text = p.output.slice(p.cursor);
|
|
70
|
+
p.cursor = p.output.length;
|
|
71
|
+
return { text, status: p.status, exitCode: p.exitCode };
|
|
72
|
+
}
|
|
73
|
+
kill(id) {
|
|
74
|
+
const p = this.procs.get(id);
|
|
75
|
+
if (!p)
|
|
76
|
+
return false;
|
|
77
|
+
if (p.status === "running") {
|
|
78
|
+
p.status = "killed";
|
|
79
|
+
try {
|
|
80
|
+
p.child.kill("SIGTERM");
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
/* already gone */
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
list() {
|
|
89
|
+
return [...this.procs.values()].map((p) => ({
|
|
90
|
+
id: p.id,
|
|
91
|
+
command: p.command,
|
|
92
|
+
status: p.status,
|
|
93
|
+
exitCode: p.exitCode,
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
killAll() {
|
|
97
|
+
for (const p of this.procs.values()) {
|
|
98
|
+
try {
|
|
99
|
+
p.child.kill("SIGTERM");
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
/* already gone */
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
this.procs.clear();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Session-global registry (one per CLI process). */
|
|
109
|
+
export const backgroundRegistry = new BackgroundRegistry();
|
|
110
|
+
//# sourceMappingURL=background.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background.js","sourceRoot":"","sources":["../src/background.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runSessionInk.d.ts","sourceRoot":"","sources":["../../src/ink/runSessionInk.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runSessionInk.d.ts","sourceRoot":"","sources":["../../src/ink/runSessionInk.ts"],"names":[],"mappings":"AAyBA,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsLpE"}
|
|
@@ -20,8 +20,15 @@ import { execToolInk } from "./execToolInk.js";
|
|
|
20
20
|
import { connectProjectContextField } from "../projectContext.js";
|
|
21
21
|
import { startInkUI } from "./App.js";
|
|
22
22
|
import * as store from "./store.js";
|
|
23
|
+
import { McpManager, isMcpTool } from "../mcp.js";
|
|
24
|
+
import { backgroundRegistry } from "../background.js";
|
|
23
25
|
export async function runSessionInk(sessionId) {
|
|
24
26
|
const wsUrl = `${WS_URL}/terminal/sessions/${sessionId}/stream`;
|
|
27
|
+
// Start MCP servers (if configured) before connecting so their tools
|
|
28
|
+
// ride the connect manifest — identical to ws.ts::runSession (#14608).
|
|
29
|
+
const mcp = new McpManager();
|
|
30
|
+
const { tools: mcpTools, errors: mcpErrors } = await mcp.startAll();
|
|
31
|
+
const allTools = [...TOOL_MANIFEST, ...mcpTools];
|
|
25
32
|
return new Promise((resolve, reject) => {
|
|
26
33
|
const ws = new WebSocket(wsUrl);
|
|
27
34
|
let connected = false;
|
|
@@ -46,6 +53,8 @@ export async function runSessionInk(sessionId) {
|
|
|
46
53
|
settled = true;
|
|
47
54
|
if (pingInterval)
|
|
48
55
|
clearInterval(pingInterval);
|
|
56
|
+
mcp.stopAll();
|
|
57
|
+
backgroundRegistry.killAll();
|
|
49
58
|
try {
|
|
50
59
|
ink.unmount();
|
|
51
60
|
}
|
|
@@ -75,7 +84,9 @@ export async function runSessionInk(sessionId) {
|
|
|
75
84
|
while (toolQueue.length > 0) {
|
|
76
85
|
const tc = toolQueue.shift();
|
|
77
86
|
store.flushStreaming();
|
|
78
|
-
const result =
|
|
87
|
+
const result = isMcpTool(tc.name)
|
|
88
|
+
? await mcp.call(tc.name, tc.input, tc.tool_use_id)
|
|
89
|
+
: await execToolInk(tc);
|
|
79
90
|
try {
|
|
80
91
|
await postToolResults(sessionId, [
|
|
81
92
|
{ tool_use_id: result.tool_use_id, content: result.content, is_error: result.is_error },
|
|
@@ -97,7 +108,7 @@ export async function runSessionInk(sessionId) {
|
|
|
97
108
|
ws.send(JSON.stringify({
|
|
98
109
|
type: "connect",
|
|
99
110
|
cwd: process.cwd(),
|
|
100
|
-
tools:
|
|
111
|
+
tools: allTools,
|
|
101
112
|
...connectProjectContextField(process.cwd()),
|
|
102
113
|
}));
|
|
103
114
|
});
|
|
@@ -113,6 +124,9 @@ export async function runSessionInk(sessionId) {
|
|
|
113
124
|
store.setBotName(name);
|
|
114
125
|
const shortId = String(msg.session_id ?? sessionId).slice(0, 4);
|
|
115
126
|
store.setSessionLabel(`${(name ?? "session").toLowerCase()} · ${shortId}`);
|
|
127
|
+
for (const err of mcpErrors) {
|
|
128
|
+
store.pushError(`MCP server skipped — ${err}`);
|
|
129
|
+
}
|
|
116
130
|
break;
|
|
117
131
|
}
|
|
118
132
|
case "text_delta":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runSessionInk.js","sourceRoot":"","sources":["../../src/ink/runSessionInk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"runSessionInk.js","sourceRoot":"","sources":["../../src/ink/runSessionInk.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP (Model Context Protocol) client — SPRINT-CLI-CAPABILITY-PARITY-1
|
|
3
|
+
* (#14608).
|
|
4
|
+
*
|
|
5
|
+
* Lets the terminal agent reach external tool servers (the KB/estate,
|
|
6
|
+
* a browser driver, platform connectors) the same way Claude Code
|
|
7
|
+
* does: spawn the servers declared in `~/.xiaotime/mcp.json`, discover
|
|
8
|
+
* their tools over stdio JSON-RPC, and expose them to the LLM as extra
|
|
9
|
+
* entries in the connect manifest. A tool_use for one of these names is
|
|
10
|
+
* routed to its server's `tools/call` instead of the local executeTool
|
|
11
|
+
* switch.
|
|
12
|
+
*
|
|
13
|
+
* Transport: newline-delimited JSON-RPC 2.0 over the child's stdio
|
|
14
|
+
* (the MCP stdio contract — one JSON message per line, no embedded
|
|
15
|
+
* newlines).
|
|
16
|
+
*
|
|
17
|
+
* Tool naming: `mcp__<server>__<tool>` so two servers can expose a tool
|
|
18
|
+
* of the same bare name without colliding, and the dispatcher can parse
|
|
19
|
+
* the server back out of the name.
|
|
20
|
+
*
|
|
21
|
+
* Config shape (Claude-Code-compatible):
|
|
22
|
+
* { "mcpServers": { "<name>": { "command": "...", "args": [...],
|
|
23
|
+
* "env": { ... } } } }
|
|
24
|
+
*
|
|
25
|
+
* Governance: MCP tools ride the SAME tool_call → tool_result round-trip
|
|
26
|
+
* as the built-in tools, so they surface in the transcript. Per-tool
|
|
27
|
+
* approval on outbound MCP calls lands with the #14605 room; today the
|
|
28
|
+
* mediation is the config file itself (only servers the user declared
|
|
29
|
+
* are spawned).
|
|
30
|
+
*/
|
|
31
|
+
import type { ToolManifestEntry, ToolResult } from "./tools.js";
|
|
32
|
+
export interface McpServerConfig {
|
|
33
|
+
command: string;
|
|
34
|
+
args?: string[];
|
|
35
|
+
env?: Record<string, string>;
|
|
36
|
+
}
|
|
37
|
+
export interface McpConfig {
|
|
38
|
+
mcpServers: Record<string, McpServerConfig>;
|
|
39
|
+
}
|
|
40
|
+
export declare const MCP_TOOL_PREFIX = "mcp__";
|
|
41
|
+
export declare function mcpConfigPath(): string;
|
|
42
|
+
/**
|
|
43
|
+
* Read `~/.xiaotime/mcp.json`. Returns an empty server set for any
|
|
44
|
+
* failure (missing / unreadable / malformed) — a broken MCP config
|
|
45
|
+
* must never stop the CLI from starting (mirrors settings.ts's
|
|
46
|
+
* never-throw allowlist load).
|
|
47
|
+
*/
|
|
48
|
+
export declare function loadMcpConfig(): McpConfig;
|
|
49
|
+
export declare function isMcpTool(name: string): boolean;
|
|
50
|
+
/** Parse `mcp__<server>__<tool>` back into its parts (null if malformed). */
|
|
51
|
+
export declare function parseMcpToolName(name: string): {
|
|
52
|
+
server: string;
|
|
53
|
+
tool: string;
|
|
54
|
+
} | null;
|
|
55
|
+
/** One live connection to a spawned MCP server. */
|
|
56
|
+
export declare class McpConnection {
|
|
57
|
+
readonly name: string;
|
|
58
|
+
private cfg;
|
|
59
|
+
private child;
|
|
60
|
+
private buf;
|
|
61
|
+
private nextId;
|
|
62
|
+
private pending;
|
|
63
|
+
private closed;
|
|
64
|
+
tools: ToolManifestEntry[];
|
|
65
|
+
constructor(name: string, cfg: McpServerConfig);
|
|
66
|
+
start(timeoutMs?: number): Promise<void>;
|
|
67
|
+
callTool(tool: string, args: Record<string, unknown>, timeoutMs?: number): Promise<{
|
|
68
|
+
text: string;
|
|
69
|
+
isError: boolean;
|
|
70
|
+
}>;
|
|
71
|
+
stop(): void;
|
|
72
|
+
private _onData;
|
|
73
|
+
private _request;
|
|
74
|
+
private _notify;
|
|
75
|
+
private _fail;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Owns every live MCP connection for a session. Connects all configured
|
|
79
|
+
* servers concurrently, aggregates their tools into one manifest slice,
|
|
80
|
+
* and routes tool calls to the right server. A server that fails to
|
|
81
|
+
* start is skipped (reported in `errors`), never fatal.
|
|
82
|
+
*/
|
|
83
|
+
export declare class McpManager {
|
|
84
|
+
private conns;
|
|
85
|
+
startAll(cfg?: McpConfig): Promise<{
|
|
86
|
+
tools: ToolManifestEntry[];
|
|
87
|
+
errors: string[];
|
|
88
|
+
}>;
|
|
89
|
+
hasServers(): boolean;
|
|
90
|
+
serverNames(): string[];
|
|
91
|
+
call(name: string, input: Record<string, unknown>, tool_use_id: string): Promise<ToolResult>;
|
|
92
|
+
stopAll(): void;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;AAGD,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,SAAS,CAczC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GACX;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMzC;AAQD,mDAAmD;AACnD,qBAAa,aAAa;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,MAAM,CAAS;IACvB,KAAK,EAAE,iBAAiB,EAAE,CAAM;gBAEpB,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe;IAKxC,KAAK,CAAC,SAAS,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCvC,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,SAAS,GACjB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAc9C,IAAI,IAAI,IAAI;IAcZ,OAAO,CAAC,OAAO;IAwBf,OAAO,CAAC,QAAQ;IAsBhB,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,KAAK;CAQd;AAcD;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAoC;IAE3C,QAAQ,CACZ,GAAG,GAAE,SAA2B,GAC/B,OAAO,CAAC;QAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAoB5D,UAAU,IAAI,OAAO;IAIrB,WAAW,IAAI,MAAM,EAAE;IAIjB,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC;IAyBtB,OAAO,IAAI,IAAI;CAIhB"}
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP (Model Context Protocol) client — SPRINT-CLI-CAPABILITY-PARITY-1
|
|
3
|
+
* (#14608).
|
|
4
|
+
*
|
|
5
|
+
* Lets the terminal agent reach external tool servers (the KB/estate,
|
|
6
|
+
* a browser driver, platform connectors) the same way Claude Code
|
|
7
|
+
* does: spawn the servers declared in `~/.xiaotime/mcp.json`, discover
|
|
8
|
+
* their tools over stdio JSON-RPC, and expose them to the LLM as extra
|
|
9
|
+
* entries in the connect manifest. A tool_use for one of these names is
|
|
10
|
+
* routed to its server's `tools/call` instead of the local executeTool
|
|
11
|
+
* switch.
|
|
12
|
+
*
|
|
13
|
+
* Transport: newline-delimited JSON-RPC 2.0 over the child's stdio
|
|
14
|
+
* (the MCP stdio contract — one JSON message per line, no embedded
|
|
15
|
+
* newlines).
|
|
16
|
+
*
|
|
17
|
+
* Tool naming: `mcp__<server>__<tool>` so two servers can expose a tool
|
|
18
|
+
* of the same bare name without colliding, and the dispatcher can parse
|
|
19
|
+
* the server back out of the name.
|
|
20
|
+
*
|
|
21
|
+
* Config shape (Claude-Code-compatible):
|
|
22
|
+
* { "mcpServers": { "<name>": { "command": "...", "args": [...],
|
|
23
|
+
* "env": { ... } } } }
|
|
24
|
+
*
|
|
25
|
+
* Governance: MCP tools ride the SAME tool_call → tool_result round-trip
|
|
26
|
+
* as the built-in tools, so they surface in the transcript. Per-tool
|
|
27
|
+
* approval on outbound MCP calls lands with the #14605 room; today the
|
|
28
|
+
* mediation is the config file itself (only servers the user declared
|
|
29
|
+
* are spawned).
|
|
30
|
+
*/
|
|
31
|
+
import * as fs from "fs";
|
|
32
|
+
import * as os from "os";
|
|
33
|
+
import * as path from "path";
|
|
34
|
+
import { spawn } from "child_process";
|
|
35
|
+
const PROTOCOL_VERSION = "2024-11-05";
|
|
36
|
+
export const MCP_TOOL_PREFIX = "mcp__";
|
|
37
|
+
export function mcpConfigPath() {
|
|
38
|
+
return (process.env.XIAOTIME_MCP_CONFIG ??
|
|
39
|
+
path.join(os.homedir(), ".xiaotime", "mcp.json"));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Read `~/.xiaotime/mcp.json`. Returns an empty server set for any
|
|
43
|
+
* failure (missing / unreadable / malformed) — a broken MCP config
|
|
44
|
+
* must never stop the CLI from starting (mirrors settings.ts's
|
|
45
|
+
* never-throw allowlist load).
|
|
46
|
+
*/
|
|
47
|
+
export function loadMcpConfig() {
|
|
48
|
+
const p = mcpConfigPath();
|
|
49
|
+
if (!fs.existsSync(p))
|
|
50
|
+
return { mcpServers: {} };
|
|
51
|
+
try {
|
|
52
|
+
const parsed = JSON.parse(fs.readFileSync(p, "utf-8"));
|
|
53
|
+
const servers = parsed?.mcpServers;
|
|
54
|
+
if (!servers || typeof servers !== "object")
|
|
55
|
+
return { mcpServers: {} };
|
|
56
|
+
return { mcpServers: servers };
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
process.stderr.write(`[xiaotime] ~/.xiaotime/mcp.json unreadable: ${e.message}\n`);
|
|
60
|
+
return { mcpServers: {} };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export function isMcpTool(name) {
|
|
64
|
+
return name.startsWith(MCP_TOOL_PREFIX);
|
|
65
|
+
}
|
|
66
|
+
/** Parse `mcp__<server>__<tool>` back into its parts (null if malformed). */
|
|
67
|
+
export function parseMcpToolName(name) {
|
|
68
|
+
if (!isMcpTool(name))
|
|
69
|
+
return null;
|
|
70
|
+
const rest = name.slice(MCP_TOOL_PREFIX.length);
|
|
71
|
+
const idx = rest.indexOf("__");
|
|
72
|
+
if (idx === -1 || idx === 0 || idx + 2 >= rest.length)
|
|
73
|
+
return null;
|
|
74
|
+
return { server: rest.slice(0, idx), tool: rest.slice(idx + 2) };
|
|
75
|
+
}
|
|
76
|
+
/** One live connection to a spawned MCP server. */
|
|
77
|
+
export class McpConnection {
|
|
78
|
+
name;
|
|
79
|
+
cfg;
|
|
80
|
+
child = null;
|
|
81
|
+
buf = "";
|
|
82
|
+
nextId = 1;
|
|
83
|
+
pending = new Map();
|
|
84
|
+
closed = false;
|
|
85
|
+
tools = [];
|
|
86
|
+
constructor(name, cfg) {
|
|
87
|
+
this.name = name;
|
|
88
|
+
this.cfg = cfg;
|
|
89
|
+
}
|
|
90
|
+
async start(timeoutMs = 15000) {
|
|
91
|
+
this.child = spawn(this.cfg.command, this.cfg.args ?? [], {
|
|
92
|
+
env: { ...process.env, ...(this.cfg.env ?? {}) },
|
|
93
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
94
|
+
});
|
|
95
|
+
this.child.stdout.setEncoding("utf-8");
|
|
96
|
+
this.child.stdout.on("data", (chunk) => this._onData(chunk));
|
|
97
|
+
this.child.on("exit", () => this._fail(new Error(`MCP server '${this.name}' exited`)));
|
|
98
|
+
this.child.on("error", (e) => this._fail(e));
|
|
99
|
+
await this._request("initialize", {
|
|
100
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
101
|
+
capabilities: {},
|
|
102
|
+
clientInfo: { name: "xiaotime-cli", version: "0.6.1" },
|
|
103
|
+
}, timeoutMs);
|
|
104
|
+
this._notify("notifications/initialized", {});
|
|
105
|
+
const listed = (await this._request("tools/list", {}, timeoutMs));
|
|
106
|
+
const raw = Array.isArray(listed?.tools) ? listed.tools : [];
|
|
107
|
+
this.tools = raw
|
|
108
|
+
.filter((t) => t && typeof t.name === "string")
|
|
109
|
+
.map((t) => ({
|
|
110
|
+
name: `${MCP_TOOL_PREFIX}${this.name}__${t.name}`,
|
|
111
|
+
description: t.description ?? `(${this.name}) ${t.name}`,
|
|
112
|
+
input_schema: _normalizeSchema(t.inputSchema),
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
async callTool(tool, args, timeoutMs = 120000) {
|
|
116
|
+
const res = (await this._request("tools/call", { name: tool, arguments: args }, timeoutMs));
|
|
117
|
+
const content = Array.isArray(res?.content) ? res.content : [];
|
|
118
|
+
const text = content
|
|
119
|
+
.map((c) => (typeof c?.text === "string" ? c.text : ""))
|
|
120
|
+
.join("\n")
|
|
121
|
+
.trim();
|
|
122
|
+
return { text: text || "(empty result)", isError: Boolean(res?.isError) };
|
|
123
|
+
}
|
|
124
|
+
stop() {
|
|
125
|
+
this.closed = true;
|
|
126
|
+
for (const [, p] of this.pending) {
|
|
127
|
+
clearTimeout(p.timer);
|
|
128
|
+
p.reject(new Error("connection closed"));
|
|
129
|
+
}
|
|
130
|
+
this.pending.clear();
|
|
131
|
+
try {
|
|
132
|
+
this.child?.kill();
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
/* already gone */
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
_onData(chunk) {
|
|
139
|
+
this.buf += chunk;
|
|
140
|
+
let nl;
|
|
141
|
+
while ((nl = this.buf.indexOf("\n")) !== -1) {
|
|
142
|
+
const line = this.buf.slice(0, nl).trim();
|
|
143
|
+
this.buf = this.buf.slice(nl + 1);
|
|
144
|
+
if (!line)
|
|
145
|
+
continue;
|
|
146
|
+
let msg;
|
|
147
|
+
try {
|
|
148
|
+
msg = JSON.parse(line);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
continue; // non-JSON stderr-ish noise on stdout — skip
|
|
152
|
+
}
|
|
153
|
+
if (typeof msg.id === "number" && this.pending.has(msg.id)) {
|
|
154
|
+
const p = this.pending.get(msg.id);
|
|
155
|
+
clearTimeout(p.timer);
|
|
156
|
+
this.pending.delete(msg.id);
|
|
157
|
+
if (msg.error)
|
|
158
|
+
p.reject(new Error(msg.error.message ?? "MCP error"));
|
|
159
|
+
else
|
|
160
|
+
p.resolve(msg.result);
|
|
161
|
+
}
|
|
162
|
+
// server-initiated notifications are ignored (no id)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
_request(method, params, timeoutMs) {
|
|
166
|
+
if (this.closed || !this.child) {
|
|
167
|
+
return Promise.reject(new Error("MCP connection not open"));
|
|
168
|
+
}
|
|
169
|
+
const id = this.nextId++;
|
|
170
|
+
const payload = JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n";
|
|
171
|
+
return new Promise((resolve, reject) => {
|
|
172
|
+
const timer = setTimeout(() => {
|
|
173
|
+
this.pending.delete(id);
|
|
174
|
+
reject(new Error(`MCP '${this.name}' ${method} timed out`));
|
|
175
|
+
}, timeoutMs);
|
|
176
|
+
this.pending.set(id, { resolve, reject, timer });
|
|
177
|
+
try {
|
|
178
|
+
this.child.stdin.write(payload);
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
clearTimeout(timer);
|
|
182
|
+
this.pending.delete(id);
|
|
183
|
+
reject(e);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
_notify(method, params) {
|
|
188
|
+
if (this.closed || !this.child)
|
|
189
|
+
return;
|
|
190
|
+
try {
|
|
191
|
+
this.child.stdin.write(JSON.stringify({ jsonrpc: "2.0", method, params }) + "\n");
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
/* best-effort */
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
_fail(err) {
|
|
198
|
+
if (this.closed)
|
|
199
|
+
return;
|
|
200
|
+
for (const [, p] of this.pending) {
|
|
201
|
+
clearTimeout(p.timer);
|
|
202
|
+
p.reject(err);
|
|
203
|
+
}
|
|
204
|
+
this.pending.clear();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function _normalizeSchema(s) {
|
|
208
|
+
if (s && typeof s === "object" && s.type === "object") {
|
|
209
|
+
const obj = s;
|
|
210
|
+
return {
|
|
211
|
+
type: "object",
|
|
212
|
+
properties: obj.properties ?? {},
|
|
213
|
+
required: Array.isArray(obj.required) ? obj.required : undefined,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
return { type: "object", properties: {} };
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Owns every live MCP connection for a session. Connects all configured
|
|
220
|
+
* servers concurrently, aggregates their tools into one manifest slice,
|
|
221
|
+
* and routes tool calls to the right server. A server that fails to
|
|
222
|
+
* start is skipped (reported in `errors`), never fatal.
|
|
223
|
+
*/
|
|
224
|
+
export class McpManager {
|
|
225
|
+
conns = new Map();
|
|
226
|
+
async startAll(cfg = loadMcpConfig()) {
|
|
227
|
+
const errors = [];
|
|
228
|
+
const names = Object.keys(cfg.mcpServers);
|
|
229
|
+
await Promise.all(names.map(async (name) => {
|
|
230
|
+
const conn = new McpConnection(name, cfg.mcpServers[name]);
|
|
231
|
+
try {
|
|
232
|
+
await conn.start();
|
|
233
|
+
this.conns.set(name, conn);
|
|
234
|
+
}
|
|
235
|
+
catch (e) {
|
|
236
|
+
errors.push(`${name}: ${e.message}`);
|
|
237
|
+
conn.stop();
|
|
238
|
+
}
|
|
239
|
+
}));
|
|
240
|
+
const tools = [];
|
|
241
|
+
for (const c of this.conns.values())
|
|
242
|
+
tools.push(...c.tools);
|
|
243
|
+
return { tools, errors };
|
|
244
|
+
}
|
|
245
|
+
hasServers() {
|
|
246
|
+
return this.conns.size > 0;
|
|
247
|
+
}
|
|
248
|
+
serverNames() {
|
|
249
|
+
return [...this.conns.keys()];
|
|
250
|
+
}
|
|
251
|
+
async call(name, input, tool_use_id) {
|
|
252
|
+
const parsed = parseMcpToolName(name);
|
|
253
|
+
if (!parsed) {
|
|
254
|
+
return { tool_use_id, content: `Not an MCP tool: ${name}`, is_error: true };
|
|
255
|
+
}
|
|
256
|
+
const conn = this.conns.get(parsed.server);
|
|
257
|
+
if (!conn) {
|
|
258
|
+
return {
|
|
259
|
+
tool_use_id,
|
|
260
|
+
content: `MCP server not connected: ${parsed.server}`,
|
|
261
|
+
is_error: true,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
const { text, isError } = await conn.callTool(parsed.tool, input);
|
|
266
|
+
return { tool_use_id, content: text, is_error: isError };
|
|
267
|
+
}
|
|
268
|
+
catch (e) {
|
|
269
|
+
return {
|
|
270
|
+
tool_use_id,
|
|
271
|
+
content: `MCP call failed: ${e.message}`,
|
|
272
|
+
is_error: true,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
stopAll() {
|
|
277
|
+
for (const c of this.conns.values())
|
|
278
|
+
c.stop();
|
|
279
|
+
this.conns.clear();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=mcp.js.map
|
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAuC,MAAM,eAAe,CAAC;AAa3E,MAAM,gBAAgB,GAAG,YAAY,CAAC;AACtC,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AAEvC,MAAM,UAAU,aAAa;IAC3B,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAC/B,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,CACjD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,CAAC,GAAG,aAAa,EAAE,CAAC;IAC1B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,MAAM,EAAE,UAAU,CAAC;QACnC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QACvE,OAAO,EAAE,UAAU,EAAE,OAA0C,EAAE,CAAC;IACpE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+CAAgD,CAAW,CAAC,OAAO,IAAI,CACxE,CAAC;QACF,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AAC1C,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,gBAAgB,CAC9B,IAAY;IAEZ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACnE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC;AAQD,mDAAmD;AACnD,MAAM,OAAO,aAAa;IACf,IAAI,CAAS;IACd,GAAG,CAAkB;IACrB,KAAK,GAA0C,IAAI,CAAC;IACpD,GAAG,GAAG,EAAE,CAAC;IACT,MAAM,GAAG,CAAC,CAAC;IACX,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IACrC,MAAM,GAAG,KAAK,CAAC;IACvB,KAAK,GAAwB,EAAE,CAAC;IAEhC,YAAY,IAAY,EAAE,GAAoB;QAC5C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE;YACxD,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;YAChD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAmC,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CACzB,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,CAC1D,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAU,CAAC,CAAC,CAAC;QAEtD,MAAM,IAAI,CAAC,QAAQ,CACjB,YAAY,EACZ;YACE,eAAe,EAAE,gBAAgB;YACjC,YAAY,EAAE,EAAE;YAChB,UAAU,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE;SACvD,EACD,SAAS,CACV,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QAE9C,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,EAAE,SAAS,CAAC,CAE/D,CAAC;QACF,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,IAAI,CAAC,KAAK,GAAG,GAAG;aACb,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;aAC9C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,GAAG,eAAe,GAAG,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE;YACjD,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE;YACxD,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC;SAC9C,CAAC,CAAC,CAAC;IACR,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,IAAY,EACZ,IAA6B,EAC7B,SAAS,GAAG,MAAM;QAElB,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,CAC9B,YAAY,EACZ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAC/B,SAAS,CACV,CAA6E,CAAC;QAC/E,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,GAAG,OAAO;aACjB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aACvD,IAAI,CAAC,IAAI,CAAC;aACV,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;IAC5E,CAAC;IAED,IAAI;QACF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC;IAEO,OAAO,CAAC,KAAa;QAC3B,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC;QAClB,IAAI,EAAU,CAAC;QACf,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,IAAI,GAAoE,CAAC;YACzE,IAAI,CAAC;gBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS,CAAC,6CAA6C;YACzD,CAAC;YACD,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC3D,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;gBACpC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC5B,IAAI,GAAG,CAAC,KAAK;oBAAE,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,WAAW,CAAC,CAAC,CAAC;;oBAChE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;YACD,qDAAqD;QACvD,CAAC;IACH,CAAC;IAEO,QAAQ,CAAC,MAAc,EAAE,MAAe,EAAE,SAAiB;QACjE,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;QAC9E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,IAAI,KAAK,MAAM,YAAY,CAAC,CAAC,CAAC;YAC9D,CAAC,EAAE,SAAS,CAAC,CAAC;YACd,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC;gBACH,IAAI,CAAC,KAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,MAAM,CAAC,CAAU,CAAC,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,OAAO,CAAC,MAAc,EAAE,MAAe;QAC7C,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QACvC,IAAI,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,iBAAiB;QACnB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,GAAU;QACtB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF;AAED,SAAS,gBAAgB,CAAC,CAAU;IAClC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAK,CAAuB,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7E,MAAM,GAAG,GAAG,CAA+D,CAAC;QAC5E,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE;YAChC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,QAAqB,CAAC,CAAC,CAAC,SAAS;SAC/E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IACb,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEjD,KAAK,CAAC,QAAQ,CACZ,MAAiB,aAAa,EAAE;QAEhC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACvB,MAAM,IAAI,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3D,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;gBACnB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,KAAM,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;gBAChD,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CACH,CAAC;QACF,MAAM,KAAK,GAAwB,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,WAAW;QACT,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,IAAI,CACR,IAAY,EACZ,KAA8B,EAC9B,WAAmB;QAEnB,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,oBAAoB,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC9E,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,WAAW;gBACX,OAAO,EAAE,6BAA6B,MAAM,CAAC,MAAM,EAAE;gBACrD,QAAQ,EAAE,IAAI;aACf,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAClE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAC3D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO;gBACL,WAAW;gBACX,OAAO,EAAE,oBAAqB,CAAW,CAAC,OAAO,EAAE;gBACnD,QAAQ,EAAE,IAAI;aACf,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
|