aai-gateway 0.1.2 → 0.1.4
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/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { b as createDesktopDiscovery, d as createGatewayServer, l as logger } from "./server-
|
|
3
|
-
const VERSION = "0.1.
|
|
2
|
+
import { b as createDesktopDiscovery, d as createGatewayServer, l as logger } from "./server-wlJ31cFg.js";
|
|
3
|
+
const VERSION = "0.1.4";
|
|
4
4
|
function parseArgs(args) {
|
|
5
5
|
return {
|
|
6
6
|
scan: args.includes("--scan"),
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { createGatewayServer } from './mcp/server.js';\nimport { createDesktopDiscovery } from './discovery/index.js';\nimport { logger } from './utils/logger.js';\n\nconst VERSION = '0.1.
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { createGatewayServer } from './mcp/server.js';\nimport { createDesktopDiscovery } from './discovery/index.js';\nimport { logger } from './utils/logger.js';\n\nconst VERSION = '0.1.4';\n\ninterface CliOptions {\n scan: boolean;\n dev: boolean;\n version: boolean;\n help: boolean;\n}\n\nfunction parseArgs(args: string[]): CliOptions {\n return {\n scan: args.includes('--scan'),\n dev: args.includes('--dev'),\n version: args.includes('--version'),\n help: args.includes('--help') || args.includes('-h'),\n };\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const options = parseArgs(args);\n\n if (options.help) {\n console.log(`\nAAI Gateway - Agent App Interface Protocol Gateway\n\nUsage:\n aai-gateway [options]\n\nOptions:\n --scan Scan for AAI-enabled desktop apps and exit\n --dev Enable development mode (scan Xcode build directories)\n --version Show version\n --help, -h Show this help message\n\nEnvironment Variables:\n AAI_LOG_LEVEL Log level (debug, info, warn, error)\n\nDevelopment Mode:\n When --dev is used with --scan or MCP server, the gateway will also scan\n Xcode build directories for apps in development:\n ~/Library/Developer/Xcode/DerivedData/*/Build/Products/Debug\n ~/Library/Developer/Xcode/DerivedData/*/Build/Products/Release\n\nDefault mode starts an MCP server over stdio.\n`);\n process.exit(0);\n }\n\n if (options.version) {\n console.log(`aai-gateway v${VERSION}`);\n process.exit(0);\n }\n\n if (options.scan) {\n try {\n const discovery = createDesktopDiscovery();\n const apps = await discovery.scan({ devMode: options.dev });\n\n console.log('\\nDiscovered AAI-enabled Applications:');\n console.log('=====================================\\n');\n\n if (apps.length === 0) {\n console.log('No applications found.');\n if (options.dev) {\n console.log('Apps must ship /Applications/<Name>.app/Contents/Resources/aai.json');\n console.log(\n 'Or in Xcode build: ~/Library/Developer/Xcode/DerivedData/*/Build/Products/Debug/<Name>.app/Contents/Resources/aai.json'\n );\n } else {\n console.log('Apps must ship /Applications/<Name>.app/Contents/Resources/aai.json');\n console.log('Tip: Use --dev to also scan Xcode build directories.');\n }\n } else {\n for (const app of apps) {\n console.log(` ${app.appId}`);\n console.log(` Name: ${app.name}`);\n console.log(` Bundle: ${app.bundlePath}`);\n console.log(` Description: ${app.description}`);\n console.log('');\n }\n console.log(`Total: ${apps.length} application(s)`);\n if (options.dev) {\n console.log('(Development mode: scanned Xcode build directories)');\n }\n }\n } catch (err) {\n console.error('Scan failed:', err);\n process.exit(1);\n }\n process.exit(0);\n }\n\n // Default: start MCP server\n try {\n const gateway = await createGatewayServer({ devMode: options.dev });\n await gateway.start();\n } catch (err) {\n logger.fatal({ err }, 'Failed to start AAI Gateway');\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n});\n"],"names":[],"mappings":";;AAMA,MAAM,UAAU;AAShB,SAAS,UAAU,MAA4B;AAC7C,SAAO;AAAA,IACL,MAAM,KAAK,SAAS,QAAQ;AAAA,IAC5B,KAAK,KAAK,SAAS,OAAO;AAAA,IAC1B,SAAS,KAAK,SAAS,WAAW;AAAA,IAClC,MAAM,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI;AAAA,EAAA;AAEvD;AAEA,eAAe,OAAsB;AACnC,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,QAAM,UAAU,UAAU,IAAI;AAE9B,MAAI,QAAQ,MAAM;AAChB,YAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAsBf;AACG,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAQ,SAAS;AACnB,YAAQ,IAAI,gBAAgB,OAAO,EAAE;AACrC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAQ,MAAM;AAChB,QAAI;AACF,YAAM,YAAY,uBAAA;AAClB,YAAM,OAAO,MAAM,UAAU,KAAK,EAAE,SAAS,QAAQ,KAAK;AAE1D,cAAQ,IAAI,wCAAwC;AACpD,cAAQ,IAAI,yCAAyC;AAErD,UAAI,KAAK,WAAW,GAAG;AACrB,gBAAQ,IAAI,wBAAwB;AACpC,YAAI,QAAQ,KAAK;AACf,kBAAQ,IAAI,qEAAqE;AACjF,kBAAQ;AAAA,YACN;AAAA,UAAA;AAAA,QAEJ,OAAO;AACL,kBAAQ,IAAI,qEAAqE;AACjF,kBAAQ,IAAI,sDAAsD;AAAA,QACpE;AAAA,MACF,OAAO;AACL,mBAAW,OAAO,MAAM;AACtB,kBAAQ,IAAI,KAAK,IAAI,KAAK,EAAE;AAC5B,kBAAQ,IAAI,aAAa,IAAI,IAAI,EAAE;AACnC,kBAAQ,IAAI,eAAe,IAAI,UAAU,EAAE;AAC3C,kBAAQ,IAAI,oBAAoB,IAAI,WAAW,EAAE;AACjD,kBAAQ,IAAI,EAAE;AAAA,QAChB;AACA,gBAAQ,IAAI,UAAU,KAAK,MAAM,iBAAiB;AAClD,YAAI,QAAQ,KAAK;AACf,kBAAQ,IAAI,qDAAqD;AAAA,QACnE;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,gBAAgB,GAAG;AACjC,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI;AACF,UAAM,UAAU,MAAM,oBAAoB,EAAE,SAAS,QAAQ,KAAK;AAClE,UAAM,QAAQ,MAAA;AAAA,EAChB,SAAS,KAAK;AACZ,WAAO,MAAM,EAAE,IAAA,GAAO,6BAA6B;AACnD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,OAAO,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,gBAAgB,GAAG;AACjC,UAAQ,KAAK,CAAC;AAChB,CAAC;"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import require$$0 from "ajv";
|
|
2
2
|
import process$1 from "node:process";
|
|
3
3
|
import pino from "pino";
|
|
4
|
-
import { exec, execFile } from "node:child_process";
|
|
4
|
+
import { exec, execFile, execFileSync } from "node:child_process";
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
6
|
import { readFile, mkdir, writeFile } from "node:fs/promises";
|
|
7
7
|
import { dirname, join } from "node:path";
|
|
@@ -8115,27 +8115,105 @@ function createSecureStorage() {
|
|
|
8115
8115
|
throw new AaiError("NOT_IMPLEMENTED", "Windows secure storage not yet supported");
|
|
8116
8116
|
}
|
|
8117
8117
|
}
|
|
8118
|
+
function getSystemLocale() {
|
|
8119
|
+
try {
|
|
8120
|
+
const output = execFileSync(
|
|
8121
|
+
"defaults",
|
|
8122
|
+
["read", "-g", "AppleLocale"],
|
|
8123
|
+
{ encoding: "utf-8", timeout: 1e3 }
|
|
8124
|
+
).trim();
|
|
8125
|
+
return normalizeLocale(output);
|
|
8126
|
+
} catch {
|
|
8127
|
+
const envLocale = process.env.LANG || process.env.LC_ALL || process.env.LC_MESSAGES || "en";
|
|
8128
|
+
return normalizeLocale(envLocale);
|
|
8129
|
+
}
|
|
8130
|
+
}
|
|
8131
|
+
function normalizeLocale(locale) {
|
|
8132
|
+
const lower = locale.toLowerCase().replace(/[^a-z-]/g, "");
|
|
8133
|
+
if (lower.startsWith("zh-hans") || lower === "zh-cn" || lower === "zh_cn") {
|
|
8134
|
+
return "zh-CN";
|
|
8135
|
+
}
|
|
8136
|
+
if (lower.startsWith("zh-hant") || lower === "zh-tw" || lower === "zh_tw" || lower === "zh-hk" || lower === "zh_hk") {
|
|
8137
|
+
return "zh-TW";
|
|
8138
|
+
}
|
|
8139
|
+
if (lower.startsWith("zh")) {
|
|
8140
|
+
return "zh-CN";
|
|
8141
|
+
}
|
|
8142
|
+
return "en";
|
|
8143
|
+
}
|
|
8144
|
+
const en = {
|
|
8145
|
+
dialogTitle: "⚠️ Tool Authorization Request",
|
|
8146
|
+
appLabel: "App",
|
|
8147
|
+
requestPermissionLabel: "Agent requests permission to use:",
|
|
8148
|
+
parametersLabel: "Parameters:",
|
|
8149
|
+
noParameters: "(no parameters)",
|
|
8150
|
+
buttonDeny: "Deny",
|
|
8151
|
+
buttonAuthorizeTool: "Authorize Tool",
|
|
8152
|
+
buttonAuthorizeAll: "Authorize All",
|
|
8153
|
+
rememberDialogTitle: "Remember this decision for '{toolName}'?",
|
|
8154
|
+
rememberButtonNo: "No",
|
|
8155
|
+
rememberButtonYes: "Yes"
|
|
8156
|
+
};
|
|
8157
|
+
const zhCN = {
|
|
8158
|
+
dialogTitle: "⚠️ 工具授权请求",
|
|
8159
|
+
appLabel: "应用",
|
|
8160
|
+
requestPermissionLabel: "智能体请求使用:",
|
|
8161
|
+
parametersLabel: "参数:",
|
|
8162
|
+
noParameters: "(无参数)",
|
|
8163
|
+
buttonDeny: "拒绝",
|
|
8164
|
+
buttonAuthorizeTool: "授权工具",
|
|
8165
|
+
buttonAuthorizeAll: "全部授权",
|
|
8166
|
+
rememberDialogTitle: "记住对「{toolName}」的授权决定?",
|
|
8167
|
+
rememberButtonNo: "否",
|
|
8168
|
+
rememberButtonYes: "是"
|
|
8169
|
+
};
|
|
8170
|
+
const zhTW = {
|
|
8171
|
+
dialogTitle: "⚠️ 工具授權請求",
|
|
8172
|
+
appLabel: "應用程式",
|
|
8173
|
+
requestPermissionLabel: "智慧代理請求使用:",
|
|
8174
|
+
parametersLabel: "參數:",
|
|
8175
|
+
noParameters: "(無參數)",
|
|
8176
|
+
buttonDeny: "拒絕",
|
|
8177
|
+
buttonAuthorizeTool: "授權工具",
|
|
8178
|
+
buttonAuthorizeAll: "全部授權",
|
|
8179
|
+
rememberDialogTitle: "記住對「{toolName}」的授權決定?",
|
|
8180
|
+
rememberButtonNo: "否",
|
|
8181
|
+
rememberButtonYes: "是"
|
|
8182
|
+
};
|
|
8183
|
+
const translations = {
|
|
8184
|
+
en,
|
|
8185
|
+
"zh-CN": zhCN,
|
|
8186
|
+
"zh-TW": zhTW
|
|
8187
|
+
};
|
|
8188
|
+
function getTranslations(locale) {
|
|
8189
|
+
return translations[locale] ?? translations.en;
|
|
8190
|
+
}
|
|
8118
8191
|
const execFileAsync$2 = promisify(execFile);
|
|
8119
|
-
function buildParamLines(parameters) {
|
|
8192
|
+
function buildParamLines(parameters, noParamsText) {
|
|
8120
8193
|
const props = parameters.properties ?? {};
|
|
8121
|
-
return Object.entries(props).map(([k, v]) => `• ${k}${v.description ? `: ${v.description}` : ""}`).join("\\n") ||
|
|
8194
|
+
return Object.entries(props).map(([k, v]) => `• ${k}${v.description ? `: ${v.description}` : ""}`).join("\\n") || noParamsText;
|
|
8122
8195
|
}
|
|
8123
8196
|
class MacOSConsentDialog {
|
|
8197
|
+
locale;
|
|
8198
|
+
constructor() {
|
|
8199
|
+
this.locale = getSystemLocale();
|
|
8200
|
+
}
|
|
8124
8201
|
async show(info) {
|
|
8125
|
-
const
|
|
8202
|
+
const t = getTranslations(this.locale);
|
|
8203
|
+
const paramLines = buildParamLines(info.parameters, t.noParameters);
|
|
8126
8204
|
const authScript = `
|
|
8127
|
-
set dialogText to "
|
|
8205
|
+
set dialogText to "${t.dialogTitle}
|
|
8128
8206
|
|
|
8129
|
-
|
|
8207
|
+
${t.appLabel}: ${info.appName} (${info.appId})
|
|
8130
8208
|
|
|
8131
|
-
|
|
8209
|
+
${t.requestPermissionLabel}
|
|
8132
8210
|
|
|
8133
8211
|
${info.toolName}
|
|
8134
8212
|
${info.toolDescription}
|
|
8135
8213
|
|
|
8136
|
-
|
|
8214
|
+
${t.parametersLabel}
|
|
8137
8215
|
${paramLines}"
|
|
8138
|
-
set result to display dialog dialogText buttons {"
|
|
8216
|
+
set result to display dialog dialogText buttons {"${t.buttonDeny}", "${t.buttonAuthorizeTool}", "${t.buttonAuthorizeAll}"} default button "${t.buttonAuthorizeTool}" with icon caution
|
|
8139
8217
|
set btn to button returned of result
|
|
8140
8218
|
return btn
|
|
8141
8219
|
`.trim();
|
|
@@ -8143,9 +8221,9 @@ return btn
|
|
|
8143
8221
|
try {
|
|
8144
8222
|
const { stdout } = await execFileAsync$2("osascript", ["-e", authScript]);
|
|
8145
8223
|
const btn = stdout.trim();
|
|
8146
|
-
if (btn ===
|
|
8224
|
+
if (btn === t.buttonAuthorizeAll) {
|
|
8147
8225
|
decision = "all";
|
|
8148
|
-
} else if (btn ===
|
|
8226
|
+
} else if (btn === t.buttonAuthorizeTool) {
|
|
8149
8227
|
decision = "tool";
|
|
8150
8228
|
} else {
|
|
8151
8229
|
decision = "deny";
|
|
@@ -8158,12 +8236,13 @@ return btn
|
|
|
8158
8236
|
}
|
|
8159
8237
|
let remember = false;
|
|
8160
8238
|
try {
|
|
8239
|
+
const rememberMessage = t.rememberDialogTitle.replace("{toolName}", info.toolName);
|
|
8161
8240
|
const rememberScript = `
|
|
8162
|
-
set r to display dialog "
|
|
8241
|
+
set r to display dialog "${rememberMessage}" buttons {"${t.rememberButtonNo}", "${t.rememberButtonYes}"} default button "${t.rememberButtonYes}"
|
|
8163
8242
|
return button returned of r
|
|
8164
8243
|
`.trim();
|
|
8165
8244
|
const { stdout: remOut } = await execFileAsync$2("osascript", ["-e", rememberScript]);
|
|
8166
|
-
remember = remOut.trim() ===
|
|
8245
|
+
remember = remOut.trim() === t.rememberButtonYes;
|
|
8167
8246
|
} catch {
|
|
8168
8247
|
remember = false;
|
|
8169
8248
|
}
|
|
@@ -8702,4 +8781,4 @@ export {
|
|
|
8702
8781
|
parseAaiJson as p,
|
|
8703
8782
|
startOAuthFlow as s
|
|
8704
8783
|
};
|
|
8705
|
-
//# sourceMappingURL=server-
|
|
8784
|
+
//# sourceMappingURL=server-wlJ31cFg.js.map
|