@agent-native/core 0.51.15 → 0.52.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/README.md +3 -3
- package/dist/cli/connect.d.ts +4 -3
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +67 -26
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts +20 -13
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +152 -13
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/cli/mcp.d.ts +2 -2
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +41 -193
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/plan-local.d.ts +3 -1
- package/dist/cli/plan-local.d.ts.map +1 -1
- package/dist/cli/plan-local.js +24 -6
- package/dist/cli/plan-local.js.map +1 -1
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +1 -1
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills.d.ts +11 -4
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +218 -53
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/agent-engine-key.d.ts +6 -4
- package/dist/client/agent-engine-key.d.ts.map +1 -1
- package/dist/client/agent-engine-key.js +9 -6
- package/dist/client/agent-engine-key.js.map +1 -1
- package/dist/client/chat/run-recovery.js +1 -1
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +7 -14
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/coding-tools/run-code.d.ts +7 -0
- package/dist/coding-tools/run-code.d.ts.map +1 -1
- package/dist/coding-tools/run-code.js +21 -106
- package/dist/coding-tools/run-code.js.map +1 -1
- package/dist/coding-tools/sandbox/adapter.d.ts +79 -0
- package/dist/coding-tools/sandbox/adapter.d.ts.map +1 -0
- package/dist/coding-tools/sandbox/adapter.js +24 -0
- package/dist/coding-tools/sandbox/adapter.js.map +1 -0
- package/dist/coding-tools/sandbox/index.d.ts +51 -0
- package/dist/coding-tools/sandbox/index.d.ts.map +1 -0
- package/dist/coding-tools/sandbox/index.js +79 -0
- package/dist/coding-tools/sandbox/index.js.map +1 -0
- package/dist/coding-tools/sandbox/local-child-process-adapter.d.ts +24 -0
- package/dist/coding-tools/sandbox/local-child-process-adapter.d.ts.map +1 -0
- package/dist/coding-tools/sandbox/local-child-process-adapter.js +141 -0
- package/dist/coding-tools/sandbox/local-child-process-adapter.js.map +1 -0
- package/dist/server/agent-engine-api-key-route.d.ts +37 -0
- package/dist/server/agent-engine-api-key-route.d.ts.map +1 -0
- package/dist/server/agent-engine-api-key-route.js +105 -0
- package/dist/server/agent-engine-api-key-route.js.map +1 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +10 -6
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.js +1 -1
- package/dist/server/create-server.js.map +1 -1
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -4
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -4
package/README.md
CHANGED
|
@@ -18,17 +18,17 @@ The agent and the UI are equal citizens of the same system. Every action works b
|
|
|
18
18
|
- **Reusable integrations** — Connect a provider once in Dispatch, keep secret values in the vault, then grant apps like Brain, Analytics, Mail, and Dispatch access to the shared account metadata and credential refs.
|
|
19
19
|
- **Apps that improve themselves** — Your apps get better on their own. The agent can add features, fix bugs, and refine the UI over time.
|
|
20
20
|
- **Any database, any host** — Any SQL database Drizzle supports. Any hosting target Nitro supports. No lock-in.
|
|
21
|
-
- **Any AI agent** — Claude Code, Codex,
|
|
21
|
+
- **Any AI agent** — Claude Code, Codex, Cursor, Pi, OpenCode, GitHub Copilot / VS Code, or Builder.io. Use whichever agent you prefer.
|
|
22
22
|
|
|
23
23
|
## Try it with a skill
|
|
24
24
|
|
|
25
|
-
Don't want to scaffold a whole app yet? Add agent-native superpowers to a coding agent you already use — Claude Code, Codex,
|
|
25
|
+
Don't want to scaffold a whole app yet? Add agent-native superpowers to a coding agent you already use — Claude Code, Codex, Cursor, Pi, OpenCode, GitHub Copilot / VS Code, and similar agents — with one command:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
npx @agent-native/core@latest skills add visual-plan
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
It installs the skills, registers the hosted MCP connector, and signs in the selected
|
|
31
|
+
It installs the skills, writes shared `.agents` skill folders for agents that support them, registers the hosted MCP connector for supported local clients, and signs in the selected client(s) in one step. You get two slash commands that upgrade how your agent plans and reports its work:
|
|
32
32
|
|
|
33
33
|
- **`/visual-plan`** — before the agent writes code, it opens a structured, reviewable plan document instead of a wall of text: inline diagrams, UI wireframes and prototypes, file-by-file implementation maps, and annotations you can comment on and approve.
|
|
34
34
|
- **`/visual-recap`** — after changes land, it turns a PR or git diff into a high-altitude visual recap: schema, API, and file changes rendered as grounded before/after blocks with a shareable review link, instead of scrolling a raw diff.
|
package/dist/cli/connect.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agent-native connect <url>` — wire your local
|
|
2
|
+
* `agent-native connect <url>` — wire your local MCP-capable coding agent
|
|
3
3
|
* to a DEPLOYED agent-native app. OAuth-capable clients receive a standard
|
|
4
4
|
* remote MCP URL entry and authenticate in the host. Fallback clients use the
|
|
5
5
|
* browser device-code flow: open the verification URL, approve in the browser,
|
|
6
6
|
* and the minted HTTP MCP server entry is written idempotently.
|
|
7
7
|
*
|
|
8
8
|
* agent-native connect <url> [--client all|claude-code|claude-code-cli|
|
|
9
|
-
* codex|cowork
|
|
9
|
+
* codex|cowork|cursor|opencode|github-copilot]
|
|
10
|
+
* [--scope user|project]
|
|
10
11
|
* [--name <serverName>]
|
|
11
12
|
* agent-native reconnect [<url>] [--client ...] [--name <serverName>]
|
|
12
13
|
* agent-native connect <url> --token <token> (no-browser fallback)
|
|
@@ -34,7 +35,7 @@ export interface ParsedConnectArgs {
|
|
|
34
35
|
mode?: "dev" | "prod" | "reauth" | "reconnect";
|
|
35
36
|
/** Positional URL (the deployed app origin). Undefined for `--all`. */
|
|
36
37
|
url?: string;
|
|
37
|
-
/** all | claude-code | claude-code-cli | codex | cowork (default "all"). */
|
|
38
|
+
/** all | claude-code | claude-code-cli | codex | cowork | cursor | opencode | github-copilot (default "all"). */
|
|
38
39
|
client: string;
|
|
39
40
|
/** True when the user passed --client explicitly, so we skip the picker. */
|
|
40
41
|
clientExplicit: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/cli/connect.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/cli/connect.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/connect.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agent-native connect <url>` — wire your local
|
|
2
|
+
* `agent-native connect <url>` — wire your local MCP-capable coding agent
|
|
3
3
|
* to a DEPLOYED agent-native app. OAuth-capable clients receive a standard
|
|
4
4
|
* remote MCP URL entry and authenticate in the host. Fallback clients use the
|
|
5
5
|
* browser device-code flow: open the verification URL, approve in the browser,
|
|
6
6
|
* and the minted HTTP MCP server entry is written idempotently.
|
|
7
7
|
*
|
|
8
8
|
* agent-native connect <url> [--client all|claude-code|claude-code-cli|
|
|
9
|
-
* codex|cowork
|
|
9
|
+
* codex|cowork|cursor|opencode|github-copilot]
|
|
10
|
+
* [--scope user|project]
|
|
10
11
|
* [--name <serverName>]
|
|
11
12
|
* agent-native reconnect [<url>] [--client ...] [--name <serverName>]
|
|
12
13
|
* agent-native connect <url> --token <token> (no-browser fallback)
|
|
@@ -33,7 +34,7 @@ import os from "node:os";
|
|
|
33
34
|
import { spawn } from "node:child_process";
|
|
34
35
|
import path from "node:path";
|
|
35
36
|
import { findWorkspaceRoot } from "../mcp/workspace-resolve.js";
|
|
36
|
-
import { CLIENTS, configPathFor, removeSameUrlDuplicatesForClient, writeCodexBlock, writeHttpEntryForClient,
|
|
37
|
+
import { CLIENTS, configPathFor, jsonMcpConfigKeyForClient, removeSameUrlDuplicatesForClient, writeCodexBlock, writeHttpEntryForClient, writeJsonMcpEntryForClient, } from "./mcp-config-writers.js";
|
|
37
38
|
import { isFirstPartyPlanHost, writePlanPublishAuth, } from "./plan-publish-store.js";
|
|
38
39
|
import { TEMPLATES, visibleTemplates } from "./templates-meta.js";
|
|
39
40
|
const DEVICE_START_PATH = "/_agent-native/mcp/connect/device/start";
|
|
@@ -66,16 +67,25 @@ const CLIENT_LABELS = {
|
|
|
66
67
|
"claude-code-cli": "Claude Code CLI",
|
|
67
68
|
codex: "Codex",
|
|
68
69
|
cowork: "Claude Cowork",
|
|
70
|
+
cursor: "Cursor",
|
|
71
|
+
opencode: "OpenCode",
|
|
72
|
+
"github-copilot": "GitHub Copilot / VS Code",
|
|
69
73
|
};
|
|
70
74
|
const CLIENT_HINTS = {
|
|
71
75
|
"claude-code": ".mcp.json or ~/.claude.json",
|
|
72
76
|
"claude-code-cli": ".mcp.json or ~/.claude.json",
|
|
73
77
|
codex: "$CODEX_HOME/config.toml or ~/.codex/config.toml",
|
|
74
78
|
cowork: "~/.cowork/mcp.json",
|
|
79
|
+
cursor: ".cursor/mcp.json or ~/.cursor/mcp.json",
|
|
80
|
+
opencode: "opencode.json or ~/.config/opencode/opencode.json",
|
|
81
|
+
"github-copilot": ".vscode/mcp.json or VS Code user mcp.json",
|
|
75
82
|
};
|
|
76
83
|
const REMOTE_MCP_OAUTH_CLIENTS = new Set([
|
|
77
84
|
"claude-code",
|
|
78
85
|
"claude-code-cli",
|
|
86
|
+
"cursor",
|
|
87
|
+
"opencode",
|
|
88
|
+
"github-copilot",
|
|
79
89
|
]);
|
|
80
90
|
let logOutImpl = (msg) => process.stdout.write(`${msg}\n`);
|
|
81
91
|
let logErrImpl = (msg) => process.stderr.write(`${msg}\n`);
|
|
@@ -177,7 +187,7 @@ export function normalizeUrl(raw) {
|
|
|
177
187
|
}
|
|
178
188
|
/** Resolve the requested clients list. "all" → every supported client. */
|
|
179
189
|
export function resolveClients(client) {
|
|
180
|
-
const c = (client ?? "all")
|
|
190
|
+
const c = normalizeClientAlias(client ?? "all");
|
|
181
191
|
if (c === "all" || c === "")
|
|
182
192
|
return [...CLIENTS];
|
|
183
193
|
if (c.includes(",")) {
|
|
@@ -189,6 +199,15 @@ export function resolveClients(client) {
|
|
|
189
199
|
return [c];
|
|
190
200
|
throw new Error(`Unknown --client "${client}". Use: all, ${CLIENTS.join(", ")}`);
|
|
191
201
|
}
|
|
202
|
+
function normalizeClientAlias(value) {
|
|
203
|
+
const id = value.trim().toLowerCase();
|
|
204
|
+
if (id === "claude" || id === "claude-code-desktop")
|
|
205
|
+
return "claude-code";
|
|
206
|
+
if (id === "copilot" || id === "vscode" || id === "vs-code") {
|
|
207
|
+
return "github-copilot";
|
|
208
|
+
}
|
|
209
|
+
return id;
|
|
210
|
+
}
|
|
192
211
|
export function connectPreferencesPath() {
|
|
193
212
|
return path.join(os.homedir(), ".agent-native", "connect.json");
|
|
194
213
|
}
|
|
@@ -200,7 +219,7 @@ function normalizeClientIds(values) {
|
|
|
200
219
|
for (const value of values) {
|
|
201
220
|
if (typeof value !== "string")
|
|
202
221
|
continue;
|
|
203
|
-
const id = value
|
|
222
|
+
const id = normalizeClientAlias(value);
|
|
204
223
|
if (!CLIENTS.includes(id))
|
|
205
224
|
continue;
|
|
206
225
|
const client = id;
|
|
@@ -361,6 +380,22 @@ function sentenceClientLabelList(clients) {
|
|
|
361
380
|
return `${labels[0]} and ${labels[1]}`;
|
|
362
381
|
return `${labels.slice(0, -1).join(", ")}, and ${labels[labels.length - 1]}`;
|
|
363
382
|
}
|
|
383
|
+
function oauthNextStepsForClients(clients, serverName) {
|
|
384
|
+
const lines = [];
|
|
385
|
+
if (clients.includes("claude-code") || clients.includes("claude-code-cli")) {
|
|
386
|
+
lines.push("Claude Code: restart Claude Code, run /mcp, and choose Authenticate.");
|
|
387
|
+
}
|
|
388
|
+
if (clients.includes("cursor")) {
|
|
389
|
+
lines.push("Cursor: restart or reload Cursor, then authenticate the MCP server from Cursor MCP settings if prompted.");
|
|
390
|
+
}
|
|
391
|
+
if (clients.includes("opencode")) {
|
|
392
|
+
lines.push(`OpenCode: run opencode mcp auth ${serverName ?? "<server-name>"} or authenticate on first use.`);
|
|
393
|
+
}
|
|
394
|
+
if (clients.includes("github-copilot")) {
|
|
395
|
+
lines.push("GitHub Copilot / VS Code: reload VS Code, open the MCP config, and use the Auth action above the server if prompted.");
|
|
396
|
+
}
|
|
397
|
+
return lines;
|
|
398
|
+
}
|
|
364
399
|
function clientsNotIn(requestedClients, effectiveClients) {
|
|
365
400
|
const effective = new Set(effectiveClients);
|
|
366
401
|
return requestedClients.filter((client) => !effective.has(client));
|
|
@@ -379,7 +414,7 @@ async function showReconnectSuccessOutro({ serverName, clients, }) {
|
|
|
379
414
|
}
|
|
380
415
|
const oauthClients = clients.filter((client) => supportsRemoteMcpOAuth(client));
|
|
381
416
|
if (oauthClients.length > 0) {
|
|
382
|
-
lines.push(
|
|
417
|
+
lines.push(...oauthNextStepsForClients(oauthClients, serverName));
|
|
383
418
|
}
|
|
384
419
|
if (!clients.includes("codex") && oauthClients.length === 0) {
|
|
385
420
|
lines.push(`Restart or reload ${sentenceClientLabelList(clients)} before using the MCP tools.`);
|
|
@@ -707,10 +742,10 @@ function setSavedProfileEntry(profiles, serverName, client, file, entry) {
|
|
|
707
742
|
profiles.prodEntries[serverName][client] ??= {};
|
|
708
743
|
profiles.prodEntries[serverName][client][file] = entry;
|
|
709
744
|
}
|
|
710
|
-
function readJsonMcpServerEntry(file, serverName) {
|
|
745
|
+
function readJsonMcpServerEntry(client, file, serverName) {
|
|
711
746
|
try {
|
|
712
747
|
const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
713
|
-
const entry = parsed?.
|
|
748
|
+
const entry = parsed?.[jsonMcpConfigKeyForClient(client)]?.[serverName];
|
|
714
749
|
return entry && typeof entry === "object" ? entry : undefined;
|
|
715
750
|
}
|
|
716
751
|
catch {
|
|
@@ -760,7 +795,7 @@ function readCurrentMcpEntry(client, serverName, baseDir, scope) {
|
|
|
760
795
|
: undefined,
|
|
761
796
|
};
|
|
762
797
|
}
|
|
763
|
-
const entry = readJsonMcpServerEntry(file, serverName);
|
|
798
|
+
const entry = readJsonMcpServerEntry(client, file, serverName);
|
|
764
799
|
return {
|
|
765
800
|
file,
|
|
766
801
|
saved: entry
|
|
@@ -777,7 +812,7 @@ function writeSavedMcpEntry(client, file, serverName, saved) {
|
|
|
777
812
|
}
|
|
778
813
|
if (saved.kind !== "json")
|
|
779
814
|
return;
|
|
780
|
-
|
|
815
|
+
writeJsonMcpEntryForClient(client, file, serverName, saved.entry);
|
|
781
816
|
}
|
|
782
817
|
function unescapeTomlString(value) {
|
|
783
818
|
return value.replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
@@ -808,10 +843,10 @@ function savedEntryUrl(saved) {
|
|
|
808
843
|
const match = saved.block.match(/^\s*url\s*=\s*"((?:\\.|[^"])*)"/m);
|
|
809
844
|
return match ? unescapeTomlString(match[1]) : undefined;
|
|
810
845
|
}
|
|
811
|
-
function readJsonMcpServerEntries(file) {
|
|
846
|
+
function readJsonMcpServerEntries(client, file) {
|
|
812
847
|
try {
|
|
813
848
|
const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
814
|
-
const servers = parsed?.
|
|
849
|
+
const servers = parsed?.[jsonMcpConfigKeyForClient(client)];
|
|
815
850
|
if (!servers || typeof servers !== "object" || Array.isArray(servers)) {
|
|
816
851
|
return [];
|
|
817
852
|
}
|
|
@@ -881,7 +916,7 @@ function readExistingMcpEntries(clients, baseDir, scope) {
|
|
|
881
916
|
const file = configPathFor(client, baseDir, scope);
|
|
882
917
|
const rawEntries = client === "codex"
|
|
883
918
|
? readCodexMcpServerEntries(file)
|
|
884
|
-
: readJsonMcpServerEntries(file);
|
|
919
|
+
: readJsonMcpServerEntries(client, file);
|
|
885
920
|
for (const { serverName, saved } of rawEntries) {
|
|
886
921
|
const url = savedEntryUrl(saved);
|
|
887
922
|
if (!url)
|
|
@@ -912,7 +947,12 @@ function savedEntryHeaders(saved) {
|
|
|
912
947
|
if (!saved)
|
|
913
948
|
return {};
|
|
914
949
|
if (saved.kind === "json") {
|
|
915
|
-
const headers = saved.entry.headers
|
|
950
|
+
const headers = saved.entry.headers ??
|
|
951
|
+
(saved.entry.requestInit &&
|
|
952
|
+
typeof saved.entry.requestInit === "object" &&
|
|
953
|
+
!Array.isArray(saved.entry.requestInit)
|
|
954
|
+
? saved.entry.requestInit.headers
|
|
955
|
+
: undefined);
|
|
916
956
|
return headers && typeof headers === "object"
|
|
917
957
|
? Object.fromEntries(Object.entries(headers)
|
|
918
958
|
.filter((entry) => {
|
|
@@ -1526,12 +1566,11 @@ async function connectOne(rawUrl, parsed, clients, deps) {
|
|
|
1526
1566
|
// ADDITIONAL write alongside the per-client MCP config; Best-effort and
|
|
1527
1567
|
// merge-not-clobber — never fails the connect.
|
|
1528
1568
|
//
|
|
1529
|
-
// OAuth clients
|
|
1530
|
-
//
|
|
1531
|
-
//
|
|
1532
|
-
//
|
|
1533
|
-
//
|
|
1534
|
-
// connect` right after they just ran it.
|
|
1569
|
+
// OAuth clients authenticate in-host via standard MCP OAuth, so they never
|
|
1570
|
+
// mint a local bearer token. To still populate the publish store for them, we
|
|
1571
|
+
// run a supplemental device-flow mint using a non-OAuth client arg so the
|
|
1572
|
+
// Plans server gets a usable token and `publish-visual-plan` doesn't send the
|
|
1573
|
+
// user back to `agent-native connect` right after they just ran it.
|
|
1535
1574
|
let publishToken = token;
|
|
1536
1575
|
if (!publishToken &&
|
|
1537
1576
|
oauthClients.length > 0 &&
|
|
@@ -1579,7 +1618,9 @@ async function connectOne(rawUrl, parsed, clients, deps) {
|
|
|
1579
1618
|
logOut(` Replaced legacy bearer headers for ${clientLabelList(oauthMigrations)}; it will reconnect with standard MCP OAuth.`);
|
|
1580
1619
|
}
|
|
1581
1620
|
logOut(` ${clientLabelList(oauthClients)}: wrote URL-only MCP config (no bearer headers).`);
|
|
1582
|
-
|
|
1621
|
+
for (const line of oauthNextStepsForClients(oauthClients, serverName)) {
|
|
1622
|
+
logOut(` Next: ${line}`);
|
|
1623
|
+
}
|
|
1583
1624
|
}
|
|
1584
1625
|
logOut("");
|
|
1585
1626
|
logOut(` Restart or reload ${sentenceClientLabelList(clients)} to pick up the new MCP server.`);
|
|
@@ -1762,16 +1803,16 @@ Usage:
|
|
|
1762
1803
|
|
|
1763
1804
|
npx @agent-native/core@latest connect <url> [--client <c>] [--scope user|project] [--name <n>]
|
|
1764
1805
|
Writes the HTTP MCP entry into your selected client config(s). Claude
|
|
1765
|
-
Code /
|
|
1766
|
-
|
|
1806
|
+
Code, Cursor, OpenCode, and GitHub Copilot / VS Code use standard remote
|
|
1807
|
+
MCP OAuth and get URL-only config. Codex / Cowork use the browser
|
|
1767
1808
|
device-code fallback: the command prints a code, opens the verification
|
|
1768
1809
|
URL, polls until approved, then writes bearer headers. With no --client,
|
|
1769
1810
|
opens a brief picker preselected from ~/.agent-native/connect.json, or
|
|
1770
1811
|
all clients on first run. Idempotent — re-running replaces the same entry.
|
|
1771
1812
|
Auth is stored per client config/session; restart or reload each selected
|
|
1772
1813
|
client before expecting new tools to appear.
|
|
1773
|
-
Re-running over an older
|
|
1774
|
-
OAuth config and prompts you to authenticate
|
|
1814
|
+
Re-running over an older OAuth-capable bearer entry upgrades it to
|
|
1815
|
+
URL-only OAuth config and prompts you to authenticate in that host.
|
|
1775
1816
|
|
|
1776
1817
|
For cross-app access, prefer the unified Dispatch gateway:
|
|
1777
1818
|
npx @agent-native/core@latest connect https://dispatch.agent-native.com
|
|
@@ -1808,7 +1849,7 @@ Developer:
|
|
|
1808
1849
|
npx @agent-native/core@latest connect prod [--apps mail,calendar] [--client <c>]
|
|
1809
1850
|
Restore production MCP entries saved before the dev switch.
|
|
1810
1851
|
|
|
1811
|
-
Clients: all (default), claude-code, claude-code-cli, codex, cowork
|
|
1852
|
+
Clients: all (default), claude-code, claude-code-cli, codex, cowork, cursor, opencode, github-copilot
|
|
1812
1853
|
Scope: user (default, ~/.claude.json) or project (.mcp.json)`;
|
|
1813
1854
|
/**
|
|
1814
1855
|
* `agent-native connect` entry point. `deps` is injectable for tests; the
|