@m2canvas/connect 0.2.0 → 0.3.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 CHANGED
@@ -10,7 +10,7 @@ It finds the supported clients you have installed, shows what it will change, an
10
10
 
11
11
  **In a terminal**, it asks before changing anything and opens each client's browser sign-in, so one command finishes the whole setup.
12
12
 
13
- **Run by an agent** (no interactive terminal, e.g. pasted from M2's "Copy to agent"), it adds the server to every client without asking, skips the sign-ins it can't run there, and prints the remaining steps: a command to run (Codex, Cursor, OpenCode) or a place to click in the app (Claude Code, Qoder). The agent can run the commands or pass the steps on to you. Running it again lists the sign-in steps for clients that were already added.
13
+ **Run by an agent** (no interactive terminal, e.g. pasted from M2's "Copy to agent"), the agent passes `--client <id>` (`claude-code`, `codex`, `cursor`, `opencode`, `qoder`) so only its own client is touched. It adds the server without asking, skips the sign-ins it can't run there, and prints the remaining steps: a command to run (Codex, Cursor, OpenCode) or a place to click in the app (Claude Code, Qoder). The agent can run the commands or pass the steps on to you. Running it again lists the sign-in steps for clients that were already added.
14
14
 
15
15
  | Client | How it is set up | Sign-in |
16
16
  |---|---|---|
@@ -22,6 +22,6 @@ It finds the supported clients you have installed, shows what it will change, an
22
22
 
23
23
  Clients that already have an entry pointing at `mcp.m2ui.ai`, under any name, are skipped. Before a config file is edited, the original is copied to `<file>.bak-m2canvas`.
24
24
 
25
- Options: `--dry-run` shows the plan without changing anything; `--yes` skips the confirmation.
25
+ Options: `--client <id>` sets up only that client; `--dry-run` shows the plan without changing anything; `--yes` skips the confirmation.
26
26
 
27
27
  After setup, restart each client so it loads the new server.
package/dist/cli.js CHANGED
@@ -8,9 +8,10 @@
8
8
  // 所以只写入配置,把剩余授权步骤打印成 agent 可以照做 / 转述给用户的清单。
9
9
  import { createInterface } from 'node:readline/promises';
10
10
  import { M2_MCP_URL, SERVER_NAME } from './config-files.js';
11
- import { detectClients } from './clients.js';
11
+ import { CLIENTS, detectClients, isClientId } from './clients.js';
12
12
  import { run } from './system.js';
13
- const HELP = `Usage: npx @m2canvas/connect [--yes] [--dry-run]
13
+ const CLIENT_IDS = Object.keys(CLIENTS).join(', ');
14
+ const HELP = `Usage: npx @m2canvas/connect [--client <id>] [--yes] [--dry-run]
14
15
 
15
16
  Adds M2 Canvas (${M2_MCP_URL}) to every agent client found on this machine
16
17
  (Claude Code, Codex, Cursor, OpenCode, Qoder), then signs each one in.
@@ -19,6 +20,7 @@ In a terminal it asks before changing anything and opens each sign-in in your br
19
20
  When run by an agent (no terminal), it only adds the server and prints the remaining
20
21
  sign-in steps.
21
22
 
23
+ --client <id> only set up this client (${CLIENT_IDS})
22
24
  -y, --yes skip the confirmation prompt
23
25
  --dry-run only show what would change
24
26
  -h, --help show this help`;
@@ -59,13 +61,27 @@ function describePending(step) {
59
61
  return step.manual ?? '';
60
62
  }
61
63
  async function main() {
62
- const args = new Set(process.argv.slice(2));
64
+ const argv = process.argv.slice(2);
65
+ const args = new Set(argv);
63
66
  if (args.has('-h') || args.has('--help')) {
64
67
  console.log(HELP);
65
68
  return 0;
66
69
  }
67
70
  const interactive = Boolean(process.stdin.isTTY);
68
- const plans = detectClients();
71
+ // agent 代跑时由起手式带上自己的 --client:只处理这一家,其他客户端不动、不提 ——
72
+ // 用户只是在一个客户端里粘了一段话,不该顺带改掉、也不该被列出别的客户端。
73
+ const clientIndex = argv.indexOf('--client');
74
+ const requested = clientIndex >= 0 ? (argv[clientIndex + 1] ?? '') : null;
75
+ if (requested !== null && !isClientId(requested)) {
76
+ console.error(`Unknown --client "${requested}". Use one of: ${CLIENT_IDS}.`);
77
+ return 2;
78
+ }
79
+ const only = requested ?? undefined;
80
+ const plans = detectClients(only);
81
+ if (only && plans.length === 0) {
82
+ console.log(`Couldn't find a working ${only} CLI on this machine.\nAdd this MCP server by hand instead: ${M2_MCP_URL} (streamable HTTP, OAuth sign-in).`);
83
+ return 1;
84
+ }
69
85
  if (plans.length === 0) {
70
86
  console.log(`No supported agent client found.\nAdd this MCP server in your client by hand: ${M2_MCP_URL} (streamable HTTP, OAuth sign-in).`);
71
87
  return 1;
package/dist/clients.js CHANGED
@@ -136,6 +136,18 @@ function cursor() {
136
136
  },
137
137
  };
138
138
  }
139
- export function detectClients() {
140
- return [claudeCode(), codex(), cursor(), opencode(), qoder()].filter((plan) => plan !== null);
139
+ /** `--client` 的取值 → 探测函数。探测会真跑 `--version`,所以按需只跑被点名的那家。 */
140
+ export const CLIENTS = {
141
+ 'claude-code': claudeCode,
142
+ codex,
143
+ cursor,
144
+ opencode,
145
+ qoder,
146
+ };
147
+ export function isClientId(value) {
148
+ return Object.hasOwn(CLIENTS, value);
149
+ }
150
+ export function detectClients(only) {
151
+ const ids = only ? [only] : Object.keys(CLIENTS);
152
+ return ids.map((id) => CLIENTS[id]()).filter((plan) => plan !== null);
141
153
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m2canvas/connect",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Connect your local agent clients (Claude Code, Codex, Cursor, OpenCode, Qoder) to M2 Canvas over MCP in one command.",
5
5
  "type": "module",
6
6
  "bin": {