@agent-native/core 0.21.0 → 0.22.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.
Files changed (134) hide show
  1. package/dist/cli/connect.d.ts +5 -3
  2. package/dist/cli/connect.d.ts.map +1 -1
  3. package/dist/cli/connect.js +127 -15
  4. package/dist/cli/connect.js.map +1 -1
  5. package/dist/client/AgentPanel.d.ts.map +1 -1
  6. package/dist/client/AgentPanel.js +6 -2
  7. package/dist/client/AgentPanel.js.map +1 -1
  8. package/dist/client/AssistantChat.d.ts.map +1 -1
  9. package/dist/client/AssistantChat.js +7 -1
  10. package/dist/client/AssistantChat.js.map +1 -1
  11. package/dist/client/NewWorkspaceAppFlow.js +1 -1
  12. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  13. package/dist/client/agent-chat.d.ts.map +1 -1
  14. package/dist/client/agent-chat.js +13 -8
  15. package/dist/client/agent-chat.js.map +1 -1
  16. package/dist/client/agent-sidebar-state.d.ts +2 -0
  17. package/dist/client/agent-sidebar-state.d.ts.map +1 -1
  18. package/dist/client/agent-sidebar-state.js +40 -0
  19. package/dist/client/agent-sidebar-state.js.map +1 -1
  20. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  21. package/dist/client/mcp-apps/McpAppRenderer.js +9 -4
  22. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
  23. package/dist/client/use-db-sync.d.ts +5 -5
  24. package/dist/client/use-db-sync.d.ts.map +1 -1
  25. package/dist/client/use-db-sync.js +15 -5
  26. package/dist/client/use-db-sync.js.map +1 -1
  27. package/dist/client/use-db-sync.spec.d.ts +2 -0
  28. package/dist/client/use-db-sync.spec.d.ts.map +1 -0
  29. package/dist/client/use-db-sync.spec.js +80 -0
  30. package/dist/client/use-db-sync.spec.js.map +1 -0
  31. package/dist/db/client.d.ts.map +1 -1
  32. package/dist/db/client.js +14 -8
  33. package/dist/db/client.js.map +1 -1
  34. package/dist/extensions/actions.d.ts.map +1 -1
  35. package/dist/extensions/actions.js +62 -3
  36. package/dist/extensions/actions.js.map +1 -1
  37. package/dist/extensions/content-patch.d.ts +71 -0
  38. package/dist/extensions/content-patch.d.ts.map +1 -0
  39. package/dist/extensions/content-patch.js +251 -0
  40. package/dist/extensions/content-patch.js.map +1 -0
  41. package/dist/extensions/routes.js +6 -1
  42. package/dist/extensions/routes.js.map +1 -1
  43. package/dist/extensions/store.d.ts +4 -4
  44. package/dist/extensions/store.d.ts.map +1 -1
  45. package/dist/extensions/store.js +14 -18
  46. package/dist/extensions/store.js.map +1 -1
  47. package/dist/mcp/build-server.d.ts +3 -0
  48. package/dist/mcp/build-server.d.ts.map +1 -1
  49. package/dist/mcp/build-server.js +55 -6
  50. package/dist/mcp/build-server.js.map +1 -1
  51. package/dist/mcp/oauth-route.d.ts +22 -0
  52. package/dist/mcp/oauth-route.d.ts.map +1 -0
  53. package/dist/mcp/oauth-route.js +618 -0
  54. package/dist/mcp/oauth-route.js.map +1 -0
  55. package/dist/mcp/oauth-store.d.ts +89 -0
  56. package/dist/mcp/oauth-store.d.ts.map +1 -0
  57. package/dist/mcp/oauth-store.js +391 -0
  58. package/dist/mcp/oauth-store.js.map +1 -0
  59. package/dist/mcp/oauth-token.d.ts +28 -0
  60. package/dist/mcp/oauth-token.d.ts.map +1 -0
  61. package/dist/mcp/oauth-token.js +83 -0
  62. package/dist/mcp/oauth-token.js.map +1 -0
  63. package/dist/mcp/server.d.ts.map +1 -1
  64. package/dist/mcp/server.js +5 -2
  65. package/dist/mcp/server.js.map +1 -1
  66. package/dist/mcp-client/index.d.ts.map +1 -1
  67. package/dist/mcp-client/index.js +16 -2
  68. package/dist/mcp-client/index.js.map +1 -1
  69. package/dist/mcp-client/routes.js +18 -5
  70. package/dist/mcp-client/routes.js.map +1 -1
  71. package/dist/scripts/dev/shell.d.ts.map +1 -1
  72. package/dist/scripts/dev/shell.js +24 -1
  73. package/dist/scripts/dev/shell.js.map +1 -1
  74. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  75. package/dist/server/agent-chat-plugin.js +3 -2
  76. package/dist/server/agent-chat-plugin.js.map +1 -1
  77. package/dist/server/auth.d.ts.map +1 -1
  78. package/dist/server/auth.js +14 -8
  79. package/dist/server/auth.js.map +1 -1
  80. package/dist/server/builder-browser.d.ts +6 -0
  81. package/dist/server/builder-browser.d.ts.map +1 -1
  82. package/dist/server/builder-browser.js +15 -0
  83. package/dist/server/builder-browser.js.map +1 -1
  84. package/dist/server/core-routes-plugin.d.ts +5 -4
  85. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  86. package/dist/server/core-routes-plugin.js +17 -2
  87. package/dist/server/core-routes-plugin.js.map +1 -1
  88. package/dist/templates/default/.agents/skills/actions/SKILL.md +193 -72
  89. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +88 -38
  90. package/dist/templates/default/AGENTS.md +3 -3
  91. package/dist/templates/default/actions/hello.ts +13 -20
  92. package/dist/templates/default/actions/navigate.ts +19 -51
  93. package/dist/templates/default/actions/view-screen.ts +16 -33
  94. package/dist/templates/default/app/hooks/use-navigation-state.ts +13 -3
  95. package/dist/templates/default/app/lib/tab-id.ts +1 -0
  96. package/dist/templates/default/app/root.tsx +2 -1
  97. package/dist/templates/default/app/routes/_index.tsx +11 -0
  98. package/dist/templates/default/package.json +2 -1
  99. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +9 -1
  100. package/dist/templates/workspace-core/AGENTS.md +8 -0
  101. package/dist/templates/workspace-root/AGENTS.md +7 -0
  102. package/dist/vite/client.d.ts.map +1 -1
  103. package/dist/vite/client.js +2 -2
  104. package/dist/vite/client.js.map +1 -1
  105. package/docs/content/actions.md +1 -1
  106. package/docs/content/authentication.md +16 -1
  107. package/docs/content/client.md +11 -8
  108. package/docs/content/context-awareness.md +2 -3
  109. package/docs/content/creating-templates.md +2 -2
  110. package/docs/content/external-agents.md +47 -14
  111. package/docs/content/faq.md +2 -2
  112. package/docs/content/key-concepts.md +31 -23
  113. package/docs/content/mcp-protocol.md +50 -17
  114. package/docs/content/template-starter.md +3 -3
  115. package/docs/content/what-is-agent-native.md +4 -2
  116. package/package.json +2 -1
  117. package/src/templates/default/.agents/skills/actions/SKILL.md +193 -72
  118. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +88 -38
  119. package/src/templates/default/AGENTS.md +3 -3
  120. package/src/templates/default/actions/hello.ts +13 -20
  121. package/src/templates/default/actions/navigate.ts +19 -51
  122. package/src/templates/default/actions/view-screen.ts +16 -33
  123. package/src/templates/default/app/hooks/use-navigation-state.ts +13 -3
  124. package/src/templates/default/app/lib/tab-id.ts +1 -0
  125. package/src/templates/default/app/root.tsx +2 -1
  126. package/src/templates/default/app/routes/_index.tsx +11 -0
  127. package/src/templates/default/package.json +2 -1
  128. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +9 -1
  129. package/src/templates/workspace-core/AGENTS.md +8 -0
  130. package/src/templates/workspace-root/AGENTS.md +7 -0
  131. package/dist/templates/default/server/routes/api/hello.get.ts +0 -5
  132. package/dist/templates/default/shared/api.ts +0 -6
  133. package/src/templates/default/server/routes/api/hello.get.ts +0 -5
  134. package/src/templates/default/shared/api.ts +0 -6
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * `agent-native connect <url>` — wire your local Claude Code / Codex / Cowork
3
- * to a DEPLOYED agent-native app using a browser device-code flow. No token
4
- * copying: open the verification URL, approve in the browser, and the minted
5
- * HTTP MCP server entry is written into your client config(s) idempotently.
3
+ * to a DEPLOYED agent-native app. OAuth-capable clients receive a standard
4
+ * remote MCP URL entry and authenticate in the host. Fallback clients use the
5
+ * browser device-code flow: open the verification URL, approve in the browser,
6
+ * and the minted HTTP MCP server entry is written idempotently.
6
7
  *
7
8
  * agent-native connect <url> [--client all|claude-code|claude-code-cli|
8
9
  * codex|cowork] [--scope user|project]
@@ -82,6 +83,7 @@ export interface ConnectHostedAppsPromptContext {
82
83
  apps: HostedApp[];
83
84
  initialApps: string[];
84
85
  }
86
+ export declare function supportsRemoteMcpOAuth(client: ClientId): boolean;
85
87
  /** Injectable hooks so the poll state machine is unit-testable. */
86
88
  export interface ConnectDeps {
87
89
  /** Defaults to global fetch. */
@@ -1 +1 @@
1
- {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/cli/connect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/cli/connect.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * `agent-native connect <url>` — wire your local Claude Code / Codex / Cowork
3
- * to a DEPLOYED agent-native app using a browser device-code flow. No token
4
- * copying: open the verification URL, approve in the browser, and the minted
5
- * HTTP MCP server entry is written into your client config(s) idempotently.
3
+ * to a DEPLOYED agent-native app. OAuth-capable clients receive a standard
4
+ * remote MCP URL entry and authenticate in the host. Fallback clients use the
5
+ * browser device-code flow: open the verification URL, approve in the browser,
6
+ * and the minted HTTP MCP server entry is written idempotently.
6
7
  *
7
8
  * agent-native connect <url> [--client all|claude-code|claude-code-cli|
8
9
  * codex|cowork] [--scope user|project]
@@ -35,6 +36,7 @@ import { CLIENTS, configPathFor, writeCodexBlock, writeHttpEntryForClient, write
35
36
  import { TEMPLATES, visibleTemplates } from "./templates-meta.js";
36
37
  const DEVICE_START_PATH = "/_agent-native/mcp/connect/device/start";
37
38
  const DEVICE_POLL_PATH = "/_agent-native/mcp/connect/device/poll";
39
+ const MCP_PATH = "/_agent-native/mcp";
38
40
  const SERVER_NAME_PREFIX = "agent-native";
39
41
  const CONNECT_PREFERENCES_VERSION = 1;
40
42
  const CONNECT_PROFILES_VERSION = 1;
@@ -51,6 +53,10 @@ const CLIENT_HINTS = {
51
53
  codex: "~/.codex/config.toml",
52
54
  cowork: "~/.cowork/mcp.json",
53
55
  };
56
+ const REMOTE_MCP_OAUTH_CLIENTS = new Set([
57
+ "claude-code",
58
+ "claude-code-cli",
59
+ ]);
54
60
  function logOut(msg) {
55
61
  process.stdout.write(`${msg}\n`);
56
62
  }
@@ -306,6 +312,12 @@ async function resolveHostedAppsFromPrompt(deps) {
306
312
  function clientArgForDeviceFlow(clients) {
307
313
  return clients.length === 1 ? clients[0] : "all";
308
314
  }
315
+ export function supportsRemoteMcpOAuth(client) {
316
+ return REMOTE_MCP_OAUTH_CLIENTS.has(client);
317
+ }
318
+ function clientLabelList(clients) {
319
+ return clients.map((client) => CLIENT_LABELS[client]).join(", ");
320
+ }
309
321
  /** Derive an app slug from a deployed origin, e.g. mail.agent-native.com → mail. */
310
322
  function appSlugFromUrl(url) {
311
323
  try {
@@ -377,6 +389,61 @@ function responseMessage(json, fallback) {
377
389
  : "";
378
390
  return message.trim() || fallback;
379
391
  }
392
+ function stripMcpPath(baseUrl) {
393
+ const parsed = new URL(baseUrl);
394
+ const pathname = parsed.pathname.replace(/\/+$/, "");
395
+ if (pathname === MCP_PATH || pathname.endsWith(MCP_PATH)) {
396
+ parsed.pathname = pathname.slice(0, -MCP_PATH.length) || "/";
397
+ parsed.search = "";
398
+ parsed.hash = "";
399
+ return `${parsed.origin}${parsed.pathname}`.replace(/\/+$/, "");
400
+ }
401
+ return baseUrl;
402
+ }
403
+ function mcpUrlForBaseUrl(baseUrl) {
404
+ const parsed = new URL(baseUrl);
405
+ const pathname = parsed.pathname.replace(/\/+$/, "");
406
+ if (pathname === MCP_PATH || pathname.endsWith(MCP_PATH)) {
407
+ parsed.pathname = pathname;
408
+ parsed.search = "";
409
+ parsed.hash = "";
410
+ return `${parsed.origin}${parsed.pathname}`;
411
+ }
412
+ return `${baseUrl.replace(/\/+$/, "")}${MCP_PATH}`;
413
+ }
414
+ async function validateOAuthMcpServer(baseUrl, mcpUrl, deps) {
415
+ const fetchImpl = deps.fetchImpl ?? fetch;
416
+ const metadataUrl = `${baseUrl}/.well-known/oauth-protected-resource`;
417
+ const controller = new AbortController();
418
+ const timeout = setTimeout(() => controller.abort(), 15_000);
419
+ try {
420
+ const response = await fetchImpl(metadataUrl, {
421
+ method: "GET",
422
+ headers: { accept: "application/json" },
423
+ signal: controller.signal,
424
+ });
425
+ if (!response.ok) {
426
+ logErr(` Could not validate OAuth MCP support at ${metadataUrl} ` +
427
+ `(HTTP ${response.status}).`);
428
+ return false;
429
+ }
430
+ const metadata = (await response.json().catch(() => null));
431
+ if (metadata?.resource !== mcpUrl) {
432
+ logErr(` ${metadataUrl} did not advertise the expected MCP resource ` +
433
+ `${mcpUrl}.`);
434
+ return false;
435
+ }
436
+ return true;
437
+ }
438
+ catch (err) {
439
+ logErr(` Could not reach ${metadataUrl} (${err?.message ?? err}). ` +
440
+ `Check the URL and your network.`);
441
+ return false;
442
+ }
443
+ finally {
444
+ clearTimeout(timeout);
445
+ }
446
+ }
380
447
  const SPINNER = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
381
448
  /**
382
449
  * Run the device-code flow against `baseUrl` and return the approved grant.
@@ -956,9 +1023,20 @@ async function connectProdProfile(parsed, clients, deps) {
956
1023
  // Single-app connect
957
1024
  // ---------------------------------------------------------------------------
958
1025
  async function connectOne(rawUrl, parsed, clients, deps) {
959
- const baseUrl = normalizeUrl(rawUrl);
1026
+ const normalizedUrl = normalizeUrl(rawUrl);
1027
+ const baseUrl = stripMcpPath(normalizedUrl);
1028
+ const normalizedMcpUrl = mcpUrlForBaseUrl(normalizedUrl);
960
1029
  const appSlug = appSlugFromUrl(baseUrl);
961
1030
  const scope = parsed.scope === "user" ? "user" : "project";
1031
+ const baseDir = projectBaseDir();
1032
+ const allWritten = [];
1033
+ const oauthClients = parsed.token
1034
+ ? []
1035
+ : clients.filter((client) => supportsRemoteMcpOAuth(client));
1036
+ const deviceFlowClients = parsed.token
1037
+ ? clients
1038
+ : clients.filter((client) => !supportsRemoteMcpOAuth(client));
1039
+ const oauthMigrations = [];
962
1040
  let token;
963
1041
  let mcpUrl;
964
1042
  let serverName;
@@ -966,13 +1044,18 @@ async function connectOne(rawUrl, parsed, clients, deps) {
966
1044
  if (parsed.token) {
967
1045
  // No-browser fallback: skip the device flow entirely.
968
1046
  token = parsed.token;
969
- mcpUrl = `${baseUrl}/_agent-native/mcp`;
1047
+ mcpUrl = normalizedMcpUrl;
970
1048
  serverName = parsed.name ?? defaultServerName(baseUrl);
971
1049
  logOut("");
972
1050
  logOut(` Using supplied --token for ${baseUrl} (skipping browser flow).`);
973
1051
  }
1052
+ else if (deviceFlowClients.length === 0) {
1053
+ token = undefined;
1054
+ mcpUrl = normalizedMcpUrl;
1055
+ serverName = parsed.name ?? defaultServerName(baseUrl);
1056
+ }
974
1057
  else {
975
- const grant = await runDeviceFlow(baseUrl, appSlug, clientArgForDeviceFlow(clients), deps);
1058
+ const grant = await runDeviceFlow(baseUrl, appSlug, clientArgForDeviceFlow(deviceFlowClients), deps);
976
1059
  if (!grant)
977
1060
  return { ok: false };
978
1061
  token = grant.token;
@@ -980,15 +1063,40 @@ async function connectOne(rawUrl, parsed, clients, deps) {
980
1063
  serverName = parsed.name ?? grant.serverName ?? defaultServerName(baseUrl);
981
1064
  headers = grant.headers;
982
1065
  }
983
- const written = writeConfigs(clients, serverName, mcpUrl, token, scope, undefined, headers);
1066
+ if (oauthClients.length > 0 && !parsed.token) {
1067
+ if (!(await validateOAuthMcpServer(baseUrl, mcpUrl, deps))) {
1068
+ return { ok: false };
1069
+ }
1070
+ }
1071
+ if (deviceFlowClients.length > 0) {
1072
+ allWritten.push(...writeConfigs(deviceFlowClients, serverName, mcpUrl, token, scope, baseDir, headers));
1073
+ }
1074
+ if (oauthClients.length > 0) {
1075
+ for (const client of oauthClients) {
1076
+ const current = readCurrentMcpEntry(client, serverName, baseDir, scope);
1077
+ const currentHeaders = savedEntryHeaders(current.saved);
1078
+ if (typeof currentHeaders.Authorization === "string") {
1079
+ oauthMigrations.push(client);
1080
+ }
1081
+ }
1082
+ allWritten.push(...writeConfigs(oauthClients, serverName, mcpUrl, undefined, scope, baseDir, undefined));
1083
+ }
984
1084
  logOut("");
985
- logOut(` Connected "${serverName}" → ${mcpUrl}`);
986
- for (const w of written) {
1085
+ logOut(` Configured "${serverName}" → ${mcpUrl}`);
1086
+ for (const w of allWritten) {
987
1087
  logOut(` ${w.client.padEnd(18)} ${w.file}`);
988
1088
  }
1089
+ if (oauthClients.length > 0 && !parsed.token) {
1090
+ logOut("");
1091
+ if (oauthMigrations.length > 0) {
1092
+ logOut(` Replaced legacy bearer headers for ${clientLabelList(oauthMigrations)}; it will reconnect with standard MCP OAuth.`);
1093
+ }
1094
+ logOut(` ${clientLabelList(oauthClients)}: wrote URL-only MCP config (no bearer headers).`);
1095
+ logOut(" Next: restart Claude Code, run /mcp, and choose Authenticate.");
1096
+ }
989
1097
  logOut("");
990
1098
  logOut(" Restart your coding agent to pick up the new MCP server.");
991
- return { ok: true, serverName, files: written.map((w) => w.file) };
1099
+ return { ok: true, serverName, files: allWritten.map((w) => w.file) };
992
1100
  }
993
1101
  // ---------------------------------------------------------------------------
994
1102
  // --all : connect every first-party hosted app
@@ -1049,11 +1157,15 @@ Usage:
1049
1157
  (mail.agent-native.com, calendar.agent-native.com, and friends).
1050
1158
 
1051
1159
  agent-native connect <url> [--client <c>] [--scope user|project] [--name <n>]
1052
- Browser device-code flow. Prints a code, opens the verification URL,
1053
- polls until approved, then writes the HTTP MCP entry into your
1054
- selected client config(s). With no --client, opens a brief picker
1055
- preselected from ~/.agent-native/connect.json, or all clients on first
1056
- run. Idempotent re-running replaces the same entry.
1160
+ Writes the HTTP MCP entry into your selected client config(s). Claude
1161
+ Code / Claude Code CLI use standard remote MCP OAuth: restart Claude,
1162
+ run /mcp, and choose Authenticate. Codex / Cowork use the browser
1163
+ device-code fallback: the command prints a code, opens the verification
1164
+ URL, polls until approved, then writes bearer headers. With no --client,
1165
+ opens a brief picker preselected from ~/.agent-native/connect.json, or
1166
+ all clients on first run. Idempotent — re-running replaces the same entry.
1167
+ Re-running over an older Claude bearer entry upgrades it to URL-only
1168
+ OAuth config and prompts you to authenticate with /mcp.
1057
1169
 
1058
1170
  agent-native connect <url> --token <token>
1059
1171
  No-browser fallback. Skip the device flow and write the entry with