@agent-native/core 0.44.4 → 0.45.1

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 (165) hide show
  1. package/dist/action.d.ts +8 -1
  2. package/dist/action.d.ts.map +1 -1
  3. package/dist/action.js +20 -10
  4. package/dist/action.js.map +1 -1
  5. package/dist/cli/app-skill.d.ts +3 -1
  6. package/dist/cli/app-skill.d.ts.map +1 -1
  7. package/dist/cli/app-skill.js +50 -8
  8. package/dist/cli/app-skill.js.map +1 -1
  9. package/dist/cli/connect.d.ts +2 -1
  10. package/dist/cli/connect.d.ts.map +1 -1
  11. package/dist/cli/connect.js +224 -10
  12. package/dist/cli/connect.js.map +1 -1
  13. package/dist/cli/create.d.ts.map +1 -1
  14. package/dist/cli/create.js +9 -7
  15. package/dist/cli/create.js.map +1 -1
  16. package/dist/cli/index.js +69 -10
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/cli/mcp-config-writers.d.ts +10 -0
  19. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  20. package/dist/cli/mcp-config-writers.js +60 -6
  21. package/dist/cli/mcp-config-writers.js.map +1 -1
  22. package/dist/cli/mcp.d.ts.map +1 -1
  23. package/dist/cli/mcp.js +4 -6
  24. package/dist/cli/mcp.js.map +1 -1
  25. package/dist/cli/plan-local.d.ts +43 -0
  26. package/dist/cli/plan-local.d.ts.map +1 -0
  27. package/dist/cli/plan-local.js +490 -0
  28. package/dist/cli/plan-local.js.map +1 -0
  29. package/dist/cli/plan-publish-store.d.ts +17 -7
  30. package/dist/cli/plan-publish-store.d.ts.map +1 -1
  31. package/dist/cli/plan-publish-store.js +33 -8
  32. package/dist/cli/plan-publish-store.js.map +1 -1
  33. package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
  34. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  35. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  36. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  37. package/dist/cli/recap.d.ts +225 -3
  38. package/dist/cli/recap.d.ts.map +1 -1
  39. package/dist/cli/recap.js +1267 -27
  40. package/dist/cli/recap.js.map +1 -1
  41. package/dist/cli/skills.d.ts +26 -11
  42. package/dist/cli/skills.d.ts.map +1 -1
  43. package/dist/cli/skills.js +810 -1365
  44. package/dist/cli/skills.js.map +1 -1
  45. package/dist/cli/templates-meta.d.ts.map +1 -1
  46. package/dist/cli/templates-meta.js +3 -2
  47. package/dist/cli/templates-meta.js.map +1 -1
  48. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  49. package/dist/client/blocks/library/AnnotatedCodeBlock.js +41 -10
  50. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  51. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  52. package/dist/client/blocks/library/DiffBlock.js +54 -23
  53. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  54. package/dist/client/blocks/library/annotation-rail.d.ts +27 -8
  55. package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
  56. package/dist/client/blocks/library/annotation-rail.js +64 -27
  57. package/dist/client/blocks/library/annotation-rail.js.map +1 -1
  58. package/dist/client/blocks/library/code-filename-label.d.ts +8 -0
  59. package/dist/client/blocks/library/code-filename-label.d.ts.map +1 -0
  60. package/dist/client/blocks/library/code-filename-label.js +15 -0
  61. package/dist/client/blocks/library/code-filename-label.js.map +1 -0
  62. package/dist/client/blocks/library/code.d.ts.map +1 -1
  63. package/dist/client/blocks/library/code.js +3 -2
  64. package/dist/client/blocks/library/code.js.map +1 -1
  65. package/dist/client/blocks/library/diff.config.d.ts +1 -1
  66. package/dist/client/blocks/library/diff.config.js.map +1 -1
  67. package/dist/client/blocks/library/html.d.ts.map +1 -1
  68. package/dist/client/blocks/library/html.js +3 -1
  69. package/dist/client/blocks/library/html.js.map +1 -1
  70. package/dist/client/blocks/library/narrow-container.d.ts +4 -4
  71. package/dist/client/blocks/library/narrow-container.d.ts.map +1 -1
  72. package/dist/client/blocks/library/narrow-container.js +10 -10
  73. package/dist/client/blocks/library/narrow-container.js.map +1 -1
  74. package/dist/client/blocks/library/question-form.d.ts.map +1 -1
  75. package/dist/client/blocks/library/question-form.js +4 -1
  76. package/dist/client/blocks/library/question-form.js.map +1 -1
  77. package/dist/client/blocks/library/tabs.d.ts.map +1 -1
  78. package/dist/client/blocks/library/tabs.js +7 -2
  79. package/dist/client/blocks/library/tabs.js.map +1 -1
  80. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  81. package/dist/client/composer/TiptapComposer.js +4 -1
  82. package/dist/client/composer/TiptapComposer.js.map +1 -1
  83. package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
  84. package/dist/client/db-admin/TableEditor.js +3 -1
  85. package/dist/client/db-admin/TableEditor.js.map +1 -1
  86. package/dist/db/client.d.ts +8 -0
  87. package/dist/db/client.d.ts.map +1 -1
  88. package/dist/db/client.js +23 -2
  89. package/dist/db/client.js.map +1 -1
  90. package/dist/db/migrations.d.ts.map +1 -1
  91. package/dist/db/migrations.js +2 -1
  92. package/dist/db/migrations.js.map +1 -1
  93. package/dist/deploy/build.d.ts.map +1 -1
  94. package/dist/deploy/build.js +8 -0
  95. package/dist/deploy/build.js.map +1 -1
  96. package/dist/extensions/html-shell.js +1 -1
  97. package/dist/extensions/html-shell.js.map +1 -1
  98. package/dist/extensions/routes.d.ts +18 -0
  99. package/dist/extensions/routes.d.ts.map +1 -1
  100. package/dist/extensions/routes.js +30 -8
  101. package/dist/extensions/routes.js.map +1 -1
  102. package/dist/jobs/scheduler.d.ts.map +1 -1
  103. package/dist/jobs/scheduler.js +5 -1
  104. package/dist/jobs/scheduler.js.map +1 -1
  105. package/dist/mcp/build-server.d.ts +1 -0
  106. package/dist/mcp/build-server.d.ts.map +1 -1
  107. package/dist/mcp/build-server.js +7 -3
  108. package/dist/mcp/build-server.js.map +1 -1
  109. package/dist/mcp/oauth-route.d.ts.map +1 -1
  110. package/dist/mcp/oauth-route.js +56 -19
  111. package/dist/mcp/oauth-route.js.map +1 -1
  112. package/dist/mcp/oauth-store.d.ts +1 -0
  113. package/dist/mcp/oauth-store.d.ts.map +1 -1
  114. package/dist/mcp/oauth-store.js +9 -0
  115. package/dist/mcp/oauth-store.js.map +1 -1
  116. package/dist/mcp/server.d.ts.map +1 -1
  117. package/dist/mcp/server.js +9 -4
  118. package/dist/mcp/server.js.map +1 -1
  119. package/dist/mcp-client/errors.js +3 -3
  120. package/dist/mcp-client/errors.js.map +1 -1
  121. package/dist/oauth-tokens/store.d.ts.map +1 -1
  122. package/dist/oauth-tokens/store.js +42 -5
  123. package/dist/oauth-tokens/store.js.map +1 -1
  124. package/dist/scripts/db/index.d.ts.map +1 -1
  125. package/dist/scripts/db/index.js +1 -0
  126. package/dist/scripts/db/index.js.map +1 -1
  127. package/dist/scripts/db/migrate-encrypt-oauth-tokens.d.ts +28 -0
  128. package/dist/scripts/db/migrate-encrypt-oauth-tokens.d.ts.map +1 -0
  129. package/dist/scripts/db/migrate-encrypt-oauth-tokens.js +164 -0
  130. package/dist/scripts/db/migrate-encrypt-oauth-tokens.js.map +1 -0
  131. package/dist/scripts/db/scoping.d.ts.map +1 -1
  132. package/dist/scripts/db/scoping.js +7 -5
  133. package/dist/scripts/db/scoping.js.map +1 -1
  134. package/dist/secrets/index.d.ts +1 -0
  135. package/dist/secrets/index.d.ts.map +1 -1
  136. package/dist/secrets/index.js +4 -0
  137. package/dist/secrets/index.js.map +1 -1
  138. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  139. package/dist/server/agent-chat-plugin.js +3 -1
  140. package/dist/server/agent-chat-plugin.js.map +1 -1
  141. package/dist/server/agent-teams.d.ts.map +1 -1
  142. package/dist/server/agent-teams.js +10 -2
  143. package/dist/server/agent-teams.js.map +1 -1
  144. package/dist/server/auth.d.ts.map +1 -1
  145. package/dist/server/auth.js +7 -3
  146. package/dist/server/auth.js.map +1 -1
  147. package/dist/server/recap-image-route.d.ts.map +1 -1
  148. package/dist/server/recap-image-route.js +3 -6
  149. package/dist/server/recap-image-route.js.map +1 -1
  150. package/dist/server/sentry.d.ts.map +1 -1
  151. package/dist/server/sentry.js +12 -5
  152. package/dist/server/sentry.js.map +1 -1
  153. package/dist/server/social-og-image.d.ts.map +1 -1
  154. package/dist/server/social-og-image.js +3 -1
  155. package/dist/server/social-og-image.js.map +1 -1
  156. package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
  157. package/dist/sharing/actions/set-resource-visibility.js +4 -1
  158. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  159. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
  160. package/docs/content/plan-plugin.md +39 -7
  161. package/docs/content/pr-visual-recap.md +89 -13
  162. package/docs/content/skills-guide.md +13 -0
  163. package/docs/content/template-plan.md +62 -7
  164. package/package.json +5 -1
  165. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
@@ -8,6 +8,7 @@
8
8
  * agent-native connect <url> [--client all|claude-code|claude-code-cli|
9
9
  * codex|cowork] [--scope user|project]
10
10
  * [--name <serverName>]
11
+ * agent-native reconnect [<url>] [--client ...] [--name <serverName>]
11
12
  * agent-native connect <url> --token <token> (no-browser fallback)
12
13
  * agent-native connect [--client ...] (pick first-party apps)
13
14
  * agent-native connect --all [--client ...] (separate first-party app MCP resources)
@@ -105,8 +106,10 @@ export function parseConnectArgs(argv) {
105
106
  else if ((v = eat("--token")) !== undefined)
106
107
  out.token = v;
107
108
  else if (!a.startsWith("-") && !out.url) {
108
- if (!out.mode && (a === "dev" || a === "prod"))
109
+ if (!out.mode &&
110
+ (a === "dev" || a === "prod" || a === "reauth" || a === "reconnect")) {
109
111
  out.mode = a;
112
+ }
110
113
  else
111
114
  out.url = a;
112
115
  }
@@ -713,6 +716,106 @@ function savedEntryUrl(saved) {
713
716
  const match = saved.block.match(/^\s*url\s*=\s*"((?:\\.|[^"])*)"/m);
714
717
  return match ? unescapeTomlString(match[1]) : undefined;
715
718
  }
719
+ function readJsonMcpServerEntries(file) {
720
+ try {
721
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
722
+ const servers = parsed?.mcpServers;
723
+ if (!servers || typeof servers !== "object" || Array.isArray(servers)) {
724
+ return [];
725
+ }
726
+ return Object.entries(servers).flatMap(([serverName, entry]) => {
727
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
728
+ return [];
729
+ }
730
+ return [
731
+ {
732
+ serverName,
733
+ saved: {
734
+ kind: "json",
735
+ entry: entry,
736
+ savedAt: new Date().toISOString(),
737
+ },
738
+ },
739
+ ];
740
+ });
741
+ }
742
+ catch {
743
+ return [];
744
+ }
745
+ }
746
+ function parseCodexMcpServerName(line) {
747
+ const trimmed = line.trim();
748
+ const quoted = trimmed.match(/^\[mcp_servers\."((?:\\.|[^"])*)"\]$/);
749
+ if (quoted)
750
+ return unescapeTomlString(quoted[1]);
751
+ const bare = trimmed.match(/^\[mcp_servers\.([A-Za-z0-9_-]+)\]$/);
752
+ return bare?.[1];
753
+ }
754
+ function readCodexMcpServerEntries(file) {
755
+ let content = "";
756
+ try {
757
+ content = fs.readFileSync(file, "utf-8");
758
+ }
759
+ catch {
760
+ return [];
761
+ }
762
+ const lines = content.split(/\r?\n/);
763
+ const entries = [];
764
+ for (let i = 0; i < lines.length; i++) {
765
+ const serverName = parseCodexMcpServerName(lines[i]);
766
+ if (!serverName)
767
+ continue;
768
+ const block = [lines[i]];
769
+ i++;
770
+ while (i < lines.length && !/^\s*\[/.test(lines[i])) {
771
+ block.push(lines[i]);
772
+ i++;
773
+ }
774
+ i--;
775
+ entries.push({
776
+ serverName,
777
+ saved: {
778
+ kind: "codex",
779
+ block: block.join("\n").replace(/\n*$/, "") + "\n",
780
+ savedAt: new Date().toISOString(),
781
+ },
782
+ });
783
+ }
784
+ return entries;
785
+ }
786
+ function readExistingMcpEntries(clients, baseDir, scope) {
787
+ const entries = [];
788
+ for (const client of clients) {
789
+ const file = configPathFor(client, baseDir, scope);
790
+ const rawEntries = client === "codex"
791
+ ? readCodexMcpServerEntries(file)
792
+ : readJsonMcpServerEntries(file);
793
+ for (const { serverName, saved } of rawEntries) {
794
+ const url = savedEntryUrl(saved);
795
+ if (!url)
796
+ continue;
797
+ entries.push({ client, serverName, file, saved, url });
798
+ }
799
+ }
800
+ return entries;
801
+ }
802
+ function canonicalMcpUrl(value) {
803
+ if (!value)
804
+ return undefined;
805
+ try {
806
+ const url = new URL(value);
807
+ url.hash = "";
808
+ return url.toString().replace(/\/+$/, "");
809
+ }
810
+ catch {
811
+ return undefined;
812
+ }
813
+ }
814
+ function sameMcpUrl(a, b) {
815
+ const left = canonicalMcpUrl(a);
816
+ const right = canonicalMcpUrl(b);
817
+ return !!left && !!right && left === right;
818
+ }
716
819
  function savedEntryHeaders(saved) {
717
820
  if (!saved)
718
821
  return {};
@@ -1031,9 +1134,77 @@ async function connectProdProfile(parsed, clients, deps) {
1031
1134
  logOut(" Restart your coding agent to pick up the production MCP servers.");
1032
1135
  return missing.length === 0;
1033
1136
  }
1034
- // ---------------------------------------------------------------------------
1035
- // Single-app connect
1036
- // ---------------------------------------------------------------------------
1137
+ function distinctReconnectEntries(entries) {
1138
+ const seen = new Set();
1139
+ const out = [];
1140
+ for (const entry of entries) {
1141
+ const key = `${entry.serverName}\0${canonicalMcpUrl(entry.url) ?? entry.url}`;
1142
+ if (seen.has(key))
1143
+ continue;
1144
+ seen.add(key);
1145
+ out.push(entry);
1146
+ }
1147
+ return out;
1148
+ }
1149
+ function describeReconnectEntry(entry) {
1150
+ return `${entry.serverName} (${entry.url}) in ${entry.client}`;
1151
+ }
1152
+ function resolveReconnectTarget(parsed, clients) {
1153
+ const baseDir = projectBaseDir();
1154
+ const scope = parsed.scope === "user" ? "user" : "project";
1155
+ const entries = readExistingMcpEntries(clients, baseDir, scope);
1156
+ if (parsed.url) {
1157
+ const normalizedUrl = normalizeUrl(parsed.url);
1158
+ const mcpUrl = mcpUrlForBaseUrl(normalizedUrl);
1159
+ if (parsed.name) {
1160
+ return { rawUrl: parsed.url, serverName: parsed.name };
1161
+ }
1162
+ const matches = distinctReconnectEntries(entries.filter((entry) => sameMcpUrl(entry.url, mcpUrl)));
1163
+ const names = [...new Set(matches.map((entry) => entry.serverName))];
1164
+ if (names.length === 1) {
1165
+ return { rawUrl: parsed.url, serverName: names[0] };
1166
+ }
1167
+ if (names.length > 1) {
1168
+ logErr(` Found multiple MCP entries for ${mcpUrl}: ${names.join(", ")}.`);
1169
+ logErr(" Re-run with --name <serverName> to choose one.");
1170
+ return null;
1171
+ }
1172
+ return { rawUrl: parsed.url };
1173
+ }
1174
+ const candidates = distinctReconnectEntries(parsed.name
1175
+ ? entries.filter((entry) => entry.serverName === parsed.name)
1176
+ : entries.filter((entry) => entry.serverName.startsWith(`${SERVER_NAME_PREFIX}-`)));
1177
+ if (candidates.length === 0) {
1178
+ logErr(" No existing Agent Native MCP entry found to reconnect.");
1179
+ logErr(" Pass a URL, or use --name <serverName> if the entry has a custom name.");
1180
+ logErr(" First-time setup still uses: agent-native connect <url> --client <client>");
1181
+ return null;
1182
+ }
1183
+ if (candidates.length > 1) {
1184
+ logErr(" Found multiple Agent Native MCP entries:");
1185
+ for (const entry of candidates) {
1186
+ logErr(` ${describeReconnectEntry(entry)}`);
1187
+ }
1188
+ logErr(" Re-run with a URL or --name <serverName>.");
1189
+ return null;
1190
+ }
1191
+ const [entry] = candidates;
1192
+ return { rawUrl: entry.url, serverName: entry.serverName };
1193
+ }
1194
+ async function reconnectOne(parsed, clients, deps) {
1195
+ const target = resolveReconnectTarget(parsed, clients);
1196
+ if (!target)
1197
+ return false;
1198
+ const effectiveParsed = {
1199
+ ...parsed,
1200
+ url: target.rawUrl,
1201
+ name: target.serverName ?? parsed.name,
1202
+ };
1203
+ logOut("");
1204
+ logOut(` Reconnecting${effectiveParsed.name ? ` "${effectiveParsed.name}"` : ""}...`);
1205
+ const res = await connectOne(target.rawUrl, effectiveParsed, clients, deps);
1206
+ return res.ok;
1207
+ }
1037
1208
  async function connectOne(rawUrl, parsed, clients, deps) {
1038
1209
  const normalizedUrl = normalizeUrl(rawUrl);
1039
1210
  const baseUrl = stripMcpPath(normalizedUrl);
@@ -1097,11 +1268,45 @@ async function connectOne(rawUrl, parsed, clients, deps) {
1097
1268
  // a first-party Plans app, also persist `{ url, token }` to
1098
1269
  // `~/.agent-native/plan-publish.json` so the local Plans server can read the
1099
1270
  // same token for a server-to-server publish (publish-on-share). This is an
1100
- // ADDITIONAL write alongside the per-client MCP config; OAuth-only clients
1101
- // mint no local token, so this no-ops for them. Best-effort and merge-not-
1102
- // clobber — never fails the connect.
1103
- if (token && isFirstPartyPlanHost(baseUrl)) {
1104
- const canonicalPath = writePlanPublishAuth({ url: baseUrl, token });
1271
+ // ADDITIONAL write alongside the per-client MCP config; Best-effort and
1272
+ // merge-not-clobber never fails the connect.
1273
+ //
1274
+ // OAuth clients (claude-code, claude-code-cli) authenticate in-host via
1275
+ // standard MCP OAuth, so they never mint a local bearer token. To still
1276
+ // populate the publish store for them, we run a supplemental device-flow
1277
+ // mint using a non-OAuth client arg so the Plans server gets a usable token
1278
+ // and `publish-visual-plan` doesn't send the user back to `agent-native
1279
+ // connect` right after they just ran it.
1280
+ let publishToken = token;
1281
+ if (!publishToken &&
1282
+ oauthClients.length > 0 &&
1283
+ isFirstPartyPlanHost(baseUrl)) {
1284
+ try {
1285
+ logOut("");
1286
+ logOut(` Minting a publish token for the local Plans server (device flow)…`);
1287
+ const grant = await runDeviceFlow(baseUrl, appSlug,
1288
+ // Use a non-OAuth client arg so the server mints a bearer token even
1289
+ // though our primary clients are OAuth-native. "codex" is a stable,
1290
+ // always-supported non-OAuth client identifier.
1291
+ "codex", deps);
1292
+ if (grant?.token) {
1293
+ publishToken = grant.token;
1294
+ }
1295
+ else {
1296
+ logOut(` Warning: could not mint a publish token for the local Plans ` +
1297
+ `server. You can still publish via the hosted UI.`);
1298
+ }
1299
+ }
1300
+ catch {
1301
+ logOut(` Warning: publish-token mint failed. You can still publish via the ` +
1302
+ `hosted UI.`);
1303
+ }
1304
+ }
1305
+ if (publishToken && isFirstPartyPlanHost(baseUrl)) {
1306
+ const canonicalPath = writePlanPublishAuth({
1307
+ url: baseUrl,
1308
+ token: publishToken,
1309
+ });
1105
1310
  if (canonicalPath) {
1106
1311
  logOut("");
1107
1312
  logOut(` Saved publish token for the local Plans server → ${canonicalPath}`);
@@ -1200,6 +1405,13 @@ Usage:
1200
1405
  No-browser fallback. Skip the device flow and write the entry with
1201
1406
  the supplied token (get it from the app's Connect page).
1202
1407
 
1408
+ agent-native reconnect [<url>] [--client <c>] [--scope user|project]
1409
+ agent-native connect reconnect [<url>] [--client <c>] [--scope user|project]
1410
+ Re-authenticate an existing MCP entry without reinstalling apps/skills.
1411
+ With a URL, it reuses the existing server name for that MCP URL when
1412
+ possible. Without a URL, it reconnects the only matching Agent Native
1413
+ entry in the selected client config. Use --name for custom server names.
1414
+
1203
1415
  agent-native connect --all [--client <c>] [--scope user|project]
1204
1416
  Connect every first-party hosted app as separate MCP resources.
1205
1417
 
@@ -1234,7 +1446,9 @@ export async function runConnect(args, deps = {}) {
1234
1446
  return;
1235
1447
  const ok = parsed.mode === "dev"
1236
1448
  ? await connectDevProfile(parsed, clients, deps)
1237
- : await connectProdProfile(parsed, clients, deps);
1449
+ : parsed.mode === "prod"
1450
+ ? await connectProdProfile(parsed, clients, deps)
1451
+ : await reconnectOne(parsed, clients, deps);
1238
1452
  if (!ok)
1239
1453
  process.exitCode = 1;
1240
1454
  return;