aai-gateway 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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-wlJ31cFg.js";
3
- const VERSION = "0.1.4";
2
+ import { b as createDesktopDiscovery, d as createGatewayServer, l as logger } from "./server-BIZIyh-I.js";
3
+ const VERSION = "0.2.0";
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.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;"}
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.2.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;"}
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-wlJ31cFg.js";
1
+ import { A, a, C, T, c, b, d, e, f, g, h, i, l, p, s } from "./server-BIZIyh-I.js";
2
2
  export {
3
3
  A as AaiError,
4
4
  a as AaiGatewayServer,
@@ -7899,7 +7899,8 @@ const AaiJsonSchema = z.object({
7899
7899
  app: z.object({
7900
7900
  id: z.string(),
7901
7901
  name: z.string(),
7902
- description: z.string()
7902
+ description: z.string(),
7903
+ aliases: z.array(z.string()).optional()
7903
7904
  }),
7904
7905
  execution: ExecutionSchema,
7905
7906
  auth: AuthSchema.optional(),
@@ -8350,7 +8351,7 @@ class MacOSIpcExecutor {
8350
8351
  };
8351
8352
  const jsonStr = JSON.stringify(request).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
8352
8353
  const script = `tell application id "${appId}"
8353
- «event AAI call» given «class kfil»:"${jsonStr}"
8354
+ «event AAI call» "${jsonStr}"
8354
8355
  end tell`;
8355
8356
  let stdout;
8356
8357
  try {
@@ -8623,6 +8624,62 @@ class TokenManager {
8623
8624
  };
8624
8625
  }
8625
8626
  }
8627
+ function parseMultiLanguageName(name) {
8628
+ return name.split("|").map((n) => n.trim());
8629
+ }
8630
+ function generateAppListDescription(app) {
8631
+ const names = parseMultiLanguageName(app.name);
8632
+ const allNames = names.join("|");
8633
+ const aliases = app.aliases ?? [];
8634
+ const aliasStr = aliases.length > 0 ? ` Aliases: ${aliases.join(", ")}.` : "";
8635
+ return `【${allNames}】${app.description}.${aliasStr} Call to get guide.`;
8636
+ }
8637
+ function generateOperationGuide(appId, descriptor, platform) {
8638
+ const sections = [];
8639
+ const names = parseMultiLanguageName(descriptor.app.name);
8640
+ sections.push(`# ${names[0]} Operation Guide`);
8641
+ sections.push("");
8642
+ sections.push("## App Info");
8643
+ sections.push(`- ID: ${appId}`);
8644
+ sections.push(`- Platform: ${descriptor.platform}`);
8645
+ sections.push("");
8646
+ sections.push("## Authentication");
8647
+ if (platform === "desktop") {
8648
+ sections.push("Uses OS-level consent (TCC). First execution shows native dialog.");
8649
+ } else {
8650
+ sections.push("Uses OAuth 2.1. First execution opens browser for authorization.");
8651
+ }
8652
+ sections.push("");
8653
+ sections.push("## Available Operations");
8654
+ sections.push("");
8655
+ for (const tool of descriptor.tools) {
8656
+ sections.push(`### ${tool.name}`);
8657
+ sections.push(tool.description);
8658
+ sections.push("");
8659
+ const params = tool.parameters;
8660
+ if (params?.properties && Object.keys(params.properties).length > 0) {
8661
+ sections.push("**Parameters**:");
8662
+ for (const [key, value] of Object.entries(params.properties)) {
8663
+ const required2 = params.required?.includes(key) ? "required" : "optional";
8664
+ const desc = value.description ?? "";
8665
+ sections.push(`- ${key} (${value.type ?? "any"}, ${required2}): ${desc}`);
8666
+ }
8667
+ sections.push("");
8668
+ }
8669
+ sections.push("**Example**:");
8670
+ sections.push("```");
8671
+ sections.push(`aai:exec({`);
8672
+ sections.push(` app: "${appId}",`);
8673
+ sections.push(` tool: "${tool.name}",`);
8674
+ sections.push(` args: { ... }`);
8675
+ sections.push(`})`);
8676
+ sections.push("```");
8677
+ sections.push("");
8678
+ }
8679
+ sections.push("---");
8680
+ sections.push("Use aai:exec tool to execute operations.");
8681
+ return sections.join("\n");
8682
+ }
8626
8683
  class AaiGatewayServer {
8627
8684
  server;
8628
8685
  desktopRegistry = /* @__PURE__ */ new Map();
@@ -8632,8 +8689,8 @@ class AaiGatewayServer {
8632
8689
  constructor(options) {
8633
8690
  this.options = options ?? {};
8634
8691
  this.server = new Server(
8635
- { name: "aai-gateway", version: "0.1.0" },
8636
- { capabilities: { resources: {}, tools: {} } }
8692
+ { name: "aai-gateway", version: "0.2.0" },
8693
+ { capabilities: { tools: {} } }
8637
8694
  );
8638
8695
  this.setupHandlers();
8639
8696
  }
@@ -8658,101 +8715,152 @@ class AaiGatewayServer {
8658
8715
  }
8659
8716
  }
8660
8717
  setupHandlers() {
8661
- this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
8662
- const resources = Array.from(this.desktopRegistry.values()).map((app) => ({
8663
- uri: `app:${app.appId}`,
8664
- name: app.name,
8665
- description: app.description,
8666
- mimeType: "application/aai+json"
8667
- }));
8668
- return { resources };
8669
- });
8670
8718
  this.server.setRequestHandler(ListToolsRequestSchema, async () => {
8671
8719
  const tools = [];
8672
8720
  for (const app of this.desktopRegistry.values()) {
8673
- for (const tool of app.descriptor.tools) {
8674
- tools.push({
8675
- name: `${app.appId}:${tool.name}`,
8676
- description: tool.description,
8677
- inputSchema: tool.parameters ?? { type: "object", properties: {} }
8678
- });
8679
- }
8721
+ const description = generateAppListDescription({
8722
+ appId: app.appId,
8723
+ name: app.descriptor.app.name,
8724
+ description: app.descriptor.app.description,
8725
+ aliases: app.descriptor.app.aliases
8726
+ });
8727
+ tools.push({
8728
+ name: `app:${app.appId}`,
8729
+ description,
8730
+ inputSchema: { type: "object", properties: {} }
8731
+ });
8680
8732
  }
8733
+ tools.push({
8734
+ name: "web:discover",
8735
+ description: "Discover and get operation guide for a Web application. Use when user mentions a web service not in the known apps list. Supports URL, domain, or service name.",
8736
+ inputSchema: {
8737
+ type: "object",
8738
+ properties: {
8739
+ url: {
8740
+ type: "string",
8741
+ description: "Web app URL, domain, or service name (e.g., notion.com, github)"
8742
+ }
8743
+ },
8744
+ required: ["url"]
8745
+ }
8746
+ });
8747
+ tools.push({
8748
+ name: "aai:exec",
8749
+ description: "Execute an app operation. Use after reading the operation guide. Parameters: app (app ID or URL), tool (operation name), args (parameters object).",
8750
+ inputSchema: {
8751
+ type: "object",
8752
+ properties: {
8753
+ app: {
8754
+ type: "string",
8755
+ description: "App identifier (e.g., com.apple.reminders) or Web app URL"
8756
+ },
8757
+ tool: {
8758
+ type: "string",
8759
+ description: "Operation name (e.g., create_reminder)"
8760
+ },
8761
+ args: {
8762
+ type: "object",
8763
+ description: "Operation parameters as described in the guide",
8764
+ additionalProperties: true
8765
+ }
8766
+ },
8767
+ required: ["app", "tool"]
8768
+ }
8769
+ });
8681
8770
  logger.debug({ toolCount: tools.length }, "tools/list requested");
8682
8771
  return { tools };
8683
8772
  });
8684
- this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
8685
- const uri = request.params.uri;
8686
- let descriptor;
8687
- if (uri.startsWith("app:")) {
8688
- const appId = uri.slice(4);
8689
- const app = this.desktopRegistry.get(appId);
8690
- if (!app) {
8691
- throw new AaiError("UNKNOWN_APP", `App '${appId}' not found in registry`);
8692
- }
8693
- descriptor = app.descriptor;
8694
- } else if (uri.startsWith("https://") || uri.startsWith("http://")) {
8695
- descriptor = await fetchWebDescriptor(uri);
8696
- } else {
8697
- throw new AaiError("INVALID_REQUEST", `Unknown URI scheme: ${uri}`);
8698
- }
8699
- return {
8700
- contents: [
8701
- {
8702
- uri,
8703
- mimeType: "application/json",
8704
- text: JSON.stringify(descriptor, null, 2)
8705
- }
8706
- ]
8707
- };
8708
- });
8709
8773
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
8710
8774
  const { name, arguments: args } = request.params;
8711
- const colonIdx = name.indexOf(":");
8712
- if (colonIdx === -1) {
8713
- throw new AaiError(
8714
- "INVALID_REQUEST",
8715
- `Invalid tool name format '${name}'. Expected: <app_id>:<tool_name>`
8716
- );
8717
- }
8718
- const appId = name.slice(0, colonIdx);
8719
- const toolName = name.slice(colonIdx + 1);
8720
- let descriptor;
8721
- let appName;
8722
- const desktopApp = this.desktopRegistry.get(appId);
8723
- if (desktopApp) {
8724
- descriptor = desktopApp.descriptor;
8725
- appName = desktopApp.name;
8726
- } else {
8727
- descriptor = await fetchWebDescriptor(appId);
8728
- appName = descriptor.app.name;
8775
+ if (name.startsWith("app:")) {
8776
+ const appId = name.slice(4);
8777
+ return await this.handleAppGuide(appId);
8729
8778
  }
8730
- const tool = descriptor.tools.find((t) => t.name === toolName);
8731
- if (!tool) {
8732
- throw new AaiError("UNKNOWN_TOOL", `Tool '${toolName}' not found in '${appId}'`);
8779
+ if (name === "web:discover") {
8780
+ const url = args?.url;
8781
+ if (!url) {
8782
+ throw new AaiError("INVALID_REQUEST", "Missing 'url' parameter");
8783
+ }
8784
+ return await this.handleWebDiscover(url);
8733
8785
  }
8734
- await this.consentManager.checkAndPrompt(descriptor.app.id, appName, {
8735
- name: toolName,
8736
- description: tool.description,
8737
- parameters: tool.parameters
8738
- });
8739
- let result;
8740
- if (descriptor.platform === "web") {
8741
- const accessToken = await this.tokenManager.getValidToken(descriptor.app.id, descriptor);
8742
- result = await executeWebTool(descriptor, toolName, args ?? {}, accessToken);
8743
- } else {
8744
- const ipcExecutor = createIpcExecutor();
8745
- result = await ipcExecutor.execute(descriptor.app.id, toolName, args ?? {});
8786
+ if (name === "aai:exec") {
8787
+ const {
8788
+ app,
8789
+ tool,
8790
+ args: toolArgs
8791
+ } = args;
8792
+ return await this.handleExec(app, tool, toolArgs ?? {});
8746
8793
  }
8747
- return {
8748
- content: [
8749
- {
8750
- type: "text",
8751
- text: typeof result === "string" ? result : JSON.stringify(result, null, 2)
8752
- }
8753
- ]
8754
- };
8794
+ throw new AaiError("UNKNOWN_TOOL", `Unknown tool: ${name}`);
8795
+ });
8796
+ }
8797
+ async handleAppGuide(appId) {
8798
+ const app = this.desktopRegistry.get(appId);
8799
+ if (!app) {
8800
+ throw new AaiError("UNKNOWN_APP", `App not found: ${appId}`);
8801
+ }
8802
+ const guide = generateOperationGuide(appId, app.descriptor, "desktop");
8803
+ return {
8804
+ content: [{ type: "text", text: guide }]
8805
+ };
8806
+ }
8807
+ async handleWebDiscover(urlInput) {
8808
+ const normalizedUrl = this.normalizeUrl(urlInput);
8809
+ const descriptor = await fetchWebDescriptor(normalizedUrl);
8810
+ const guide = generateOperationGuide(normalizedUrl, descriptor, "web");
8811
+ return {
8812
+ content: [{ type: "text", text: guide }]
8813
+ };
8814
+ }
8815
+ async handleExec(appId, toolName, args) {
8816
+ let descriptor;
8817
+ let appName;
8818
+ let platform;
8819
+ const desktopApp = this.desktopRegistry.get(appId);
8820
+ if (desktopApp) {
8821
+ descriptor = desktopApp.descriptor;
8822
+ appName = desktopApp.name;
8823
+ platform = "desktop";
8824
+ } else {
8825
+ const normalizedUrl = this.normalizeUrl(appId);
8826
+ descriptor = await fetchWebDescriptor(normalizedUrl);
8827
+ appName = parseMultiLanguageName(descriptor.app.name)[0];
8828
+ platform = "web";
8829
+ }
8830
+ const tool = descriptor.tools.find((t) => t.name === toolName);
8831
+ if (!tool) {
8832
+ throw new AaiError("UNKNOWN_TOOL", `Tool '${toolName}' not found in '${appId}'`);
8833
+ }
8834
+ await this.consentManager.checkAndPrompt(descriptor.app.id, appName, {
8835
+ name: toolName,
8836
+ description: tool.description,
8837
+ parameters: tool.parameters
8755
8838
  });
8839
+ let result;
8840
+ if (platform === "web") {
8841
+ const accessToken = await this.tokenManager.getValidToken(descriptor.app.id, descriptor);
8842
+ result = await executeWebTool(descriptor, toolName, args, accessToken);
8843
+ } else {
8844
+ const ipcExecutor = createIpcExecutor();
8845
+ result = await ipcExecutor.execute(descriptor.app.id, toolName, args);
8846
+ }
8847
+ return {
8848
+ content: [
8849
+ {
8850
+ type: "text",
8851
+ text: typeof result === "string" ? result : JSON.stringify(result, null, 2)
8852
+ }
8853
+ ]
8854
+ };
8855
+ }
8856
+ normalizeUrl(input) {
8857
+ if (input.startsWith("https://") || input.startsWith("http://")) {
8858
+ return input;
8859
+ }
8860
+ if (input.includes(".") && !input.includes("/")) {
8861
+ return `https://${input}`;
8862
+ }
8863
+ return `https://${input}`;
8756
8864
  }
8757
8865
  async start() {
8758
8866
  await this.initialize();
@@ -8781,4 +8889,4 @@ export {
8781
8889
  parseAaiJson as p,
8782
8890
  startOAuthFlow as s
8783
8891
  };
8784
- //# sourceMappingURL=server-wlJ31cFg.js.map
8892
+ //# sourceMappingURL=server-BIZIyh-I.js.map