@super-hands/connect 0.1.9 → 0.1.16
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 +22 -2
- package/client.mjs +189 -30
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -27,7 +27,27 @@ variable too.
|
|
|
27
27
|
carries no credential.
|
|
28
28
|
|
|
29
29
|
With no flags it connects every client it finds; `--cursor`, `--claude` or
|
|
30
|
-
`--codex` narrow it to one.
|
|
30
|
+
`--codex` narrow it to one. Re-running it later to pick up a newer skill needs
|
|
31
|
+
no credential — see `update`, below.
|
|
32
|
+
|
|
33
|
+
## Updating it
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
npx -y @super-hands/connect@latest update
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Brings the skill on an already-connected machine up to whatever this build
|
|
40
|
+
ships. It takes **no token**: it reads the endpoint and the credential back out
|
|
41
|
+
of the configs the install wrote, so there is nothing to fetch from Superhands
|
|
42
|
+
and nothing new is minted. It touches no MCP entry — the entry is how the
|
|
43
|
+
credential was found, so it is already right.
|
|
44
|
+
|
|
45
|
+
A client counts as connected when its own config names the `superhands` server;
|
|
46
|
+
anything else is skipped, and a machine with no Superhands entry at all is told
|
|
47
|
+
to install first rather than half-connected. An installed skill at the same
|
|
48
|
+
version or newer is left alone, so your own edits survive an update and the run
|
|
49
|
+
says which files it left as they were. The same `--cursor` / `--claude` /
|
|
50
|
+
`--codex` flags narrow it to one client.
|
|
31
51
|
|
|
32
52
|
## Removing it
|
|
33
53
|
|
|
@@ -57,6 +77,6 @@ into the client configs above. The token can be revoked at any time from the
|
|
|
57
77
|
Superhands MCP page.
|
|
58
78
|
|
|
59
79
|
This file is generated from
|
|
60
|
-
[`lib/connect-client-entry.ts`](https://github.com/superhandsai/
|
|
80
|
+
[`lib/connect-client-entry.ts`](https://github.com/superhandsai/superhands/blob/main/lib/connect-client-entry.ts)
|
|
61
81
|
in the Superhands repository — the published bytes are that commit's, and are
|
|
62
82
|
not minified.
|
package/client.mjs
CHANGED
|
@@ -24,6 +24,7 @@ var CONNECT_URL_ENV = "SUPERHANDS_MCP_URL";
|
|
|
24
24
|
var CONNECT_DEFAULT_MCP_URL = "https://app.superhands.ai/api/mcp";
|
|
25
25
|
var CONNECT_CLIENT_PACKAGE = "@super-hands/connect";
|
|
26
26
|
var CONNECT_CLIENT_SPEC = `${CONNECT_CLIENT_PACKAGE}@latest`;
|
|
27
|
+
var CONNECT_UPDATE_COMMAND = `npx -y ${CONNECT_CLIENT_SPEC} update`;
|
|
27
28
|
var MCP_SERVER_KEY = "superhands";
|
|
28
29
|
function mcpAuthorizationHeader(token) {
|
|
29
30
|
return `Bearer ${token}`;
|
|
@@ -40,11 +41,11 @@ function codexConfigBlock(args) {
|
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
// lib/connect-skill.ts
|
|
43
|
-
var CONNECT_SKILL_VERSION =
|
|
44
|
+
var CONNECT_SKILL_VERSION = 11;
|
|
44
45
|
var CONNECT_SKILL_DIR = MCP_SERVER_KEY;
|
|
45
46
|
var CONNECT_SKILL_FILENAME = "SKILL.md";
|
|
46
47
|
var VERSION_MARKER = `[//]: # (superhands-skill-version: ${CONNECT_SKILL_VERSION})`;
|
|
47
|
-
var CONNECT_SKILL_DESCRIPTION = `Build UI the way this team has decided it should be built. Use BEFORE building, changing, or restyling any page, screen, view, form, or component \u2014 "build a page", "add a screen", "create a form", "make a dashboard", "redesign this", "new landing page" \u2014 and when asked how this product should look or behave. Reads the team's
|
|
48
|
+
var CONNECT_SKILL_DESCRIPTION = `Build UI the way this team has decided it should be built. Use BEFORE building, changing, or restyling any page, screen, view, form, or component \u2014 "build a page", "add a screen", "create a form", "make a dashboard", "redesign this", "new landing page" \u2014 and when asked how this product should look or behave. Reads the team's build-time Instructions from their Superhands MCP server.`;
|
|
48
49
|
var CONNECT_SKILL_CONTENT = `---
|
|
49
50
|
name: ${CONNECT_SKILL_DIR}
|
|
50
51
|
description: ${CONNECT_SKILL_DESCRIPTION}
|
|
@@ -55,35 +56,96 @@ ${VERSION_MARKER}
|
|
|
55
56
|
# Superhands
|
|
56
57
|
|
|
57
58
|
This machine is connected to the team's Superhands server over MCP (server
|
|
58
|
-
key \`${MCP_SERVER_KEY}\`). It holds the
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
key \`${MCP_SERVER_KEY}\`). It holds the team's build-time **Instructions**:
|
|
60
|
+
team-authored decisions, imported procedures, examples and conventions that all
|
|
61
|
+
describe how agents should build in this product. Source labels tell you where
|
|
62
|
+
an instruction came from and how to read it; they are not a choice about which
|
|
63
|
+
half to follow.
|
|
61
64
|
|
|
62
65
|
Before you build, change, or restyle any UI:
|
|
63
66
|
|
|
64
|
-
1. Call the \`
|
|
67
|
+
1. Call the \`superhands_get_instructions\` MCP tool with \`intent\` set to what
|
|
65
68
|
you have been asked to build, in plain language \u2014 for example "a sign-in
|
|
66
69
|
page with email and password and an error state", and
|
|
67
70
|
\`skill_version: ${CONNECT_SKILL_VERSION}\` \u2014 the version of this file, so
|
|
68
|
-
the server can tell you when this file is out of date. The
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
the server can tell you when this file is out of date. The corpus comes
|
|
72
|
+
back narrowed to that work, with everything not chosen still named.
|
|
73
|
+
- Pass \`paths\` too, when you already know which files this work touches \u2014
|
|
74
|
+
the handful you have open or are about to edit, repository-relative, for
|
|
75
|
+
example \`["app/marketing/pricing.tsx"]\`. The team writes down where
|
|
76
|
+
Instructions apply, and a path answers that far better than a description
|
|
77
|
+
does. Leave it out if you do not know yet; it narrows nothing away.
|
|
78
|
+
- If that tool is not available on this server, it is an older deployment:
|
|
79
|
+
call \`superhands_get_guidance\` and \`superhands_get_skill\` instead,
|
|
80
|
+
with the same \`intent\` \u2014 those two are older and take no \`paths\`.
|
|
81
|
+
2. Plan against what comes back, and note which parts of your plan each set of
|
|
82
|
+
keys covers. The first answer renders what to read first, then names
|
|
83
|
+
under **Reachable** the modules judged to matter to parts you have not
|
|
84
|
+
started \u2014 those keys are what the next step asks with \u2014 and ends with an
|
|
85
|
+
index of the modules it did **not** choose, for anything the selection
|
|
86
|
+
missed. A part of your plan with no keys against it is a real gap in what
|
|
87
|
+
the team has written down; say so rather than quietly using your own
|
|
88
|
+
defaults.
|
|
89
|
+
3. As you start each part \u2014 the sidebar, then the table, then the form \u2014 call
|
|
90
|
+
\`superhands_get_playbook_modules\` with the reachable keys covering the
|
|
91
|
+
part you are starting now and \`part\` set to that part in a few words,
|
|
92
|
+
for example \`"the form's validation errors"\`. A key ending in \`*\` takes
|
|
93
|
+
everything under it, so \`better-ui/*\` is a whole skill and
|
|
94
|
+
\`better-ui/SKILL#*\` is one file. It runs no selection and makes no model
|
|
95
|
+
call, so it is a plain, fast lookup and it returns exactly what you named.
|
|
96
|
+
- **Expect to make this call several times in one task.** A contact form is
|
|
97
|
+
not one part: it is the form, then its inputs, then its buttons, then its
|
|
98
|
+
validation errors, then its loading and empty states. One read at the
|
|
99
|
+
start and nothing after it is the mistake this step exists to prevent.
|
|
100
|
+
- Fetch each part's modules **when you reach that part**, not all of them at
|
|
101
|
+
the start. These are instructions to follow, not facts to know, so modules
|
|
102
|
+
for a part you are not building are a page of directions about the wrong
|
|
103
|
+
thing sitting in your context while you work.
|
|
104
|
+
- Team-authored decision entries from step 1 need no such loop. They are
|
|
105
|
+
concise enough to stay in the opening brief, so one read at the start is
|
|
106
|
+
the right read.
|
|
107
|
+
- If that tool is not available on this server, it is an older deployment:
|
|
108
|
+
build from what step 1 already returned and skip this step. Do not ask
|
|
109
|
+
for the whole library instead \u2014 that is the wall of text step 1 avoided.
|
|
110
|
+
4. Build to what comes back. Use the selected Instructions together. When two
|
|
111
|
+
entries pull in different directions, prefer the more specific instruction,
|
|
112
|
+
preserve explicit exceptions, and call out any conflict you cannot honestly
|
|
113
|
+
resolve.
|
|
114
|
+
5. When you have finished \u2014 not part-way through \u2014 send the files you wrote or
|
|
73
115
|
changed with \`superhands_report_completed_build\`, naming the \`route\` if
|
|
74
116
|
you know it. The team looks at what their agents build there; it records
|
|
75
117
|
and does not review, so a failed report costs the work nothing.
|
|
76
|
-
|
|
77
|
-
work
|
|
78
|
-
|
|
118
|
+
6. When you finish, say you followed the team's Instructions \u2014 never that your
|
|
119
|
+
work was checked. Reading Instructions is not a check, reporting a build is
|
|
120
|
+
not a review, and nothing has looked at what you built.
|
|
79
121
|
|
|
80
|
-
If the tool answers \`no-
|
|
81
|
-
|
|
122
|
+
If the tool answers \`no-instructions\` (or \`no-guidance\` from an older
|
|
123
|
+
server), carry on with what you were asked for and mention that the team
|
|
124
|
+
adds its Instructions on the Superhands Instructions page.
|
|
82
125
|
|
|
83
126
|
If the \`${MCP_SERVER_KEY}\` MCP server is not reachable in this session, say
|
|
84
127
|
so rather than guessing at the team's decisions \u2014 it is configured on this
|
|
85
128
|
machine, so a missing connection is worth telling the person about.
|
|
86
129
|
|
|
130
|
+
## Updating Superhands on this machine
|
|
131
|
+
|
|
132
|
+
If the person asks to update or upgrade Superhands, or if a Superhands tool
|
|
133
|
+
tells you this file is out of date, run:
|
|
134
|
+
|
|
135
|
+
\`\`\`
|
|
136
|
+
${CONNECT_UPDATE_COMMAND}
|
|
137
|
+
\`\`\`
|
|
138
|
+
|
|
139
|
+
and tell them what it printed. It reuses the credential already configured on
|
|
140
|
+
this machine, so it needs no token and mints nothing \u2014 it only brings this file
|
|
141
|
+
up to whatever the team's server now expects. Add \`--claude\`, \`--cursor\` or
|
|
142
|
+
\`--codex\` to update one client and leave the rest.
|
|
143
|
+
|
|
144
|
+
Run it when you are asked, or when you have finished the work in front of you \u2014
|
|
145
|
+
never in the middle of a build. The guidance you were given came from the
|
|
146
|
+
server, not from this file, so it is current either way and there is nothing to
|
|
147
|
+
redo.
|
|
148
|
+
|
|
87
149
|
## Removing Superhands from this machine
|
|
88
150
|
|
|
89
151
|
If the person asks to uninstall, remove, or disconnect Superhands, run:
|
|
@@ -171,6 +233,21 @@ function cursorConfigWithoutServer(existing) {
|
|
|
171
233
|
return { text: `${JSON.stringify(config, null, 2)}
|
|
172
234
|
`, removed: true };
|
|
173
235
|
}
|
|
236
|
+
function cursorNamesServer(existing) {
|
|
237
|
+
if (!existing || existing.trim() === "") return false;
|
|
238
|
+
let parsed;
|
|
239
|
+
try {
|
|
240
|
+
parsed = JSON.parse(existing);
|
|
241
|
+
} catch {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
const servers = parsed?.mcpServers;
|
|
245
|
+
if (typeof servers !== "object" || servers === null || Array.isArray(servers)) return false;
|
|
246
|
+
return MCP_SERVER_KEY in servers;
|
|
247
|
+
}
|
|
248
|
+
function codexNamesServer(existing) {
|
|
249
|
+
return existing.includes(`[mcp_servers.${MCP_SERVER_KEY}]`);
|
|
250
|
+
}
|
|
174
251
|
function cursorConnection(existing) {
|
|
175
252
|
if (!existing || existing.trim() === "") return null;
|
|
176
253
|
let parsed;
|
|
@@ -220,24 +297,30 @@ function appendedCodexConfig(existing, args) {
|
|
|
220
297
|
return { text: `${existing}${sep}${codexConfigBlock(args)}
|
|
221
298
|
`, alreadyPresent: false, repaired: false };
|
|
222
299
|
}
|
|
223
|
-
function
|
|
224
|
-
|
|
225
|
-
|
|
300
|
+
function skillPathIn(clientDir) {
|
|
301
|
+
return join(clientDir, "skills", CONNECT_SKILL_DIR, CONNECT_SKILL_FILENAME);
|
|
302
|
+
}
|
|
303
|
+
function installedSkillVersionIn(clientDir) {
|
|
226
304
|
try {
|
|
227
|
-
|
|
305
|
+
return installedSkillVersion(readFileSync(skillPathIn(clientDir), "utf8"));
|
|
228
306
|
} catch {
|
|
229
|
-
|
|
307
|
+
return 0;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function writeSkill(clientDir) {
|
|
311
|
+
const skillPath = skillPathIn(clientDir);
|
|
312
|
+
const existingVersion = installedSkillVersionIn(clientDir);
|
|
313
|
+
if (existingVersion >= CONNECT_SKILL_VERSION) {
|
|
314
|
+
return { version: existingVersion, state: "current" };
|
|
230
315
|
}
|
|
231
|
-
const existingVersion = existing === "" ? 0 : installedSkillVersion(existing);
|
|
232
|
-
if (existingVersion >= CONNECT_SKILL_VERSION) return existingVersion;
|
|
233
316
|
try {
|
|
234
317
|
mkdirSync(dirname(skillPath), { recursive: true });
|
|
235
318
|
writeFileSync(skillPath, CONNECT_SKILL_CONTENT);
|
|
236
319
|
say(` Wrote the ${CONNECT_SKILL_DIR} skill to ${skillPath} \u2014 it routes UI work through the team's guidance.`);
|
|
237
|
-
return CONNECT_SKILL_VERSION;
|
|
320
|
+
return { version: CONNECT_SKILL_VERSION, state: "wrote" };
|
|
238
321
|
} catch {
|
|
239
322
|
say(` Could not write the ${CONNECT_SKILL_DIR} skill at ${skillPath}. The connection works without it.`);
|
|
240
|
-
return existingVersion;
|
|
323
|
+
return { version: existingVersion, state: "blocked" };
|
|
241
324
|
}
|
|
242
325
|
}
|
|
243
326
|
function connectReportUrl(endpoint) {
|
|
@@ -310,6 +393,11 @@ function claudeConnection() {
|
|
|
310
393
|
return null;
|
|
311
394
|
}
|
|
312
395
|
}
|
|
396
|
+
function claudeRegistration() {
|
|
397
|
+
const result = spawnSync("claude", ["mcp", "get", MCP_SERVER_KEY], { encoding: "utf8" });
|
|
398
|
+
if (result.error || result.status !== 0) return { registered: false, connection: null };
|
|
399
|
+
return { registered: true, connection: claudeConnectionFrom(result.stdout ?? "") };
|
|
400
|
+
}
|
|
313
401
|
function hasCli(bin) {
|
|
314
402
|
try {
|
|
315
403
|
execFileSync(bin, ["--version"], { stdio: "ignore" });
|
|
@@ -341,8 +429,11 @@ async function main() {
|
|
|
341
429
|
const flags = new Set(argv.filter((arg) => arg.startsWith("--")));
|
|
342
430
|
const command = argv.find((arg) => !arg.startsWith("--")) ?? "install";
|
|
343
431
|
if (command === "uninstall") return uninstall(flags);
|
|
432
|
+
if (command === "update") return update(flags);
|
|
344
433
|
if (command !== "install") {
|
|
345
|
-
stop(
|
|
434
|
+
stop(
|
|
435
|
+
`unknown command "${command}". This tool takes "install" (the default), "update" or "uninstall".`
|
|
436
|
+
);
|
|
346
437
|
}
|
|
347
438
|
return install(flags);
|
|
348
439
|
}
|
|
@@ -389,7 +480,7 @@ async function install(flags) {
|
|
|
389
480
|
} else {
|
|
390
481
|
say(` Open Cursor (restart it if it was running), then enable ${MCP_SERVER_KEY} under Settings \u2192 MCP.`);
|
|
391
482
|
}
|
|
392
|
-
skillVersions.push(writeSkill(cursorDir));
|
|
483
|
+
skillVersions.push(writeSkill(cursorDir).version);
|
|
393
484
|
connected += 1;
|
|
394
485
|
} catch {
|
|
395
486
|
say(`Cursor \u2014 ${configPath} could not be written, so it was left as it was.`);
|
|
@@ -430,7 +521,7 @@ async function install(flags) {
|
|
|
430
521
|
);
|
|
431
522
|
say(`Claude Code \u2014 added the ${MCP_SERVER_KEY} server (user scope).`);
|
|
432
523
|
say(" Open a new claude session and it connects on start.");
|
|
433
|
-
skillVersions.push(writeSkill(join(homedir(), ".claude")));
|
|
524
|
+
skillVersions.push(writeSkill(join(homedir(), ".claude")).version);
|
|
434
525
|
connected += 1;
|
|
435
526
|
} catch {
|
|
436
527
|
say("Claude Code \u2014 `claude mcp add` failed. Run it by hand from the Superhands MCP page.");
|
|
@@ -450,7 +541,7 @@ async function install(flags) {
|
|
|
450
541
|
if (result.alreadyPresent) {
|
|
451
542
|
say(`Codex \u2014 ${configPath} already names a ${MCP_SERVER_KEY} server, so it was left as it is.`);
|
|
452
543
|
say(" If that connection is stale, update the http_headers Authorization value there by hand.");
|
|
453
|
-
skillVersions.push(writeSkill(codexDir));
|
|
544
|
+
skillVersions.push(writeSkill(codexDir).version);
|
|
454
545
|
connected += 1;
|
|
455
546
|
} else {
|
|
456
547
|
try {
|
|
@@ -460,7 +551,7 @@ async function install(flags) {
|
|
|
460
551
|
result.repaired ? `Codex \u2014 replaced the ${MCP_SERVER_KEY} entry in ${configPath}: its old bearer_token spelling makes current Codex reject the whole config.` : `Codex \u2014 added the ${MCP_SERVER_KEY} server to ${configPath}.`
|
|
461
552
|
);
|
|
462
553
|
say(" The app and the CLI both read this config \u2014 open either and it connects when a session starts.");
|
|
463
|
-
skillVersions.push(writeSkill(codexDir));
|
|
554
|
+
skillVersions.push(writeSkill(codexDir).version);
|
|
464
555
|
connected += 1;
|
|
465
556
|
} catch {
|
|
466
557
|
say(`Codex \u2014 ${configPath} could not be written, so it was left as it was.`);
|
|
@@ -483,6 +574,74 @@ async function install(flags) {
|
|
|
483
574
|
}
|
|
484
575
|
say("Done. Superhands notices the moment an agent connects \u2014 setup ticks by itself.");
|
|
485
576
|
}
|
|
577
|
+
async function update(flags) {
|
|
578
|
+
const wanted = chosenClients(flags);
|
|
579
|
+
const cursorDir = join(homedir(), ".cursor");
|
|
580
|
+
const claudeDir = join(homedir(), ".claude");
|
|
581
|
+
const codexDir = join(homedir(), ".codex");
|
|
582
|
+
const found = [];
|
|
583
|
+
const skillVersions = [];
|
|
584
|
+
let configured = 0;
|
|
585
|
+
let rewritten = 0;
|
|
586
|
+
function refresh(product, clientDir, connection) {
|
|
587
|
+
configured += 1;
|
|
588
|
+
if (connection) found.push(connection);
|
|
589
|
+
const before = installedSkillVersionIn(clientDir);
|
|
590
|
+
if (before >= CONNECT_SKILL_VERSION) {
|
|
591
|
+
say(
|
|
592
|
+
`${product} \u2014 its ${CONNECT_SKILL_DIR} skill is already at version ${before}, so it was left as it is.`
|
|
593
|
+
);
|
|
594
|
+
} else if (before === 0) {
|
|
595
|
+
say(
|
|
596
|
+
`${product} \u2014 connected, but has no ${CONNECT_SKILL_DIR} skill; writing version ${CONNECT_SKILL_VERSION}.`
|
|
597
|
+
);
|
|
598
|
+
} else {
|
|
599
|
+
say(`${product} \u2014 updating its ${CONNECT_SKILL_DIR} skill from version ${before} to ${CONNECT_SKILL_VERSION}.`);
|
|
600
|
+
}
|
|
601
|
+
const result = writeSkill(clientDir);
|
|
602
|
+
skillVersions.push(result.version);
|
|
603
|
+
if (result.state === "wrote") rewritten += 1;
|
|
604
|
+
}
|
|
605
|
+
if (wanted.cursor) {
|
|
606
|
+
let text = null;
|
|
607
|
+
try {
|
|
608
|
+
text = readFileSync(join(cursorDir, "mcp.json"), "utf8");
|
|
609
|
+
} catch {
|
|
610
|
+
text = null;
|
|
611
|
+
}
|
|
612
|
+
if (cursorNamesServer(text)) refresh("Cursor", cursorDir, cursorConnection(text));
|
|
613
|
+
}
|
|
614
|
+
if (wanted.claude) {
|
|
615
|
+
const claude = claudeRegistration();
|
|
616
|
+
if (claude.registered) refresh("Claude Code", claudeDir, claude.connection);
|
|
617
|
+
}
|
|
618
|
+
if (wanted.codex) {
|
|
619
|
+
let text = "";
|
|
620
|
+
try {
|
|
621
|
+
text = readFileSync(join(codexDir, "config.toml"), "utf8");
|
|
622
|
+
} catch {
|
|
623
|
+
text = "";
|
|
624
|
+
}
|
|
625
|
+
if (codexNamesServer(text)) refresh("Codex", codexDir, codexConnection(text));
|
|
626
|
+
}
|
|
627
|
+
if (configured === 0) {
|
|
628
|
+
say(
|
|
629
|
+
wanted.explicit ? "Nothing to update \u2014 none of the clients you named has a Superhands server configured." : "Nothing to update \u2014 no client on this machine has a Superhands server configured."
|
|
630
|
+
);
|
|
631
|
+
say(" Connect one first with the command on the Superhands Agents page; it carries the credential.");
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
const installed = skillVersions.length > 0 ? Math.min(...skillVersions) : 0;
|
|
635
|
+
if (installed > 0) {
|
|
636
|
+
const unique = new Map(found.map((c) => [`${c.endpoint}\0${c.token}`, c]));
|
|
637
|
+
for (const connection of unique.values()) {
|
|
638
|
+
await reportSkillVersion({ ...connection, version: installed });
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
say(
|
|
642
|
+
rewritten > 0 ? "Done. Open a new session in any client that was already running \u2014 a skill is read when a session starts." : "Done. Everything on this machine was already up to date."
|
|
643
|
+
);
|
|
644
|
+
}
|
|
486
645
|
async function uninstall(flags) {
|
|
487
646
|
const wanted = chosenClients(flags);
|
|
488
647
|
const cursorDir = join(homedir(), ".cursor");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@super-hands/connect",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Connect the coding agents on this machine to your team's Superhands MCP server, and take it back off again with `uninstall`. Writes each client's own config; reads no repository, uploads nothing.",
|
|
3
|
+
"version": "0.1.16",
|
|
4
|
+
"description": "Connect the coding agents on this machine to your team's Superhands MCP server, refresh it later with `update` (no token needed), and take it back off again with `uninstall`. Writes each client's own config; reads no repository, uploads nothing.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"superhands-connect": "client.mjs"
|
|
7
7
|
},
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/superhandsai/
|
|
19
|
+
"url": "git+https://github.com/superhandsai/superhands.git",
|
|
20
20
|
"directory": "packages/connect-client"
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://app.superhands.ai",
|