mukae 0.0.0-stage → 0.1.0-beta.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.
@@ -0,0 +1,23 @@
1
+ import type { StoredAgent } from "./config.js";
2
+ export type AgentLaunch = {
3
+ command: string;
4
+ args: readonly string[];
5
+ requires: readonly string[];
6
+ };
7
+ export declare function knownAgentTypes(): readonly string[];
8
+ export declare function launchForAgentType(agentType: string): AgentLaunch | undefined;
9
+ export declare function addAgentConfig(input: {
10
+ agents: readonly StoredAgent[];
11
+ agentType: string;
12
+ name?: string;
13
+ env: Record<string, string>;
14
+ knownTypes: readonly string[];
15
+ }): {
16
+ ok: true;
17
+ agents: StoredAgent[];
18
+ createdName: string;
19
+ } | {
20
+ ok: false;
21
+ message: string;
22
+ };
23
+ export declare function formatAgentConfigList(agents: readonly StoredAgent[]): string;
package/dist/agents.js ADDED
@@ -0,0 +1,64 @@
1
+ import { launchAgentTypes } from "@mukae/contract";
2
+ const builtinAgents = {
3
+ "claude-acp": {
4
+ command: "npx",
5
+ args: ["-y", "@agentclientprotocol/claude-agent-acp@0.89.1"],
6
+ requires: ["claude", "npx"],
7
+ },
8
+ "codex-acp": {
9
+ command: "npx",
10
+ args: ["-y", "@agentclientprotocol/codex-acp@2.2.2"],
11
+ requires: ["codex", "npx"],
12
+ },
13
+ gemini: {
14
+ command: "npx",
15
+ args: ["-y", "@google/gemini-cli@0.63.0", "--acp"],
16
+ requires: ["gemini", "npx"],
17
+ },
18
+ opencode: { command: "opencode", args: ["acp"], requires: ["opencode"] },
19
+ };
20
+ const envNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
21
+ export function knownAgentTypes() {
22
+ return launchAgentTypes;
23
+ }
24
+ export function launchForAgentType(agentType) {
25
+ if (!isLaunchAgentType(agentType))
26
+ return undefined;
27
+ return builtinAgents[agentType];
28
+ }
29
+ function isLaunchAgentType(agentType) {
30
+ return launchAgentTypes.includes(agentType);
31
+ }
32
+ export function addAgentConfig(input) {
33
+ if (!input.knownTypes.includes(input.agentType)) {
34
+ const choices = input.knownTypes.length > 0 ? input.knownTypes.join(", ") : "(none)";
35
+ return { ok: false, message: `Unknown agent type "${input.agentType}". Choose one of: ${choices}.` };
36
+ }
37
+ for (const key of Object.keys(input.env)) {
38
+ if (!envNamePattern.test(key)) {
39
+ return { ok: false, message: `Environment variable "${key}" is not a valid name.` };
40
+ }
41
+ }
42
+ const name = (input.name ?? input.agentType).trim();
43
+ if (name.length === 0 || name.length > 128 || /[\r\n\t]/.test(name)) {
44
+ return { ok: false, message: "Name cannot be empty or contain a line break." };
45
+ }
46
+ if (input.agents.some((agent) => agent.name === name)) {
47
+ return {
48
+ ok: false,
49
+ message: `An agent configuration named "${name}" already exists. Pass --name to add another of this type.`,
50
+ };
51
+ }
52
+ return {
53
+ ok: true,
54
+ createdName: name,
55
+ agents: [...input.agents, { name, agentType: input.agentType, env: { ...input.env } }],
56
+ };
57
+ }
58
+ export function formatAgentConfigList(agents) {
59
+ if (agents.length === 0) {
60
+ return "No agent configurations.\nNext: mukae agent-config create --agent-type opencode\n";
61
+ }
62
+ return `${agents.map((agent) => `${agent.name}\t${agent.agentType}`).join("\n")}\n`;
63
+ }
64
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare function systemDialogCommand(agentType: string, names: readonly string[]): {
2
+ command: string;
3
+ args: string[];
4
+ };
5
+ type DialogRun = (command: string, args: readonly string[], timeoutMs: number) => Promise<{
6
+ stdout: string;
7
+ }>;
8
+ export declare function chooseNameFromSystemDialog(agentType: string, names: readonly string[], timeoutMs: number, run?: DialogRun): Promise<string | undefined>;
9
+ export {};
@@ -0,0 +1,37 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const execFileAsync = promisify(execFile);
4
+ const dialogScript = `on run argv
5
+ set agentType to item 1 of argv
6
+ set configNames to items 2 thru -1 of argv
7
+ set promptText to "Choose a configuration for " & agentType
8
+ set chosen to choose from list configNames with prompt promptText
9
+ if chosen is false then
10
+ return ""
11
+ end if
12
+ return item 1 of chosen
13
+ end run`;
14
+ export function systemDialogCommand(agentType, names) {
15
+ return {
16
+ command: "osascript",
17
+ args: ["-e", dialogScript, "--", agentType, ...names],
18
+ };
19
+ }
20
+ async function runSystemDialog(command, args, timeoutMs) {
21
+ const { stdout } = await execFileAsync(command, args, { encoding: "utf8", timeout: timeoutMs });
22
+ return { stdout };
23
+ }
24
+ export async function chooseNameFromSystemDialog(agentType, names, timeoutMs, run = runSystemDialog) {
25
+ if (names.length === 0)
26
+ return undefined;
27
+ const invocation = systemDialogCommand(agentType, names);
28
+ try {
29
+ const { stdout } = await run(invocation.command, invocation.args, timeoutMs);
30
+ const chosen = stdout.trim();
31
+ return names.includes(chosen) ? chosen : undefined;
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ }
37
+ //# sourceMappingURL=choose-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"choose-name.js","sourceRoot":"","sources":["../src/choose-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,YAAY,GAAG;;;;;;;;;QASb,CAAC;AAET,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,KAAwB;IAExB,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,IAAI,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;KACtD,CAAC;AACJ,CAAC;AAID,KAAK,UAAU,eAAe,CAC5B,OAAe,EACf,IAAuB,EACvB,SAAiB;IAEjB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAChG,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,SAAiB,EACjB,KAAwB,EACxB,SAAiB,EACjB,MAAiB,eAAe;IAEhC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,UAAU,GAAG,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+ import { execFile } from "node:child_process";
3
+ import { homedir } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+ import { promisify } from "node:util";
6
+ import { fileURLToPath } from "node:url";
7
+ import { addAgentConfig, formatAgentConfigList, knownAgentTypes } from "./agents.js";
8
+ import { readGatewayConfig, readGatewayConfigForWrite, writeGatewayConfig } from "./config.js";
9
+ import { installLocalGateway } from "./install.js";
10
+ import { readLoginPath } from "./launch-path.js";
11
+ import { openGateway } from "./open-gateway.js";
12
+ import { registerLocalGateway } from "./register.js";
13
+ import { runCli } from "./run-cli.js";
14
+ import { runtimeDependencies } from "./runtime.js";
15
+ const execFileAsync = promisify(execFile);
16
+ const cliPath = fileURLToPath(new URL("./cli.js", import.meta.url));
17
+ const packageRoot = join(dirname(cliPath), "..");
18
+ const launcherBinaryPath = join(packageRoot, "launcher", "mukae-launcher");
19
+ const applicationSupportDirectory = join(homedir(), "Library", "Application Support", "mukae");
20
+ const launchServicesRegister = "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister";
21
+ const registration = {
22
+ homeDirectory: homedir(),
23
+ applicationSupportDirectory,
24
+ nodePath: process.execPath,
25
+ launcherBinaryPath,
26
+ platform: process.platform,
27
+ registerApplication: async (applicationPath) => {
28
+ await execFileAsync(launchServicesRegister, ["-f", applicationPath]);
29
+ },
30
+ signApplication: async (applicationPath) => {
31
+ await execFileAsync("xattr", ["-cr", applicationPath]).catch(() => undefined);
32
+ await execFileAsync("codesign", ["-s", "-", "--force", applicationPath]);
33
+ },
34
+ inform: (message) => console.log(message),
35
+ warn: (message) => console.error(message),
36
+ };
37
+ const result = await runCli(process.argv.slice(2), {
38
+ install: () => installLocalGateway({
39
+ ...registration,
40
+ sourceDistDirectory: dirname(cliPath),
41
+ pathValue: readLoginPath(),
42
+ packages: runtimeDependencies(),
43
+ }),
44
+ register: () => registerLocalGateway({ ...registration, cliPath }),
45
+ open: (launchUrl) => openGateway(launchUrl),
46
+ listAgentConfigs: async () => {
47
+ const config = await readGatewayConfig();
48
+ if (config.warning) {
49
+ console.error(config.warning);
50
+ return 1;
51
+ }
52
+ process.stdout.write(formatAgentConfigList(config.agents));
53
+ return 0;
54
+ },
55
+ createAgentConfig: async (input) => {
56
+ const config = await readGatewayConfigForWrite();
57
+ if (!config.ok) {
58
+ console.error(config.message);
59
+ return 1;
60
+ }
61
+ const added = addAgentConfig({
62
+ agents: config.agents,
63
+ agentType: input.agentType,
64
+ name: input.name,
65
+ env: input.env,
66
+ knownTypes: knownAgentTypes(),
67
+ });
68
+ if (!added.ok) {
69
+ console.error(added.message);
70
+ return 1;
71
+ }
72
+ await writeGatewayConfig({ agents: added.agents });
73
+ console.log(`Created agent configuration "${added.createdName}" (${input.agentType}).`);
74
+ return 0;
75
+ },
76
+ });
77
+ if (result.showUsage) {
78
+ console.error(`Usage:
79
+ mukae
80
+ mukae register
81
+ mukae open <mukae-url>
82
+ mukae agent-config list
83
+ mukae agent-config create --agent-type <type> [--name <name>] [--env KEY=VALUE]`);
84
+ }
85
+ if (result.exitCode !== 0)
86
+ process.exitCode = result.exitCode;
87
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export type StoredAgent = {
2
+ name: string;
3
+ agentType: string;
4
+ env: Record<string, string>;
5
+ };
6
+ export type GatewayConfig = {
7
+ agents: StoredAgent[];
8
+ };
9
+ export declare function configFilePath(homeDirectory?: string): string;
10
+ export declare function parseGatewayConfig(value: unknown): GatewayConfig;
11
+ export declare function configText(config: GatewayConfig): string;
12
+ export declare function defaultConfigText(): string;
13
+ export declare function readGatewayConfig(homeDirectory?: string): Promise<{
14
+ agents: StoredAgent[];
15
+ warning?: string;
16
+ }>;
17
+ export declare function readGatewayConfigForWrite(homeDirectory?: string): Promise<{
18
+ ok: true;
19
+ agents: StoredAgent[];
20
+ } | {
21
+ ok: false;
22
+ message: string;
23
+ }>;
24
+ export declare function writeGatewayConfig(config: GatewayConfig, homeDirectory?: string): Promise<void>;
25
+ export declare function writeDefaultConfigIfMissing(homeDirectory?: string): Promise<void>;
package/dist/config.js ADDED
@@ -0,0 +1,128 @@
1
+ import { isAgentType } from "@mukae/contract";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+ const envNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
6
+ export function configFilePath(homeDirectory = homedir()) {
7
+ return join(homeDirectory, ".config", "mukae", "config.json");
8
+ }
9
+ export function parseGatewayConfig(value) {
10
+ const record = typeof value === "object" && value !== null ? value : {};
11
+ const items = Array.isArray(record.agents) ? record.agents : [];
12
+ const agents = [];
13
+ for (const item of items) {
14
+ const agent = parseStoredAgent(item);
15
+ if (agent && !agents.some((existing) => existing.name === agent.name))
16
+ agents.push(agent);
17
+ }
18
+ return { agents };
19
+ }
20
+ export function configText(config) {
21
+ return `${JSON.stringify({ agents: config.agents }, null, 2)}\n`;
22
+ }
23
+ export function defaultConfigText() {
24
+ return configText({ agents: [] });
25
+ }
26
+ export async function readGatewayConfig(homeDirectory = homedir()) {
27
+ const loaded = await loadGatewayConfig(homeDirectory);
28
+ const failure = loadFailure(loaded);
29
+ if (failure)
30
+ return { agents: [], warning: failure };
31
+ if (loaded.kind === "parsed")
32
+ return { agents: loaded.config.agents };
33
+ return { agents: [] };
34
+ }
35
+ export async function readGatewayConfigForWrite(homeDirectory = homedir()) {
36
+ const loaded = await loadGatewayConfig(homeDirectory);
37
+ const failure = loadFailure(loaded);
38
+ if (failure)
39
+ return { ok: false, message: failure };
40
+ if (loaded.kind === "parsed" && loaded.dropsAgents) {
41
+ return { ok: false, message: `Cannot rewrite ${loaded.path} without dropping agent entries.` };
42
+ }
43
+ return { ok: true, agents: loaded.kind === "parsed" ? loaded.config.agents : [] };
44
+ }
45
+ export async function writeGatewayConfig(config, homeDirectory = homedir()) {
46
+ const path = configFilePath(homeDirectory);
47
+ await mkdir(dirname(path), { recursive: true });
48
+ await writeFile(path, configText(config), "utf8");
49
+ }
50
+ export async function writeDefaultConfigIfMissing(homeDirectory = homedir()) {
51
+ const path = configFilePath(homeDirectory);
52
+ try {
53
+ await readFile(path, "utf8");
54
+ }
55
+ catch {
56
+ await mkdir(dirname(path), { recursive: true });
57
+ await writeFile(path, defaultConfigText(), "utf8");
58
+ }
59
+ }
60
+ async function loadGatewayConfig(homeDirectory) {
61
+ const path = configFilePath(homeDirectory);
62
+ let text;
63
+ try {
64
+ text = await readFile(path, "utf8");
65
+ }
66
+ catch (error) {
67
+ if (isMissingFile(error))
68
+ return { kind: "missing" };
69
+ return { kind: "unreadable", path };
70
+ }
71
+ try {
72
+ const value = JSON.parse(text);
73
+ return {
74
+ kind: "parsed",
75
+ path,
76
+ config: parseGatewayConfig(value),
77
+ dropsAgents: rewriteWouldDropAgents(value),
78
+ };
79
+ }
80
+ catch {
81
+ return { kind: "invalid", path };
82
+ }
83
+ }
84
+ function loadFailure(loaded) {
85
+ if (loaded.kind === "unreadable")
86
+ return `Cannot read ${loaded.path}.`;
87
+ if (loaded.kind === "invalid")
88
+ return `Cannot read ${loaded.path} as JSON.`;
89
+ return undefined;
90
+ }
91
+ function rewriteWouldDropAgents(value) {
92
+ if (typeof value !== "object" || value === null || Array.isArray(value))
93
+ return true;
94
+ const agents = value.agents;
95
+ if (!Array.isArray(agents))
96
+ return true;
97
+ return parseGatewayConfig(value).agents.length !== agents.length;
98
+ }
99
+ function isMissingFile(error) {
100
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
101
+ }
102
+ function parseStoredAgent(value) {
103
+ if (typeof value !== "object" || value === null)
104
+ return undefined;
105
+ const record = value;
106
+ if (typeof record.name !== "string" || record.name.trim().length === 0)
107
+ return undefined;
108
+ if (typeof record.agentType !== "string" || !isAgentType(record.agentType))
109
+ return undefined;
110
+ const env = parseEnv(record.env);
111
+ if (!env)
112
+ return undefined;
113
+ return { name: record.name, agentType: record.agentType, env };
114
+ }
115
+ function parseEnv(value) {
116
+ if (value === undefined)
117
+ return {};
118
+ if (typeof value !== "object" || value === null || Array.isArray(value))
119
+ return undefined;
120
+ const env = {};
121
+ for (const [key, item] of Object.entries(value)) {
122
+ if (!envNamePattern.test(key) || typeof item !== "string")
123
+ return undefined;
124
+ env[key] = item;
125
+ }
126
+ return env;
127
+ }
128
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const maxPendingAgentChars = 1048576;
2
+ export declare function webSocketTextToAgentLine(text: string): string;
3
+ export declare function consumeAgentChunk(pending: string, chunk: string): {
4
+ pending: string;
5
+ frames: string[];
6
+ overflow: boolean;
7
+ };
package/dist/frames.js ADDED
@@ -0,0 +1,15 @@
1
+ export const maxPendingAgentChars = 1_048_576;
2
+ export function webSocketTextToAgentLine(text) {
3
+ return text.endsWith("\n") ? text : `${text}\n`;
4
+ }
5
+ export function consumeAgentChunk(pending, chunk) {
6
+ const parts = (pending + chunk).split("\n");
7
+ const remainder = parts.pop() ?? "";
8
+ const frames = parts
9
+ .map((line) => (line.endsWith("\r") ? line.slice(0, -1) : line))
10
+ .filter((line) => line.length > 0);
11
+ if (remainder.length > maxPendingAgentChars)
12
+ return { pending: "", frames, overflow: true };
13
+ return { pending: remainder, frames, overflow: false };
14
+ }
15
+ //# sourceMappingURL=frames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.js","sourceRoot":"","sources":["../src/frames.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAE9C,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,KAAa;IAEb,MAAM,KAAK,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,KAAK;SACjB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAC/D,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrC,IAAI,SAAS,CAAC,MAAM,GAAG,oBAAoB;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC5F,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACzD,CAAC"}
package/dist/gate.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { GatewayStatus } from "@mukae/contract";
2
+ export declare function admitConnection(input: {
3
+ expectedNonce: string;
4
+ expectedOrigin: string;
5
+ nonce: string | null;
6
+ origin: string | null;
7
+ }): {
8
+ accept: true;
9
+ } | {
10
+ accept: false;
11
+ };
12
+ export declare function statusForOrigin(input: {
13
+ expectedOrigin: string;
14
+ origin: string | null;
15
+ gatewayStatus: GatewayStatus;
16
+ }): GatewayStatus | "rejected";
package/dist/gate.js ADDED
@@ -0,0 +1,12 @@
1
+ export function admitConnection(input) {
2
+ if (input.nonce === input.expectedNonce && input.origin === input.expectedOrigin) {
3
+ return { accept: true };
4
+ }
5
+ return { accept: false };
6
+ }
7
+ export function statusForOrigin(input) {
8
+ if (input.origin !== input.expectedOrigin)
9
+ return "rejected";
10
+ return input.gatewayStatus;
11
+ }
12
+ //# sourceMappingURL=gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAAC,KAK/B;IACC,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC;QACjF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAI/B;IACC,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,cAAc;QAAE,OAAO,UAAU,CAAC;IAC7D,OAAO,KAAK,CAAC,aAAa,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type ProbeOutcome } from "./probe.js";
2
+ export declare function installLocalGateway(input: {
3
+ homeDirectory: string;
4
+ applicationSupportDirectory: string;
5
+ sourceDistDirectory: string;
6
+ nodePath: string;
7
+ launcherBinaryPath: string;
8
+ platform: NodeJS.Platform;
9
+ pathValue: string;
10
+ packages: readonly {
11
+ name: string;
12
+ directory: string;
13
+ }[];
14
+ registerApplication?: (applicationPath: string) => Promise<void>;
15
+ signApplication?: (applicationPath: string) => Promise<void>;
16
+ probeAgentType?: (agentType: string, pathValue: string) => Promise<ProbeOutcome>;
17
+ inform?: (message: string) => void;
18
+ warn?: (message: string) => void;
19
+ }): Promise<void>;
@@ -0,0 +1,49 @@
1
+ import { knownAgentTypes } from "./agents.js";
2
+ import { readGatewayConfigForWrite, writeGatewayConfig } from "./config.js";
3
+ import { formatInstallReport, planAgentConfigurations, probeInstalledAgent } from "./probe.js";
4
+ import { registerLocalGateway } from "./register.js";
5
+ import { copyGatewayRuntime, runtimeDirectory } from "./runtime.js";
6
+ export async function installLocalGateway(input) {
7
+ const cliPath = await copyGatewayRuntime({
8
+ sourceDistDirectory: input.sourceDistDirectory,
9
+ destinationRoot: runtimeDirectory(input.applicationSupportDirectory),
10
+ packages: input.packages,
11
+ });
12
+ await registerLocalGateway({
13
+ homeDirectory: input.homeDirectory,
14
+ applicationSupportDirectory: input.applicationSupportDirectory,
15
+ nodePath: input.nodePath,
16
+ cliPath,
17
+ launcherBinaryPath: input.launcherBinaryPath,
18
+ platform: input.platform,
19
+ registerApplication: input.registerApplication,
20
+ signApplication: input.signApplication,
21
+ warn: input.warn,
22
+ reportNextStep: false,
23
+ });
24
+ const probe = input.probeAgentType ?? probeInstalledAgent;
25
+ const config = await readGatewayConfigForWrite(input.homeDirectory);
26
+ if (!config.ok) {
27
+ input.warn?.(config.message);
28
+ input.inform?.(`Installed mukae.\n${config.message}\n`);
29
+ return;
30
+ }
31
+ const probes = [];
32
+ for (const agentType of knownAgentTypes()) {
33
+ if (config.agents.some((agent) => agent.agentType === agentType)) {
34
+ probes.push({ agentType, outcome: { status: "already" } });
35
+ continue;
36
+ }
37
+ probes.push({ agentType, outcome: await probe(agentType, input.pathValue) });
38
+ }
39
+ const planned = planAgentConfigurations({
40
+ agents: config.agents,
41
+ probes,
42
+ knownTypes: knownAgentTypes(),
43
+ });
44
+ if (planned.agents.length !== config.agents.length) {
45
+ await writeGatewayConfig({ agents: planned.agents }, input.homeDirectory);
46
+ }
47
+ input.inform?.(formatInstallReport(planned.lines, planned.needsSignIn));
48
+ }
49
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,mBAAmB,EAAqB,MAAM,YAAY,CAAC;AAClH,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEpE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAczC;IACC,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC;QACvC,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;QAC9C,eAAe,EAAE,gBAAgB,CAAC,KAAK,CAAC,2BAA2B,CAAC;QACpE,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC,CAAC;IACH,MAAM,oBAAoB,CAAC;QACzB,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,2BAA2B,EAAE,KAAK,CAAC,2BAA2B;QAC9D,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO;QACP,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;QAC9C,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,cAAc,EAAE,KAAK;KACtB,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,IAAI,mBAAmB,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7B,KAAK,CAAC,MAAM,EAAE,CAAC,qBAAqB,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAA2E,EAAE,CAAC;IAC1F,KAAK,MAAM,SAAS,IAAI,eAAe,EAAE,EAAE,CAAC;QAC1C,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,CAAC;YACjE,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;YAC3D,SAAS;QACX,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,OAAO,GAAG,uBAAuB,CAAC;QACtC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM;QACN,UAAU,EAAE,eAAe,EAAE;KAC9B,CAAC,CAAC;IACH,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnD,MAAM,kBAAkB,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAC5E,CAAC;IACD,KAAK,CAAC,MAAM,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function commandOnPath(command: string, pathValue: string): string;
2
+ export declare function firstMissingCommand(commands: readonly string[], pathValue: string): string | undefined;
3
+ export declare function parseLoginPath(output: string): string;
4
+ export declare function readLoginPath(): string;
@@ -0,0 +1,55 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { accessSync, constants } from "node:fs";
3
+ import { delimiter, join } from "node:path";
4
+ export function commandOnPath(command, pathValue) {
5
+ if (command.includes("/") || command.includes("\\"))
6
+ return command;
7
+ for (const directory of pathValue.split(delimiter)) {
8
+ if (!directory)
9
+ continue;
10
+ const candidate = join(directory, command);
11
+ try {
12
+ accessSync(candidate, constants.X_OK);
13
+ return candidate;
14
+ }
15
+ catch {
16
+ continue;
17
+ }
18
+ }
19
+ return command;
20
+ }
21
+ export function firstMissingCommand(commands, pathValue) {
22
+ for (const command of commands) {
23
+ if (command.includes("/") || command.includes("\\"))
24
+ continue;
25
+ if (commandOnPath(command, pathValue) === command)
26
+ return command;
27
+ }
28
+ return undefined;
29
+ }
30
+ export function parseLoginPath(output) {
31
+ const line = output
32
+ .split("\n")
33
+ .map((item) => item.trim())
34
+ .filter((item) => item.includes(delimiter) && item.split(delimiter).some((directory) => directory.startsWith("/")))
35
+ .at(-1);
36
+ return line ?? "";
37
+ }
38
+ let cachedLoginPath;
39
+ export function readLoginPath() {
40
+ if (cachedLoginPath !== undefined)
41
+ return cachedLoginPath;
42
+ try {
43
+ const output = execFileSync("/bin/zsh", ["-lic", "builtin print -r -- $PATH"], {
44
+ encoding: "utf8",
45
+ timeout: 20_000,
46
+ stdio: ["ignore", "pipe", "ignore"],
47
+ });
48
+ cachedLoginPath = parseLoginPath(output);
49
+ }
50
+ catch {
51
+ cachedLoginPath = "";
52
+ }
53
+ return cachedLoginPath;
54
+ }
55
+ //# sourceMappingURL=launch-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-path.js","sourceRoot":"","sources":["../src/launch-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,SAAiB;IAC9D,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IACpE,KAAK,MAAM,SAAS,IAAI,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC,SAAS;YAAE,SAAS;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC;YACH,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YACtC,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAA2B,EAAE,SAAiB;IAChF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QAC9D,IAAI,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC;IACpE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,MAAM,IAAI,GAAG,MAAM;SAChB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;SAClH,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACV,OAAO,IAAI,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,IAAI,eAAmC,CAAC;AAExC,MAAM,UAAU,aAAa;IAC3B,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,2BAA2B,CAAC,EAAE;YAC7E,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,MAAM;YACf,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,GAAG,EAAE,CAAC;IACvB,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type GatewayServer } from "./server.js";
2
+ export type GatewaySessionOptions = {
3
+ homeDirectory?: string;
4
+ port?: number;
5
+ idleTimeoutMs?: number;
6
+ chooseName?: (agentType: string, names: readonly string[]) => Promise<string | undefined>;
7
+ commandPath?: string;
8
+ warn?: (message: string) => void;
9
+ };
10
+ export declare function openGateway(launchUrl: string, options?: GatewaySessionOptions): Promise<void>;
11
+ export declare function startGatewaySession(launchUrl: string, options?: GatewaySessionOptions): Promise<GatewayServer>;