brainferno-mcp-bridge 0.1.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/CHANGELOG.md +19 -0
- package/LICENSE +202 -0
- package/NOTICE +27 -0
- package/README.md +410 -0
- package/THIRD_PARTY_NOTICES.md +52 -0
- package/dist/bridge/handshake.d.ts +34 -0
- package/dist/bridge/handshake.js +36 -0
- package/dist/bridge/handshake.js.map +1 -0
- package/dist/bridge/script-escape.d.ts +16 -0
- package/dist/bridge/script-escape.js +47 -0
- package/dist/bridge/script-escape.js.map +1 -0
- package/dist/bridge/socket.d.ts +79 -0
- package/dist/bridge/socket.js +424 -0
- package/dist/bridge/socket.js.map +1 -0
- package/dist/bridge/types.d.ts +49 -0
- package/dist/bridge/types.js +38 -0
- package/dist/bridge/types.js.map +1 -0
- package/dist/config.d.ts +87 -0
- package/dist/config.js +172 -0
- package/dist/config.js.map +1 -0
- package/dist/drivers/ame-webservice.d.ts +118 -0
- package/dist/drivers/ame-webservice.js +356 -0
- package/dist/drivers/ame-webservice.js.map +1 -0
- package/dist/drivers/illustrator-delegate.d.ts +71 -0
- package/dist/drivers/illustrator-delegate.js +120 -0
- package/dist/drivers/illustrator-delegate.js.map +1 -0
- package/dist/drivers/osscript.d.ts +60 -0
- package/dist/drivers/osscript.js +230 -0
- package/dist/drivers/osscript.js.map +1 -0
- package/dist/http.d.ts +26 -0
- package/dist/http.js +126 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/install/cli.d.ts +2 -0
- package/dist/install/cli.js +310 -0
- package/dist/install/cli.js.map +1 -0
- package/dist/install/lib.d.ts +76 -0
- package/dist/install/lib.js +194 -0
- package/dist/install/lib.js.map +1 -0
- package/dist/jobs.d.ts +117 -0
- package/dist/jobs.js +196 -0
- package/dist/jobs.js.map +1 -0
- package/dist/logging.d.ts +8 -0
- package/dist/logging.js +33 -0
- package/dist/logging.js.map +1 -0
- package/dist/server.d.ts +38 -0
- package/dist/server.js +90 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/after-effects.d.ts +100 -0
- package/dist/tools/after-effects.js +695 -0
- package/dist/tools/after-effects.js.map +1 -0
- package/dist/tools/audio.d.ts +118 -0
- package/dist/tools/audio.js +356 -0
- package/dist/tools/audio.js.map +1 -0
- package/dist/tools/audition.d.ts +15 -0
- package/dist/tools/audition.js +329 -0
- package/dist/tools/audition.js.map +1 -0
- package/dist/tools/diagnostics.d.ts +17 -0
- package/dist/tools/diagnostics.js +61 -0
- package/dist/tools/diagnostics.js.map +1 -0
- package/dist/tools/illustrator-delegate.d.ts +9 -0
- package/dist/tools/illustrator-delegate.js +61 -0
- package/dist/tools/illustrator-delegate.js.map +1 -0
- package/dist/tools/illustrator.d.ts +36 -0
- package/dist/tools/illustrator.js +299 -0
- package/dist/tools/illustrator.js.map +1 -0
- package/dist/tools/jobs.d.ts +39 -0
- package/dist/tools/jobs.js +83 -0
- package/dist/tools/jobs.js.map +1 -0
- package/dist/tools/media-encoder.d.ts +17 -0
- package/dist/tools/media-encoder.js +180 -0
- package/dist/tools/media-encoder.js.map +1 -0
- package/dist/tools/photoshop.d.ts +17 -0
- package/dist/tools/photoshop.js +202 -0
- package/dist/tools/photoshop.js.map +1 -0
- package/dist/tools/pipelines.d.ts +23 -0
- package/dist/tools/pipelines.js +254 -0
- package/dist/tools/pipelines.js.map +1 -0
- package/dist/tools/premiere.d.ts +26 -0
- package/dist/tools/premiere.js +396 -0
- package/dist/tools/premiere.js.map +1 -0
- package/dist/tools/result.d.ts +17 -0
- package/dist/tools/result.js +51 -0
- package/dist/tools/result.js.map +1 -0
- package/package.json +64 -0
- package/panels/panel-cep/CSXS/manifest.xml +53 -0
- package/panels/panel-cep/bridge-client.js +204 -0
- package/panels/panel-cep/host.jsx +62 -0
- package/panels/panel-cep/icons/logo.svg +61 -0
- package/panels/panel-cep/index.html +48 -0
- package/panels/panel-cep/main.js +173 -0
- package/panels/panel-uxp/README.md +36 -0
- package/panels/panel-uxp/bridge-client.js +204 -0
- package/panels/panel-uxp/commands.js +375 -0
- package/panels/panel-uxp/icons/icon.png +0 -0
- package/panels/panel-uxp/icons/icon@2x.png +0 -0
- package/panels/panel-uxp/icons/logo.svg +61 -0
- package/panels/panel-uxp/index.html +47 -0
- package/panels/panel-uxp/main.js +109 -0
- package/panels/panel-uxp/manifest.json +89 -0
- package/panels/panel-uxp-ppro/README.md +11 -0
- package/panels/panel-uxp-ppro/bridge-client.js +204 -0
- package/panels/panel-uxp-ppro/commands.js +797 -0
- package/panels/panel-uxp-ppro/icons/icon.png +0 -0
- package/panels/panel-uxp-ppro/icons/icon@2x.png +0 -0
- package/panels/panel-uxp-ppro/icons/logo.svg +61 -0
- package/panels/panel-uxp-ppro/index.html +64 -0
- package/panels/panel-uxp-ppro/main.js +113 -0
- package/panels/panel-uxp-ppro/manifest.json +65 -0
package/dist/http.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { randomUUID, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
4
|
+
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { log } from "./logging.js";
|
|
6
|
+
function tokenMatches(header, token) {
|
|
7
|
+
if (!header)
|
|
8
|
+
return false;
|
|
9
|
+
const m = /^Bearer\s+(.+)$/i.exec(header.trim());
|
|
10
|
+
if (!m)
|
|
11
|
+
return false;
|
|
12
|
+
const given = Buffer.from(m[1] ?? "", "utf8");
|
|
13
|
+
const want = Buffer.from(token, "utf8");
|
|
14
|
+
return given.length === want.length && timingSafeEqual(given, want);
|
|
15
|
+
}
|
|
16
|
+
function readBody(req, limit = 4 * 1024 * 1024) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
let data = "";
|
|
19
|
+
req.setEncoding("utf8");
|
|
20
|
+
req.on("data", (d) => {
|
|
21
|
+
data += d;
|
|
22
|
+
if (data.length > limit) {
|
|
23
|
+
reject(new Error("request body too large"));
|
|
24
|
+
req.destroy();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
req.on("end", () => resolve(data));
|
|
28
|
+
req.on("error", reject);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function reply(res, status, body) {
|
|
32
|
+
res.writeHead(status, { "content-type": "application/json" });
|
|
33
|
+
res.end(JSON.stringify(body));
|
|
34
|
+
}
|
|
35
|
+
export async function startHttpServer(createSession, o) {
|
|
36
|
+
if (!o.token || o.token.length < 16)
|
|
37
|
+
throw new Error("Remote mode needs a token of at least 16 characters (BRAINFERNO_MCP_HTTP_TOKEN or httpToken in ~/.brainferno-mcp-bridge/config.json).");
|
|
38
|
+
const path = o.path ?? "/mcp";
|
|
39
|
+
const sessions = new Map();
|
|
40
|
+
const handle = async (req, res) => {
|
|
41
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
42
|
+
if (url.pathname !== path)
|
|
43
|
+
return reply(res, 404, { error: "not found" });
|
|
44
|
+
if (!tokenMatches(req.headers["authorization"], o.token)) {
|
|
45
|
+
res.setHeader("www-authenticate", 'Bearer realm="brainferno-mcp-bridge"');
|
|
46
|
+
return reply(res, 401, { jsonrpc: "2.0", error: { code: -32001, message: "Unauthorized: missing or wrong bearer token" }, id: null });
|
|
47
|
+
}
|
|
48
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
49
|
+
const existing = typeof sessionId === "string" ? sessions.get(sessionId) : undefined;
|
|
50
|
+
if (existing) {
|
|
51
|
+
const body = req.method === "POST" ? await readBody(req) : undefined;
|
|
52
|
+
let parsed = undefined;
|
|
53
|
+
if (body !== undefined && body !== "") {
|
|
54
|
+
try {
|
|
55
|
+
parsed = JSON.parse(body);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return reply(res, 400, { jsonrpc: "2.0", error: { code: -32700, message: "Parse error" }, id: null });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
await existing.transport.handleRequest(req, res, parsed);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (req.method !== "POST")
|
|
65
|
+
return reply(res, 400, { jsonrpc: "2.0", error: { code: -32000, message: "No session: send an initialize request first" }, id: null });
|
|
66
|
+
let parsed;
|
|
67
|
+
try {
|
|
68
|
+
parsed = JSON.parse(await readBody(req));
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return reply(res, 400, { jsonrpc: "2.0", error: { code: -32700, message: "Parse error" }, id: null });
|
|
72
|
+
}
|
|
73
|
+
if (!isInitializeRequest(parsed))
|
|
74
|
+
return reply(res, 400, { jsonrpc: "2.0", error: { code: -32000, message: "Unknown session id; send initialize to start one" }, id: null });
|
|
75
|
+
const server = createSession();
|
|
76
|
+
const transport = new StreamableHTTPServerTransport({
|
|
77
|
+
sessionIdGenerator: () => randomUUID(),
|
|
78
|
+
onsessioninitialized: (id) => {
|
|
79
|
+
sessions.set(id, { transport, server });
|
|
80
|
+
log.info(`remote session ${id.slice(0, 8)} opened from ${req.socket.remoteAddress ?? "?"} (${sessions.size} open)`);
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
transport.onclose = () => {
|
|
84
|
+
const id = transport.sessionId;
|
|
85
|
+
if (id && sessions.delete(id))
|
|
86
|
+
log.info(`remote session ${id.slice(0, 8)} closed (${sessions.size} open)`);
|
|
87
|
+
void server.close().catch(() => undefined);
|
|
88
|
+
};
|
|
89
|
+
await server.connect(transport);
|
|
90
|
+
await transport.handleRequest(req, res, parsed);
|
|
91
|
+
};
|
|
92
|
+
const httpServer = createServer((req, res) => {
|
|
93
|
+
handle(req, res).catch((e) => {
|
|
94
|
+
log.warn("remote request failed", e);
|
|
95
|
+
if (!res.headersSent)
|
|
96
|
+
reply(res, 500, { jsonrpc: "2.0", error: { code: -32603, message: e instanceof Error ? e.message : String(e) }, id: null });
|
|
97
|
+
else
|
|
98
|
+
res.end();
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
await new Promise((resolve, reject) => {
|
|
102
|
+
httpServer.once("error", reject);
|
|
103
|
+
httpServer.listen(o.port, o.host, () => {
|
|
104
|
+
httpServer.off("error", reject);
|
|
105
|
+
resolve();
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
const addr = httpServer.address();
|
|
109
|
+
const port = typeof addr === "object" && addr ? addr.port : o.port;
|
|
110
|
+
log.info(`remote MCP listening on http://${o.host}:${port}${path} (bearer token required)`);
|
|
111
|
+
return {
|
|
112
|
+
host: o.host,
|
|
113
|
+
port,
|
|
114
|
+
path,
|
|
115
|
+
sessions: () => sessions.size,
|
|
116
|
+
close: async () => {
|
|
117
|
+
for (const [id, s] of sessions) {
|
|
118
|
+
sessions.delete(id);
|
|
119
|
+
await s.transport.close().catch(() => undefined);
|
|
120
|
+
await s.server.close().catch(() => undefined);
|
|
121
|
+
}
|
|
122
|
+
await new Promise((resolve) => httpServer.close(() => resolve()));
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { loadConfig, migrateLegacyUserDir } from "./config.js";
|
|
4
|
+
import { startHttpServer } from "./http.js";
|
|
5
|
+
import { log } from "./logging.js";
|
|
6
|
+
import { buildRuntime, createMcpServer } from "./server.js";
|
|
7
|
+
async function main() {
|
|
8
|
+
const migrated = migrateLegacyUserDir();
|
|
9
|
+
if (migrated)
|
|
10
|
+
log.info(`copied settings from ${migrated} to ~/.brainferno-mcp-bridge (the old folder can be deleted)`);
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const rt = buildRuntime(config);
|
|
13
|
+
await rt.bridge.ready();
|
|
14
|
+
const server = createMcpServer(rt);
|
|
15
|
+
const transport = new StdioServerTransport();
|
|
16
|
+
await server.connect(transport);
|
|
17
|
+
log.info("MCP server ready on stdio");
|
|
18
|
+
let remote = null;
|
|
19
|
+
if (config.httpPort > 0) {
|
|
20
|
+
remote = await startHttpServer(() => createMcpServer(rt), { host: config.httpHost, port: config.httpPort, token: config.httpToken });
|
|
21
|
+
}
|
|
22
|
+
const shutdown = (signal) => {
|
|
23
|
+
void (async () => {
|
|
24
|
+
log.info(`received ${signal}, shutting down`);
|
|
25
|
+
await server.close().catch((error) => log.warn("error closing MCP server", error));
|
|
26
|
+
if (remote)
|
|
27
|
+
await remote.close().catch((error) => log.warn("error closing remote listener", error));
|
|
28
|
+
await rt.bridge.close().catch((error) => log.warn("error closing bridge", error));
|
|
29
|
+
await rt.illustratorDelegate.close().catch((error) => log.warn("error closing delegate", error));
|
|
30
|
+
await rt.illustratorBridge.close().catch((error) => log.warn("error closing illustrator bridge", error));
|
|
31
|
+
await rt.mediaEncoder.stop().catch((error) => log.warn("error stopping Media Encoder service", error));
|
|
32
|
+
process.exit(0);
|
|
33
|
+
})();
|
|
34
|
+
};
|
|
35
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
36
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
37
|
+
}
|
|
38
|
+
main().catch((error) => {
|
|
39
|
+
log.error("fatal", error);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { homedir, hostname, tmpdir } from "node:os";
|
|
5
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
6
|
+
import { createInterface } from "node:readline/promises";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { DEFAULT_ILLUSTRATOR_MCP_URL, migrateLegacyUserDir, readUserConfig, userConfigPath } from "../config.js";
|
|
9
|
+
import { APP_CHOICES, DEFAULT_HTTP_PORT, appsNeed, checkIllustratorKey, detectInstalledApps, extractIllustratorKey, extractIllustratorUrl, firewallCommands, lanAddresses, mcpAddCommands, mergeUserConfig, pickApps, platformPaths, rewriteAmeIni } from "./lib.js";
|
|
10
|
+
/**
|
|
11
|
+
* Interactive installer:
|
|
12
|
+
* node dist/install/cli.js [--apps ps,ae,ppro,ai,au,ame|all] [--mode local|shared] [--token T] [--port N] [--yes] [--no-panels] [--no-ame] [--no-firewall] [--register]
|
|
13
|
+
* [--illustrator-key K|"claude mcp add … line"] [--illustrator-url U] [--no-illustrator]
|
|
14
|
+
*
|
|
15
|
+
* Asks one question — "only this computer" or "shared on my network" — and
|
|
16
|
+
* sets every switch that depends on it: the remote MCP listener + token, the
|
|
17
|
+
* Windows firewall rule, and Media Encoder's web-service address. Also wires
|
|
18
|
+
* the CEP panel (junction + PlayerDebugMode) and prints the UXP steps and the
|
|
19
|
+
* `claude mcp add` lines. Safe to re-run to switch modes.
|
|
20
|
+
*/
|
|
21
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
22
|
+
const pkgRoot = resolve(here, "..", "..");
|
|
23
|
+
const distIndex = resolve(here, "..", "index.js");
|
|
24
|
+
// Installed from npm: the panels ship inside the package (panels/). From a git
|
|
25
|
+
// checkout: they are sibling workspaces (packages/).
|
|
26
|
+
const panelsDir = existsSync(join(pkgRoot, "panels")) ? join(pkgRoot, "panels") : resolve(pkgRoot, "..");
|
|
27
|
+
const panelCep = join(panelsDir, "panel-cep");
|
|
28
|
+
const panelUxp = join(panelsDir, "panel-uxp", "manifest.json");
|
|
29
|
+
const panelUxpPpro = join(panelsDir, "panel-uxp-ppro", "manifest.json");
|
|
30
|
+
const args = new Map();
|
|
31
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
32
|
+
const a = process.argv[i];
|
|
33
|
+
if (!a.startsWith("--"))
|
|
34
|
+
continue;
|
|
35
|
+
const [k, v] = a.slice(2).split("=", 2);
|
|
36
|
+
if (v !== undefined)
|
|
37
|
+
args.set(k, v);
|
|
38
|
+
else if (process.argv[i + 1] && !process.argv[i + 1].startsWith("--") && ["mode", "token", "port", "host", "illustrator-key", "illustrator-url", "apps"].includes(k))
|
|
39
|
+
args.set(k, process.argv[++i]);
|
|
40
|
+
else
|
|
41
|
+
args.set(k, true);
|
|
42
|
+
}
|
|
43
|
+
const flag = (k) => args.get(k) === true;
|
|
44
|
+
const str = (k) => (typeof args.get(k) === "string" ? args.get(k) : undefined);
|
|
45
|
+
const say = (s = "") => console.log(s);
|
|
46
|
+
const ok = (s) => say(` ✓ ${s}`);
|
|
47
|
+
const warn = (s) => say(` ! ${s}`);
|
|
48
|
+
function run(cmd, opts = {}) {
|
|
49
|
+
if (opts.elevate && process.platform === "win32") {
|
|
50
|
+
// One UAC prompt for the admin-only steps (Program Files, firewall).
|
|
51
|
+
const ps = join(tmpdir(), `brainferno-mcp-bridge-elevated-${process.pid}.ps1`);
|
|
52
|
+
writeFileSync(ps, cmd.map((c) => (/\s/.test(c) ? `"${c.replace(/"/g, '`"')}"` : c)).join(" ") + "\nexit $LASTEXITCODE\n");
|
|
53
|
+
const r = spawnSync("powershell", ["-NoProfile", "-Command", `$p = Start-Process -FilePath powershell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File "${ps}"' -Verb RunAs -Wait -PassThru; exit $p.ExitCode`], { encoding: "utf8" });
|
|
54
|
+
return { code: r.status ?? 1, out: (r.stdout ?? "") + (r.stderr ?? "") };
|
|
55
|
+
}
|
|
56
|
+
// `claude` is a shell shim on Windows; run it through the shell as one string. Everything else is a real exe.
|
|
57
|
+
const viaShell = process.platform === "win32" && cmd[0] === "claude";
|
|
58
|
+
const r = viaShell
|
|
59
|
+
? spawnSync(cmd.map((c) => (/\s/.test(c) ? `"${c}"` : c)).join(" "), { encoding: "utf8", shell: true })
|
|
60
|
+
: spawnSync(cmd[0], cmd.slice(1), { encoding: "utf8" });
|
|
61
|
+
return { code: r.status ?? 1, out: (r.stdout ?? "") + (r.stderr ?? "") };
|
|
62
|
+
}
|
|
63
|
+
async function main() {
|
|
64
|
+
say("");
|
|
65
|
+
say("Brainferno MCP Bridge — installer");
|
|
66
|
+
say("=================================");
|
|
67
|
+
if (!existsSync(distIndex)) {
|
|
68
|
+
warn(`server build not found at ${distIndex}; run "npm run build" first.`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
72
|
+
const ask = async (q, def) => {
|
|
73
|
+
if (flag("yes"))
|
|
74
|
+
return def;
|
|
75
|
+
const a = (await rl.question(`${q} [${def}] `)).trim();
|
|
76
|
+
return a === "" ? def : a;
|
|
77
|
+
};
|
|
78
|
+
// ---- 0. which apps ------------------------------------------------------
|
|
79
|
+
const migratedFrom = migrateLegacyUserDir();
|
|
80
|
+
if (migratedFrom)
|
|
81
|
+
ok(`copied your settings from ${migratedFrom} to ${dirname(userConfigPath())}`);
|
|
82
|
+
const existing = readUserConfig();
|
|
83
|
+
const detected = detectInstalledApps();
|
|
84
|
+
const preset = existing.enabledApps ?? (detected.length ? detected : APP_CHOICES.map((c) => c.id));
|
|
85
|
+
let apps = str("apps") !== undefined ? pickApps(str("apps"), preset) : undefined;
|
|
86
|
+
if (!apps) {
|
|
87
|
+
if (flag("yes"))
|
|
88
|
+
apps = [...preset];
|
|
89
|
+
else {
|
|
90
|
+
say("");
|
|
91
|
+
say("Which applications should this server control?");
|
|
92
|
+
APP_CHOICES.forEach((c, i) => say(` ${i + 1}) ${c.label.padEnd(14)} ${detected.includes(c.id) ? "(installed)" : "(not found)"}${preset.includes(c.id) ? " ←" : ""}`));
|
|
93
|
+
const a = await ask("Numbers like 1,2,5 — or 'all'", preset.map((id) => APP_CHOICES.findIndex((c) => c.id === id) + 1).join(","));
|
|
94
|
+
apps = pickApps(a, preset);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (apps.length === 0) {
|
|
98
|
+
warn("no applications chosen; nothing to install");
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
say("");
|
|
102
|
+
say(`Apps: ${APP_CHOICES.filter((c) => apps.includes(c.id)).map((c) => c.label).join(", ")}`);
|
|
103
|
+
// ---- 1. the question ----------------------------------------------------
|
|
104
|
+
let mode = str("mode");
|
|
105
|
+
if (!mode) {
|
|
106
|
+
say("");
|
|
107
|
+
say("Who may use this MCP server?");
|
|
108
|
+
say(" 1) Only this computer (Claude Code on this PC; nothing listens on the network)");
|
|
109
|
+
say(" 2) Shared on my network (other computers connect with a token over HTTP)");
|
|
110
|
+
const a = await ask("Choose 1 or 2", "1");
|
|
111
|
+
mode = a === "2" ? "shared" : "local";
|
|
112
|
+
}
|
|
113
|
+
say("");
|
|
114
|
+
say(`Mode: ${mode === "local" ? "only this computer" : "shared on my network"}`);
|
|
115
|
+
// ---- 2. Illustrator MCP key (Adobe's own server inside Illustrator) ------
|
|
116
|
+
let illustratorKey = undefined;
|
|
117
|
+
let illustratorUrl = str("illustrator-url") ?? undefined;
|
|
118
|
+
if (!flag("no-illustrator") && appsNeed(apps, "illustrator-key")) {
|
|
119
|
+
let pasted = str("illustrator-key");
|
|
120
|
+
if (pasted === undefined && !flag("yes")) {
|
|
121
|
+
say("");
|
|
122
|
+
say("Illustrator has its own MCP server (Beta today; the shipping release may change the address).");
|
|
123
|
+
say("In Illustrator: Preferences → MCP (Beta) shows a 'claude mcp add … Bearer ilst_…' line.");
|
|
124
|
+
say(`Paste that whole line or just the key here${existing.illustratorKey ? " (Enter keeps the saved key)" : " (Enter skips)"}.`);
|
|
125
|
+
pasted = (await rl.question("Illustrator key: ")).trim();
|
|
126
|
+
}
|
|
127
|
+
if (pasted !== undefined && pasted !== "") {
|
|
128
|
+
const key = extractIllustratorKey(pasted);
|
|
129
|
+
if (!key)
|
|
130
|
+
warn("that did not look like a key; nothing saved");
|
|
131
|
+
else {
|
|
132
|
+
illustratorKey = key;
|
|
133
|
+
const fromLine = extractIllustratorUrl(pasted);
|
|
134
|
+
if (fromLine && fromLine !== DEFAULT_ILLUSTRATOR_MCP_URL)
|
|
135
|
+
illustratorUrl = fromLine;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const keyToCheck = illustratorKey ?? existing.illustratorKey;
|
|
139
|
+
const urlToCheck = illustratorUrl ?? existing.illustratorUrl ?? DEFAULT_ILLUSTRATOR_MCP_URL;
|
|
140
|
+
if (keyToCheck) {
|
|
141
|
+
const check = await checkIllustratorKey(urlToCheck, keyToCheck);
|
|
142
|
+
if (check.ok)
|
|
143
|
+
ok(`Illustrator MCP key accepted by ${check.serverName ?? "the server"} at ${urlToCheck}`);
|
|
144
|
+
else if (check.reason === "not-running")
|
|
145
|
+
warn(`Illustrator MCP not reachable at ${urlToCheck} (is Illustrator open with MCP enabled?) — key saved anyway`);
|
|
146
|
+
else if (check.reason === "refused")
|
|
147
|
+
warn(`Illustrator refused the key (${check.detail}) — saved anyway; re-run with the current key from Illustrator`);
|
|
148
|
+
else
|
|
149
|
+
warn(`could not verify the Illustrator key (${check.detail}) — saved anyway`);
|
|
150
|
+
}
|
|
151
|
+
else
|
|
152
|
+
ok("Illustrator MCP delegate skipped (no key); the panel-less ai_* tools work without it");
|
|
153
|
+
}
|
|
154
|
+
// ---- 3. user config (remote listener + token) ---------------------------
|
|
155
|
+
const port = Number(str("port") ?? existing.httpPort ?? DEFAULT_HTTP_PORT);
|
|
156
|
+
const token = str("token") ?? (mode === "shared" ? existing.httpToken : undefined);
|
|
157
|
+
const next = mergeUserConfig(existing, mode, {
|
|
158
|
+
port,
|
|
159
|
+
...(token !== undefined ? { token } : {}),
|
|
160
|
+
...(str("host") !== undefined ? { host: str("host") } : {}),
|
|
161
|
+
...(illustratorKey !== undefined ? { illustratorKey } : {}),
|
|
162
|
+
...(illustratorUrl !== undefined ? { illustratorUrl } : {}),
|
|
163
|
+
apps,
|
|
164
|
+
});
|
|
165
|
+
mkdirSync(dirname(userConfigPath()), { recursive: true });
|
|
166
|
+
writeFileSync(userConfigPath(), JSON.stringify(next, null, 2) + "\n");
|
|
167
|
+
try {
|
|
168
|
+
chmodSync(userConfigPath(), 0o600);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
/* Windows ACLs: the file is under the user's profile already */
|
|
172
|
+
}
|
|
173
|
+
ok(`wrote ${userConfigPath()}${mode === "shared" ? ` (remote port ${next.httpPort}, token set)` : " (remote mode off)"}`);
|
|
174
|
+
// ---- 4. CEP panel (After Effects, Audition) -----------------------------
|
|
175
|
+
const paths = platformPaths(process.platform, homedir(), process.env["APPDATA"]);
|
|
176
|
+
if (!flag("no-panels") && appsNeed(apps, "cep")) {
|
|
177
|
+
try {
|
|
178
|
+
mkdirSync(paths.cepExtensionsDir, { recursive: true });
|
|
179
|
+
const linkName = "com.brainferno.mcp-bridge.cep";
|
|
180
|
+
const target = join(paths.cepExtensionsDir, linkName);
|
|
181
|
+
// Drop older links to the same panel folder (the spike name), or a stale one under our name.
|
|
182
|
+
for (const entry of [linkName, "com.brainferno.mcp-bridge.cep"]) {
|
|
183
|
+
const p = join(paths.cepExtensionsDir, entry);
|
|
184
|
+
try {
|
|
185
|
+
const st = lstatSync(p);
|
|
186
|
+
if (st.isSymbolicLink() || (process.platform === "win32" && st.isDirectory())) {
|
|
187
|
+
let points = "";
|
|
188
|
+
try {
|
|
189
|
+
points = readlinkSync(p);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
/* junction on Windows: readlink may fail; compare by name only */
|
|
193
|
+
}
|
|
194
|
+
if (entry !== linkName || (points && resolve(points) !== resolve(panelCep))) {
|
|
195
|
+
rmSync(p, { recursive: false, force: true });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
/* not there */
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (!existsSync(target))
|
|
204
|
+
symlinkSync(panelCep, target, process.platform === "win32" ? "junction" : "dir");
|
|
205
|
+
ok(`CEP panel linked: ${target} → ${panelCep}`);
|
|
206
|
+
for (const c of paths.csxsDebugCommands) {
|
|
207
|
+
const r = run(c);
|
|
208
|
+
if (r.code !== 0)
|
|
209
|
+
warn(`${c.join(" ")} failed: ${r.out.trim()}`);
|
|
210
|
+
}
|
|
211
|
+
ok("CEP PlayerDebugMode=1 (CSXS 11–14) so the unsigned panel loads");
|
|
212
|
+
}
|
|
213
|
+
catch (e) {
|
|
214
|
+
warn(`CEP panel setup failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// ---- 4. Media Encoder web-service address --------------------------------
|
|
218
|
+
if (!flag("no-ame") && appsNeed(apps, "ame-ini")) {
|
|
219
|
+
const ini = paths.ameIniCandidates.find((p) => existsSync(p));
|
|
220
|
+
if (!ini)
|
|
221
|
+
warn("Media Encoder not found; skipped its web-service address.");
|
|
222
|
+
else {
|
|
223
|
+
const current = readFileSync(ini, "utf8");
|
|
224
|
+
const wanted = rewriteAmeIni(current, mode);
|
|
225
|
+
if (wanted === current)
|
|
226
|
+
ok(`Media Encoder web service already ${mode === "local" ? "pinned to 127.0.0.1" : "on the network address"} (${basename(dirname(ini))})`);
|
|
227
|
+
else {
|
|
228
|
+
try {
|
|
229
|
+
writeFileSync(ini, wanted);
|
|
230
|
+
ok(`Media Encoder web service ${mode === "local" ? "pinned to 127.0.0.1" : "set to the network address"}`);
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
if (process.platform === "win32") {
|
|
234
|
+
const tmp = join(tmpdir(), "ame_webservice_config.ini");
|
|
235
|
+
writeFileSync(tmp, wanted);
|
|
236
|
+
const r = run(["Copy-Item", "-Force", tmp, ini], { elevate: true });
|
|
237
|
+
if (r.code === 0)
|
|
238
|
+
ok(`Media Encoder web service ${mode === "local" ? "pinned to 127.0.0.1" : "set to the network address"} (admin)`);
|
|
239
|
+
else
|
|
240
|
+
warn(`could not write ${ini} — edit it as admin: ${mode === "local" ? "ip = 127.0.0.1" : "#ip = 127.0.0.1"}`);
|
|
241
|
+
}
|
|
242
|
+
else
|
|
243
|
+
warn(`could not write ${ini} — edit it with sudo: ${mode === "local" ? "ip = 127.0.0.1" : "#ip = 127.0.0.1"}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// ---- 5. firewall --------------------------------------------------------
|
|
249
|
+
if (!flag("no-firewall")) {
|
|
250
|
+
const cmds = firewallCommands(process.platform, mode, next.httpPort ?? port);
|
|
251
|
+
if (cmds.length === 0)
|
|
252
|
+
ok("firewall: nothing to do on this platform");
|
|
253
|
+
else {
|
|
254
|
+
const script = cmds.map((c) => c.join(" ")).join("; ");
|
|
255
|
+
const r = run(["powershell", "-NoProfile", "-Command", script], { elevate: true });
|
|
256
|
+
if (r.code === 0)
|
|
257
|
+
ok(mode === "shared" ? `firewall: port ${next.httpPort} open on private networks` : "firewall: remote rule removed");
|
|
258
|
+
else
|
|
259
|
+
warn(`firewall step skipped (${r.out.trim().split("\n")[0] ?? "no admin"}). Manually: ${script}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// ---- 6. UXP panels (Photoshop, Premiere) --------------------------------
|
|
263
|
+
if (appsNeed(apps, "uxp") || appsNeed(apps, "cep")) {
|
|
264
|
+
say("");
|
|
265
|
+
say("Panels:");
|
|
266
|
+
if (apps.includes("photoshop") || apps.includes("premiere"))
|
|
267
|
+
say(" UXP panels load through Adobe's UXP Developer Tool (Add Plugin → manifest → Load):");
|
|
268
|
+
if (apps.includes("photoshop"))
|
|
269
|
+
say(` Photoshop : ${panelUxp}`);
|
|
270
|
+
if (apps.includes("premiere"))
|
|
271
|
+
say(` Premiere : ${panelUxpPpro} (first enable Settings → Plugins → developer mode, restart Premiere)`);
|
|
272
|
+
if (apps.includes("photoshop") || apps.includes("premiere"))
|
|
273
|
+
say(" Then Window → Extensions (UXP) → Brainferno MCP Bridge in each app.");
|
|
274
|
+
if (apps.includes("after_effects") || apps.includes("audition"))
|
|
275
|
+
say(` ${[apps.includes("after_effects") ? "After Effects" : "", apps.includes("audition") ? "Audition" : ""].filter(Boolean).join(" / ")}: Window → Extensions → Brainferno MCP Bridge.`);
|
|
276
|
+
}
|
|
277
|
+
// ---- 7. register with Claude Code ---------------------------------------
|
|
278
|
+
const cmds = mcpAddCommands({ mode, distIndex, port: next.httpPort ?? port, token: next.httpToken ?? "", addresses: lanAddresses() });
|
|
279
|
+
say("");
|
|
280
|
+
say("Claude Code on this computer:");
|
|
281
|
+
say(` ${cmds.local}`);
|
|
282
|
+
const wantRegister = flag("register") || (!flag("yes") && (await ask("Run that now? (y/n)", "y")).toLowerCase().startsWith("y"));
|
|
283
|
+
if (wantRegister) {
|
|
284
|
+
// Replace our own entry, and retire the pre-rename alias in both scopes.
|
|
285
|
+
for (const scope of ["user", "local"]) {
|
|
286
|
+
run(["claude", "mcp", "remove", "--scope", scope, "brainferno"]);
|
|
287
|
+
run(["claude", "mcp", "remove", "--scope", scope, "adobe-cc"]);
|
|
288
|
+
}
|
|
289
|
+
const r2 = run(["claude", "mcp", "add", "--scope", "user", "brainferno", "--", "node", distIndex]);
|
|
290
|
+
if (r2.code === 0)
|
|
291
|
+
ok("registered as 'brainferno' (user scope)");
|
|
292
|
+
else
|
|
293
|
+
warn(`claude mcp add failed: ${r2.out.trim().split("\n")[0] ?? ""} — run the line above yourself`);
|
|
294
|
+
}
|
|
295
|
+
if (mode === "shared") {
|
|
296
|
+
say("");
|
|
297
|
+
say(`Other computers (this machine is "${hostname()}"; the token is in ${userConfigPath()}):`);
|
|
298
|
+
for (const c of cmds.remote)
|
|
299
|
+
say(` ${c}`);
|
|
300
|
+
say(" The wire is plain HTTP: use it on a trusted LAN, a VPN, or Tailscale.");
|
|
301
|
+
}
|
|
302
|
+
say("");
|
|
303
|
+
say("Done. Start or restart the server (in Claude Code: /mcp → brainferno → reconnect) to apply.");
|
|
304
|
+
rl.close();
|
|
305
|
+
}
|
|
306
|
+
main().catch((e) => {
|
|
307
|
+
console.error(e instanceof Error ? e.message : String(e));
|
|
308
|
+
process.exit(1);
|
|
309
|
+
});
|
|
310
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/install/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtI,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACjH,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,QAAQ,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAoB,MAAM,UAAU,CAAC;AAEvR;;;;;;;;;;GAUG;AAEH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AAClD,+EAA+E;AAC/E,qDAAqD;AACrD,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACzG,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;AAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,gBAAgB,EAAE,eAAe,CAAC,CAAC;AAExE,MAAM,IAAI,GAAG,IAAI,GAAG,EAA4B,CAAC;AACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IAC7C,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC;IAC3B,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,SAAS;IAClC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,SAAS;QAAE,IAAI,CAAC,GAAG,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC;SAChC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAE,CAAC;QAAE,IAAI,CAAC,GAAG,CAAC,CAAE,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAE,CAAC,CAAC;;QACpM,IAAI,CAAC,GAAG,CAAC,CAAE,EAAE,IAAI,CAAC,CAAC;AAC1B,CAAC;AACD,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AACjD,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAEnG,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACvC,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC1C,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAE5C,SAAS,GAAG,CAAC,GAAa,EAAE,OAA8B,EAAE;IAC1D,IAAI,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjD,qEAAqE;QACrE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,kCAAkC,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;QAC/E,aAAa,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,wBAAwB,CAAC,CAAC;QAC1H,MAAM,CAAC,GAAG,SAAS,CAAC,YAAY,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,oGAAoG,EAAE,kDAAkD,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9O,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;IAC3E,CAAC;IACD,8GAA8G;IAC9G,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC;IACrE,MAAM,CAAC,GAAG,QAAQ;QAChB,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACvG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3D,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACzC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,6BAA6B,SAAS,8BAA8B,CAAC,CAAC;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,MAAM,GAAG,GAAG,KAAK,EAAE,CAAS,EAAE,GAAW,EAAmB,EAAE;QAC5D,IAAI,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,GAAG,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvD,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,4EAA4E;IAC5E,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAC;IAC5C,IAAI,YAAY;QAAE,EAAE,CAAC,6BAA6B,YAAY,OAAO,OAAO,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC;IAClG,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnG,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,IAAI,CAAC,KAAK,CAAC;YAAE,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;aAC/B,CAAC;YACJ,GAAG,CAAC,EAAE,CAAC,CAAC;YACR,GAAG,CAAC,gDAAgD,CAAC,CAAC;YACtD,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACxK,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,+BAA+B,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAClI,IAAI,GAAG,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,4CAA4C,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,GAAG,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE/F,4EAA4E;IAC5E,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,CAA4B,CAAC;IAClD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,GAAG,CAAC,EAAE,CAAC,CAAC;QACR,GAAG,CAAC,8BAA8B,CAAC,CAAC;QACpC,GAAG,CAAC,mFAAmF,CAAC,CAAC;QACzF,GAAG,CAAC,4EAA4E,CAAC,CAAC;QAClF,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;QAC1C,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IACxC,CAAC;IACD,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,GAAG,CAAC,SAAS,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC;IAEjF,6EAA6E;IAC7E,IAAI,cAAc,GAA8B,SAAS,CAAC;IAC1D,IAAI,cAAc,GAA8B,GAAG,CAAC,iBAAiB,CAAC,IAAI,SAAS,CAAC;IACpF,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACjE,IAAI,MAAM,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACpC,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,EAAE,CAAC,CAAC;YACR,GAAG,CAAC,+FAA+F,CAAC,CAAC;YACrG,GAAG,CAAC,yFAAyF,CAAC,CAAC;YAC/F,GAAG,CAAC,6CAA6C,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC;YACjI,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3D,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;YAC1C,MAAM,GAAG,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG;gBAAE,IAAI,CAAC,6CAA6C,CAAC,CAAC;iBACzD,CAAC;gBACJ,cAAc,GAAG,GAAG,CAAC;gBACrB,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;gBAC/C,IAAI,QAAQ,IAAI,QAAQ,KAAK,2BAA2B;oBAAE,cAAc,GAAG,QAAQ,CAAC;YACtF,CAAC;QACH,CAAC;QACD,MAAM,UAAU,GAAG,cAAc,IAAI,QAAQ,CAAC,cAAc,CAAC;QAC7D,MAAM,UAAU,GAAG,cAAc,IAAI,QAAQ,CAAC,cAAc,IAAI,2BAA2B,CAAC;QAC5F,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAChE,IAAI,KAAK,CAAC,EAAE;gBAAE,EAAE,CAAC,mCAAmC,KAAK,CAAC,UAAU,IAAI,YAAY,OAAO,UAAU,EAAE,CAAC,CAAC;iBACpG,IAAI,KAAK,CAAC,MAAM,KAAK,aAAa;gBAAE,IAAI,CAAC,oCAAoC,UAAU,6DAA6D,CAAC,CAAC;iBACtJ,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,gCAAgC,KAAK,CAAC,MAAM,gEAAgE,CAAC,CAAC;;gBACnJ,IAAI,CAAC,yCAAyC,KAAK,CAAC,MAAM,kBAAkB,CAAC,CAAC;QACrF,CAAC;;YAAM,EAAE,CAAC,sFAAsF,CAAC,CAAC;IACpG,CAAC;IAED,4EAA4E;IAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,IAAI,iBAAiB,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnF,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,EAAE;QAC3C,IAAI;QACJ,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,GAAG,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,IAAI;KACL,CAAC,CAAC;IACH,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,aAAa,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,SAAS,CAAC,cAAc,EAAE,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;IACD,EAAE,CAAC,SAAS,cAAc,EAAE,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,IAAI,CAAC,QAAQ,cAAc,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAE1H,4EAA4E;IAC5E,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IACjF,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC;YACH,SAAS,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACvD,MAAM,QAAQ,GAAG,+BAA+B,CAAC;YACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;YACtD,6FAA6F;YAC7F,KAAK,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,+BAA+B,CAAC,EAAE,CAAC;gBAChE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;gBAC9C,IAAI,CAAC;oBACH,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;oBACxB,IAAI,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;wBAC9E,IAAI,MAAM,GAAG,EAAE,CAAC;wBAChB,IAAI,CAAC;4BACH,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;wBAC3B,CAAC;wBAAC,MAAM,CAAC;4BACP,kEAAkE;wBACpE,CAAC;wBACD,IAAI,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;4BAC5E,MAAM,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;wBAC/C,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,eAAe;gBACjB,CAAC;YACH,CAAC;YACD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC1G,EAAE,CAAC,qBAAqB,MAAM,MAAM,QAAQ,EAAE,CAAC,CAAC;YAChD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBACxC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;gBACjB,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;oBAAE,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACnE,CAAC;YACD,EAAE,CAAC,gEAAgE,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,2BAA2B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,2DAA2D,CAAC,CAAC;aACvE,CAAC;YACJ,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC5C,IAAI,MAAM,KAAK,OAAO;gBAAE,EAAE,CAAC,qCAAqC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,wBAAwB,KAAK,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;iBAC9J,CAAC;gBACJ,IAAI,CAAC;oBACH,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;oBAC3B,EAAE,CAAC,6BAA6B,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,4BAA4B,EAAE,CAAC,CAAC;gBAC7G,CAAC;gBAAC,MAAM,CAAC;oBACP,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;wBACjC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,2BAA2B,CAAC,CAAC;wBACxD,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;wBAC3B,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;wBACpE,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;4BAAE,EAAE,CAAC,6BAA6B,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,4BAA4B,UAAU,CAAC,CAAC;;4BAChI,IAAI,CAAC,mBAAmB,GAAG,wBAAwB,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;oBACrH,CAAC;;wBAAM,IAAI,CAAC,mBAAmB,GAAG,yBAAyB,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;gBACxH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;QAC7E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,EAAE,CAAC,0CAA0C,CAAC,CAAC;aACjE,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvD,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACnF,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;gBAAE,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,kBAAkB,IAAI,CAAC,QAAQ,2BAA2B,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC;;gBAClI,IAAI,CAAC,0BAA0B,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,gBAAgB,MAAM,EAAE,CAAC,CAAC;QACzG,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,EAAE,CAAC,CAAC;QACR,GAAG,CAAC,SAAS,CAAC,CAAC;QACf,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,GAAG,CAAC,sFAAsF,CAAC,CAAC;QACzJ,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,GAAG,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QACnE,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,GAAG,CAAC,mBAAmB,YAAY,yEAAyE,CAAC,CAAC;QAC7I,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,GAAG,CAAC,yEAAyE,CAAC,CAAC;QAC5I,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAC9P,CAAC;IAED,4EAA4E;IAC5E,MAAM,IAAI,GAAG,cAAc,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;IACtI,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,GAAG,CAAC,+BAA+B,CAAC,CAAC;IACrC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACvB,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACjI,IAAI,YAAY,EAAE,CAAC;QACjB,yEAAyE;QACzE,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;YACtC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;YACjE,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QACnG,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC;YAAE,EAAE,CAAC,yCAAyC,CAAC,CAAC;;YAC5D,IAAI,CAAC,0BAA0B,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,gCAAgC,CAAC,CAAC;IAC1G,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,GAAG,CAAC,EAAE,CAAC,CAAC;QACR,GAAG,CAAC,qCAAqC,QAAQ,EAAE,sBAAsB,cAAc,EAAE,IAAI,CAAC,CAAC;QAC/F,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3C,GAAG,CAAC,yEAAyE,CAAC,CAAC;IACjF,CAAC;IACD,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,GAAG,CAAC,6FAA6F,CAAC,CAAC;IACnG,EAAE,CAAC,KAAK,EAAE,CAAC;AACb,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE;IAC1B,OAAO,CAAC,KAAK,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type InstallableApp, type UserConfigFile } from "../config.js";
|
|
2
|
+
export interface AppChoice {
|
|
3
|
+
id: InstallableApp;
|
|
4
|
+
label: string;
|
|
5
|
+
/** Regex on the install folder name (Program Files\Adobe on Windows, /Applications on macOS). */
|
|
6
|
+
folder: RegExp;
|
|
7
|
+
/** What the installer has to set up for it. */
|
|
8
|
+
needs: ("cep" | "uxp" | "illustrator-key" | "ame-ini")[];
|
|
9
|
+
}
|
|
10
|
+
export declare const APP_CHOICES: readonly AppChoice[];
|
|
11
|
+
/** Which of the six are installed, judged by their app folders. */
|
|
12
|
+
export declare function detectInstalledApps(platform?: NodeJS.Platform): InstallableApp[];
|
|
13
|
+
/** "1,3,5", "1 3", "all", or app names → app ids (in canonical order). */
|
|
14
|
+
export declare function pickApps(answer: string, fallback: readonly InstallableApp[]): InstallableApp[];
|
|
15
|
+
export declare function appsNeed(apps: readonly InstallableApp[], need: AppChoice["needs"][number]): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Pure pieces of the installer, kept apart from the interactive CLI so they
|
|
18
|
+
* can be unit-tested: config merging, the Media Encoder ini rewrite, the
|
|
19
|
+
* firewall and registration command lines, and the per-platform paths.
|
|
20
|
+
*/
|
|
21
|
+
export type InstallMode = "local" | "shared";
|
|
22
|
+
export declare const DEFAULT_HTTP_PORT = 7898;
|
|
23
|
+
export declare function randomToken(): string;
|
|
24
|
+
/** Non-internal IPv4 addresses, the ones other machines can reach. */
|
|
25
|
+
export declare function lanAddresses(): string[];
|
|
26
|
+
/**
|
|
27
|
+
* The Illustrator MCP key as the user pasted it: either the bare `ilst_…` key or
|
|
28
|
+
* the whole `claude mcp add … --header "Authorization: Bearer ilst_…" …` line
|
|
29
|
+
* Illustrator shows. Returns null when nothing key-like is in there.
|
|
30
|
+
*/
|
|
31
|
+
export declare function extractIllustratorKey(input: string): string | null;
|
|
32
|
+
/** The endpoint URL from a pasted `claude mcp add` line, if it carries one. */
|
|
33
|
+
export declare function extractIllustratorUrl(input: string): string | null;
|
|
34
|
+
export type IllustratorKeyCheck = {
|
|
35
|
+
ok: true;
|
|
36
|
+
serverName: string | null;
|
|
37
|
+
} | {
|
|
38
|
+
ok: false;
|
|
39
|
+
reason: "not-running" | "refused" | "unexpected";
|
|
40
|
+
detail: string;
|
|
41
|
+
};
|
|
42
|
+
/** Try an MCP initialize against Adobe's Illustrator endpoint with the key. */
|
|
43
|
+
export declare function checkIllustratorKey(url: string, key: string, timeoutMs?: number): Promise<IllustratorKeyCheck>;
|
|
44
|
+
/** Apply the chosen mode to the user config file (other keys untouched). */
|
|
45
|
+
export declare function mergeUserConfig(existing: UserConfigFile, mode: InstallMode, o?: {
|
|
46
|
+
port?: number;
|
|
47
|
+
token?: string;
|
|
48
|
+
host?: string;
|
|
49
|
+
illustratorKey?: string | null;
|
|
50
|
+
illustratorUrl?: string | null;
|
|
51
|
+
apps?: readonly InstallableApp[];
|
|
52
|
+
}): UserConfigFile;
|
|
53
|
+
/**
|
|
54
|
+
* Media Encoder's web-service ini: local pins `ip = 127.0.0.1`; shared leaves
|
|
55
|
+
* the address to the service (it picks a LAN adapter). Other lines are kept.
|
|
56
|
+
*/
|
|
57
|
+
export declare function rewriteAmeIni(ini: string, mode: InstallMode): string;
|
|
58
|
+
export interface PlatformPaths {
|
|
59
|
+
cepExtensionsDir: string;
|
|
60
|
+
csxsDebugCommands: string[][];
|
|
61
|
+
ameIniCandidates: string[];
|
|
62
|
+
}
|
|
63
|
+
export declare function platformPaths(platform: NodeJS.Platform, home: string, appData?: string): PlatformPaths;
|
|
64
|
+
/** Windows Defender Firewall rule for the remote port, private networks only. */
|
|
65
|
+
export declare function firewallCommands(platform: NodeJS.Platform, mode: InstallMode, port: number): string[][];
|
|
66
|
+
/** The `claude mcp add` lines to print/run. */
|
|
67
|
+
export declare function mcpAddCommands(o: {
|
|
68
|
+
mode: InstallMode;
|
|
69
|
+
distIndex: string;
|
|
70
|
+
port: number;
|
|
71
|
+
token: string;
|
|
72
|
+
addresses: string[];
|
|
73
|
+
}): {
|
|
74
|
+
local: string;
|
|
75
|
+
remote: string[];
|
|
76
|
+
};
|