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-Co-wKJpj.js";
3
- const VERSION = "0.1.0";
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.0';\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;"}
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,4 +1,4 @@
1
- import { A, a, C, T, c, b, d, e, f, g, h, i, l, p, s } from "./server-Co-wKJpj.js";
1
+ import { A, a, C, T, c, b, d, e, f, g, h, i, l, p, s } from "./server-wlJ31cFg.js";
2
2
  export {
3
3
  A as AaiError,
4
4
  a as AaiGatewayServer,
@@ -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") || "(no parameters)";
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 paramLines = buildParamLines(info.parameters);
8202
+ const t = getTranslations(this.locale);
8203
+ const paramLines = buildParamLines(info.parameters, t.noParameters);
8126
8204
  const authScript = `
8127
- set dialogText to "⚠️ Tool Authorization Request
8205
+ set dialogText to "${t.dialogTitle}
8128
8206
 
8129
- App: ${info.appName} (${info.appId})
8207
+ ${t.appLabel}: ${info.appName} (${info.appId})
8130
8208
 
8131
- Agent requests permission to use:
8209
+ ${t.requestPermissionLabel}
8132
8210
 
8133
8211
  ${info.toolName}
8134
8212
  ${info.toolDescription}
8135
8213
 
8136
- Parameters:
8214
+ ${t.parametersLabel}
8137
8215
  ${paramLines}"
8138
- set result to display dialog dialogText buttons {"Deny", "Authorize Tool", "Authorize All"} default button "Authorize Tool" with icon caution
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 === "Authorize All") {
8224
+ if (btn === t.buttonAuthorizeAll) {
8147
8225
  decision = "all";
8148
- } else if (btn === "Authorize Tool") {
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 "Remember this decision for '${info.toolName}'?" buttons {"No", "Yes"} default button "Yes"
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() === "Yes";
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-Co-wKJpj.js.map
8784
+ //# sourceMappingURL=server-wlJ31cFg.js.map