aimeat 2.6.0 → 2.7.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 +57 -0
- package/dist/build-stamp.json +4 -4
- package/dist/public/changelog.json +13 -0
- package/dist/src/cli/connect/clients/claude.d.ts +22 -0
- package/dist/src/cli/connect/clients/claude.d.ts.map +1 -0
- package/dist/src/cli/connect/clients/claude.js +105 -0
- package/dist/src/cli/connect/clients/claude.js.map +1 -0
- package/dist/src/cli/connect/clients/cursor-vscode.d.ts +17 -0
- package/dist/src/cli/connect/clients/cursor-vscode.d.ts.map +1 -0
- package/dist/src/cli/connect/clients/cursor-vscode.js +88 -0
- package/dist/src/cli/connect/clients/cursor-vscode.js.map +1 -0
- package/dist/src/cli/connect/clients/fs-merge.d.ts +35 -0
- package/dist/src/cli/connect/clients/fs-merge.d.ts.map +1 -0
- package/dist/src/cli/connect/clients/fs-merge.js +87 -0
- package/dist/src/cli/connect/clients/fs-merge.js.map +1 -0
- package/dist/src/cli/connect/clients/goose.d.ts +15 -0
- package/dist/src/cli/connect/clients/goose.d.ts.map +1 -0
- package/dist/src/cli/connect/clients/goose.js +67 -0
- package/dist/src/cli/connect/clients/goose.js.map +1 -0
- package/dist/src/cli/connect/clients/index.d.ts +23 -0
- package/dist/src/cli/connect/clients/index.d.ts.map +1 -0
- package/dist/src/cli/connect/clients/index.js +148 -0
- package/dist/src/cli/connect/clients/index.js.map +1 -0
- package/dist/src/cli/connect/clients/launcher.d.ts +33 -0
- package/dist/src/cli/connect/clients/launcher.d.ts.map +1 -0
- package/dist/src/cli/connect/clients/launcher.js +94 -0
- package/dist/src/cli/connect/clients/launcher.js.map +1 -0
- package/dist/src/cli/connect/clients/types.d.ts +63 -0
- package/dist/src/cli/connect/clients/types.d.ts.map +1 -0
- package/dist/src/cli/connect/clients/types.js +16 -0
- package/dist/src/cli/connect/clients/types.js.map +1 -0
- package/dist/src/generated/api-types.d.ts +117 -3
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/index-connect.d.ts.map +1 -1
- package/dist/src/index-connect.js +4 -0
- package/dist/src/index-connect.js.map +1 -1
- package/dist/src/index-help.d.ts +2 -2
- package/dist/src/index-help.d.ts.map +1 -1
- package/dist/src/index-help.js +16 -0
- package/dist/src/index-help.js.map +1 -1
- package/dist/src/mcp/ai-provenance-input.d.ts.map +1 -1
- package/dist/src/mcp/ai-provenance-input.js +6 -2
- package/dist/src/mcp/ai-provenance-input.js.map +1 -1
- package/dist/src/models/ai-provenance-schemas.d.ts +17 -0
- package/dist/src/models/ai-provenance-schemas.d.ts.map +1 -1
- package/dist/src/models/ai-provenance-schemas.js +18 -1
- package/dist/src/models/ai-provenance-schemas.js.map +1 -1
- package/dist/src/routes/ai-provenance.d.ts.map +1 -1
- package/dist/src/routes/ai-provenance.js +23 -2
- package/dist/src/routes/ai-provenance.js.map +1 -1
- package/dist/src/routes/workflows.d.ts.map +1 -1
- package/dist/src/routes/workflows.js +25 -0
- package/dist/src/routes/workflows.js.map +1 -1
- package/dist/src/services/ai-provenance-page.d.ts +18 -0
- package/dist/src/services/ai-provenance-page.d.ts.map +1 -1
- package/dist/src/services/ai-provenance-page.js +43 -1
- package/dist/src/services/ai-provenance-page.js.map +1 -1
- package/dist/src/utils/build-stamp.d.ts.map +1 -1
- package/dist/src/utils/build-stamp.js +12 -1
- package/dist/src/utils/build-stamp.js.map +1 -1
- package/package.json +3 -2
- package/scripts/vendor-libs.mjs +144 -0
package/README.md
CHANGED
|
@@ -182,6 +182,60 @@ An app is also an **agent surface**: any function it exposes can be published as
|
|
|
182
182
|
|
|
183
183
|
## What You Can Do
|
|
184
184
|
|
|
185
|
+
### Use the AI chat you like, with your node in it
|
|
186
|
+
|
|
187
|
+
One command connects **Goose, Claude Code, Cursor, VS Code or Claude Desktop** to your node:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
aimeat connect client goose --url https://aimeat.io --owner your-handle
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
It does three things. It authorizes an agent **of its own** for that program (you approve it from your
|
|
194
|
+
profile -> Agents tab, as always). It writes the MCP settings in the shape that program expects,
|
|
195
|
+
merging into whatever you already had. And it leaves you a launcher script that starts the program
|
|
196
|
+
with the token supplied at run time.
|
|
197
|
+
|
|
198
|
+
| Client | How it reaches the node | Config it writes |
|
|
199
|
+
|---|---|---|
|
|
200
|
+
| `goose` | `POST /v1/mcp` | `config.yaml` -> `extensions` |
|
|
201
|
+
| `claude-code` | `POST /v1/mcp` | `claude mcp add-json`, user scope |
|
|
202
|
+
| `cursor` | `POST /v1/mcp` | `~/.cursor/mcp.json` |
|
|
203
|
+
| `vscode` | `POST /v1/mcp` | user `mcp.json` -> `servers` |
|
|
204
|
+
| `claude-desktop` | local connector over stdio | `claude_desktop_config.json` |
|
|
205
|
+
|
|
206
|
+
Options: `--agent <name>` names the agent, `--workdir <path>` decides where the program starts (an
|
|
207
|
+
agent writes files where it is launched, so this keeps it out of your source repos), `--surface
|
|
208
|
+
appdev` narrows the toolset to app building, `--home <path>` puts the credential somewhere else,
|
|
209
|
+
`--name <server>` lets a second node live alongside the first.
|
|
210
|
+
|
|
211
|
+
**Two guarantees, because this command edits files you own.** Your token is never written into a
|
|
212
|
+
config file: each client is given a variable reference, a headers-helper command, or the local
|
|
213
|
+
connector, and the token itself stays in the connector home. And every other MCP server you had
|
|
214
|
+
configured is left exactly as it was -- the command merges, backs the file up first, and refuses to
|
|
215
|
+
write at all if it cannot parse what is there.
|
|
216
|
+
|
|
217
|
+
After it runs you are talking to your own memory, apps, organisms, workspaces, tasks and the
|
|
218
|
+
marketplace from that window: "what do I have in my workspace", "build me an app that does X",
|
|
219
|
+
"what did my agents do today".
|
|
220
|
+
|
|
221
|
+
**Goose is the one to try if you want a chat that is not Claude, ChatGPT or Grok.** It is an open
|
|
222
|
+
source terminal agent that takes its model from **OpenRouter**, so you pick the model and pay per
|
|
223
|
+
token for exactly what you use -- a strong model for a hard build, a cheap one for everything else,
|
|
224
|
+
switched in seconds:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# a model for this session only
|
|
228
|
+
$env:GOOSE_MODEL = "z-ai/glm-5.2"; C:\Users\you\.aimeat-goose\launch-goose.ps1
|
|
229
|
+
GOOSE_MODEL=z-ai/glm-5.2 ~/.aimeat-goose/launch-goose.sh
|
|
230
|
+
|
|
231
|
+
# inside a running session
|
|
232
|
+
/model deepseek/deepseek-v3.2 # switch model without restarting
|
|
233
|
+
/mode auto # stop confirming every tool call
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Set `OPENROUTER_API_KEY` in your environment before launching. The full toolset costs roughly 50k
|
|
237
|
+
input tokens per turn; `--surface appdev` cuts that to about a third when you are only building apps.
|
|
238
|
+
|
|
185
239
|
### Connect AI agents
|
|
186
240
|
|
|
187
241
|
<img src="assets/screenshots/profile-agents.png" alt="Agent connection prompt" width="600" />
|
|
@@ -452,6 +506,9 @@ npx aimeat seed # seed example packages (in another terminal, server must be
|
|
|
452
506
|
|
|
453
507
|
# Or just connect an agent to someone else's node
|
|
454
508
|
npx aimeat connect --url https://your-node --owner your-handle
|
|
509
|
+
|
|
510
|
+
# Or point your own AI chat at a node in one command (goose | claude-code | cursor | vscode | claude-desktop)
|
|
511
|
+
npx aimeat connect client goose --url https://aimeat.io --owner your-handle
|
|
455
512
|
```
|
|
456
513
|
|
|
457
514
|
**App thumbnails (optional).** `aimeat screenshot-worker` renders each published app and stores a
|
package/dist/build-stamp.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": 1,
|
|
3
|
-
"version": "2.
|
|
4
|
-
"commit": "
|
|
3
|
+
"version": "2.7.0",
|
|
4
|
+
"commit": "c16f054a02c9198474fd62c9985ca0dcdb5419f0",
|
|
5
5
|
"dirty": false,
|
|
6
|
-
"built_at": "2026-08-
|
|
7
|
-
"newest_source_mtime":
|
|
6
|
+
"built_at": "2026-08-02T02:40:18.003Z",
|
|
7
|
+
"newest_source_mtime": 1785638212648.5315,
|
|
8
8
|
"source_dirs": [
|
|
9
9
|
"src",
|
|
10
10
|
"bin",
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_format": "Node change log, newest entry FIRST. Served at /changelog.json, rendered by public/views/landing-changelog.js. Add an entry in the same change that ships the thing. Fields: date (YYYY-MM-DD), version (optional, the node version it shipped in), kind (feature|fix|security|notice), title and body. title/body are either a plain string (shown to everyone) or { en, fi } when the wording deserves both languages. Write what a person gets, not what the code does.",
|
|
3
3
|
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"date": "2026-08-02",
|
|
6
|
+
"version": "2.7.0",
|
|
7
|
+
"kind": "feature",
|
|
8
|
+
"title": {
|
|
9
|
+
"en": "Use the AI chat you like, with your node in it",
|
|
10
|
+
"fi": "Käytä sitä tekoälychattia josta pidät, ja pidä nodesi mukana siinä"
|
|
11
|
+
},
|
|
12
|
+
"body": {
|
|
13
|
+
"en": "One command now connects Goose, Claude Code, Cursor, VS Code or Claude Desktop to your node: aimeat connect client goose. It creates an agent of its own for that program, writes the settings the program expects, and hands you a shortcut that starts it. From then on you can talk to your own data, apps and organisms from that window, with whichever model you pay for. It never writes your key into a settings file, and it leaves every other tool you had connected exactly as it was.",
|
|
14
|
+
"fi": "Yksi komento kytkee Goosen, Claude Coden, Cursorin, VS Coden tai Claude Desktopin nodeesi: aimeat connect client goose. Se luo ohjelmalle oman agentin, kirjoittaa asetukset siihen muotoon jota ohjelma odottaa, ja antaa sinulle pikakuvakkeen jolla se käynnistyy. Sen jälkeen voit jutella omalle datallesi, apeillesi ja organismeillesi siitä ikkunasta, sillä mallilla josta itse maksat. Avaintasi ei kirjoiteta asetustiedostoon, eikä yksikään aiemmin kytkemäsi työkalu muutu matkalla."
|
|
15
|
+
}
|
|
16
|
+
},
|
|
4
17
|
{
|
|
5
18
|
"date": "2026-08-01",
|
|
6
19
|
"version": "2.4.0",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file claude.ts
|
|
3
|
+
* @description Claude Code and Claude Desktop adapters. They are the two clients that do NOT take
|
|
4
|
+
* a plain remote entry with a token in it:
|
|
5
|
+
* - Claude Code has `headersHelper`, a command whose stdout becomes the request headers. That
|
|
6
|
+
* is strictly better than a static header: the token never enters ~/.claude.json and a
|
|
7
|
+
* re-authenticated agent is picked up without editing anything.
|
|
8
|
+
* - Claude Desktop's config file is stdio-only. A `url` field there is not merely ignored: the
|
|
9
|
+
* app drops the whole mcpServers block on startup. So Desktop is connected over the local
|
|
10
|
+
* connector (`aimeat connect serve`), which is a real stdio MCP server and needs no token in
|
|
11
|
+
* the file either.
|
|
12
|
+
* @structure
|
|
13
|
+
* - claudeCodeAdapter — runs `claude mcp add-json` when the CLI is present, prints it when not.
|
|
14
|
+
* - claudeDesktopAdapter — merges a stdio entry into claude_desktop_config.json.
|
|
15
|
+
* @usage Registered in clients/registry.ts as `claude-code` and `claude-desktop`.
|
|
16
|
+
* @version-history
|
|
17
|
+
* v1.0.0 — 2026-08-02 — Initial creation: one-command client connect.
|
|
18
|
+
*/
|
|
19
|
+
import type { ClientAdapter } from './types.js';
|
|
20
|
+
export declare const claudeCodeAdapter: ClientAdapter;
|
|
21
|
+
export declare const claudeDesktopAdapter: ClientAdapter;
|
|
22
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../../../src/cli/connect/clients/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,aAAa,EAA6B,MAAM,YAAY,CAAC;AAoB3E,eAAO,MAAM,iBAAiB,EAAE,aAyC/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,aAgClC,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file claude.ts
|
|
3
|
+
* @description Claude Code and Claude Desktop adapters. They are the two clients that do NOT take
|
|
4
|
+
* a plain remote entry with a token in it:
|
|
5
|
+
* - Claude Code has `headersHelper`, a command whose stdout becomes the request headers. That
|
|
6
|
+
* is strictly better than a static header: the token never enters ~/.claude.json and a
|
|
7
|
+
* re-authenticated agent is picked up without editing anything.
|
|
8
|
+
* - Claude Desktop's config file is stdio-only. A `url` field there is not merely ignored: the
|
|
9
|
+
* app drops the whole mcpServers block on startup. So Desktop is connected over the local
|
|
10
|
+
* connector (`aimeat connect serve`), which is a real stdio MCP server and needs no token in
|
|
11
|
+
* the file either.
|
|
12
|
+
* @structure
|
|
13
|
+
* - claudeCodeAdapter — runs `claude mcp add-json` when the CLI is present, prints it when not.
|
|
14
|
+
* - claudeDesktopAdapter — merges a stdio entry into claude_desktop_config.json.
|
|
15
|
+
* @usage Registered in clients/registry.ts as `claude-code` and `claude-desktop`.
|
|
16
|
+
* @version-history
|
|
17
|
+
* v1.0.0 — 2026-08-02 — Initial creation: one-command client connect.
|
|
18
|
+
*/
|
|
19
|
+
import { spawnSync } from 'node:child_process';
|
|
20
|
+
import { homedir } from 'node:os';
|
|
21
|
+
import { join } from 'node:path';
|
|
22
|
+
import { backup, objectAt, readJsonFile, writeJsonFile } from './fs-merge.js';
|
|
23
|
+
import { writeHeadersHelper } from './launcher.js';
|
|
24
|
+
function claudeCodeConfigPath() {
|
|
25
|
+
return join(homedir(), '.claude.json');
|
|
26
|
+
}
|
|
27
|
+
function claudeDesktopConfigPath() {
|
|
28
|
+
if (process.platform === 'win32') {
|
|
29
|
+
const appData = process.env.APPDATA ?? join(homedir(), 'AppData', 'Roaming');
|
|
30
|
+
return join(appData, 'Claude', 'claude_desktop_config.json');
|
|
31
|
+
}
|
|
32
|
+
if (process.platform === 'darwin') {
|
|
33
|
+
return join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
34
|
+
}
|
|
35
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config');
|
|
36
|
+
return join(xdg, 'Claude', 'claude_desktop_config.json');
|
|
37
|
+
}
|
|
38
|
+
export const claudeCodeAdapter = {
|
|
39
|
+
id: 'claude-code',
|
|
40
|
+
label: 'Claude Code',
|
|
41
|
+
transport: 'http',
|
|
42
|
+
configPath: claudeCodeConfigPath,
|
|
43
|
+
async apply(target) {
|
|
44
|
+
const helper = writeHeadersHelper(target);
|
|
45
|
+
const entry = {
|
|
46
|
+
type: 'http',
|
|
47
|
+
url: target.mcpUrl,
|
|
48
|
+
headersHelper: process.platform === 'win32'
|
|
49
|
+
? `powershell -NoProfile -File "${helper.ps1}"`
|
|
50
|
+
: helper.sh,
|
|
51
|
+
};
|
|
52
|
+
const addJson = `claude mcp add-json ${target.serverName} '${JSON.stringify(entry)}' --scope user`;
|
|
53
|
+
// ~/.claude.json holds far more than MCP servers, so let Claude Code write its own file
|
|
54
|
+
// rather than hand-editing it here.
|
|
55
|
+
const claude = spawnSync('claude', ['mcp', 'add-json', target.serverName, JSON.stringify(entry), '--scope', 'user'], {
|
|
56
|
+
encoding: 'utf8', shell: process.platform === 'win32',
|
|
57
|
+
});
|
|
58
|
+
if (claude.status === 0) {
|
|
59
|
+
return {
|
|
60
|
+
written: [helper.ps1, helper.sh],
|
|
61
|
+
backedUp: [],
|
|
62
|
+
nextSteps: [
|
|
63
|
+
'Added to Claude Code at user scope. Verify with: claude mcp list',
|
|
64
|
+
'The token stays out of the config: headersHelper reads it from the connector home at connect time.',
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
written: [helper.ps1, helper.sh],
|
|
70
|
+
backedUp: [],
|
|
71
|
+
manual: `The \`claude\` CLI was not usable here (${claude.error?.message ?? `exit ${String(claude.status)}`}). Run this yourself:\n\n ${addJson}`,
|
|
72
|
+
nextSteps: ['Then verify with: claude mcp list'],
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
export const claudeDesktopAdapter = {
|
|
77
|
+
id: 'claude-desktop',
|
|
78
|
+
label: 'Claude Desktop',
|
|
79
|
+
transport: 'stdio',
|
|
80
|
+
configPath: claudeDesktopConfigPath,
|
|
81
|
+
async apply(target) {
|
|
82
|
+
const file = claudeDesktopConfigPath();
|
|
83
|
+
const config = readJsonFile(file);
|
|
84
|
+
const bak = backup(file);
|
|
85
|
+
// NOTE: no `url` key here, deliberately. Claude Desktop discards the whole mcpServers block
|
|
86
|
+
// when it meets one. The connector is a genuine stdio MCP server and reads its own token.
|
|
87
|
+
const args = ['connect', 'serve'];
|
|
88
|
+
if (target.surface)
|
|
89
|
+
args.push('--surface', target.surface);
|
|
90
|
+
objectAt(config, 'mcpServers')[target.serverName] = process.platform === 'win32'
|
|
91
|
+
? { command: 'cmd', args: ['/c', 'aimeat', ...args], env: { AIMEAT_HOME: target.home } }
|
|
92
|
+
: { command: 'aimeat', args, env: { AIMEAT_HOME: target.home } };
|
|
93
|
+
writeJsonFile(file, config);
|
|
94
|
+
return {
|
|
95
|
+
written: [file],
|
|
96
|
+
backedUp: bak ? [bak] : [],
|
|
97
|
+
nextSteps: [
|
|
98
|
+
'Restart Claude Desktop, then check Settings > Developer for the aimeat server.',
|
|
99
|
+
'Desktop connects over the local connector (stdio), not the HTTP endpoint: its config file cannot carry a remote URL.',
|
|
100
|
+
`That connector serves the agent stored in ${target.home}.`,
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../../../src/cli/connect/clients/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file cursor-vscode.ts
|
|
3
|
+
* @description Cursor and VS Code adapters. Both keep a JSON MCP config and both expand
|
|
4
|
+
* `${env:NAME}` inside header values, so the token stays in the environment. They differ in the
|
|
5
|
+
* top-level key (`mcpServers` vs `servers`), in whether `type` is required, and in where the file
|
|
6
|
+
* lives.
|
|
7
|
+
* @structure
|
|
8
|
+
* - cursorAdapter — ~/.cursor/mcp.json, `mcpServers`.
|
|
9
|
+
* - vscodeAdapter — per-platform user mcp.json, `servers` with `type: http`.
|
|
10
|
+
* @usage Registered in clients/registry.ts as `cursor` and `vscode`.
|
|
11
|
+
* @version-history
|
|
12
|
+
* v1.0.0 — 2026-08-02 — Initial creation: one-command client connect.
|
|
13
|
+
*/
|
|
14
|
+
import type { ClientAdapter } from './types.js';
|
|
15
|
+
export declare const cursorAdapter: ClientAdapter;
|
|
16
|
+
export declare const vscodeAdapter: ClientAdapter;
|
|
17
|
+
//# sourceMappingURL=cursor-vscode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-vscode.d.ts","sourceRoot":"","sources":["../../../../../src/cli/connect/clients/cursor-vscode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,aAAa,EAA6B,MAAM,YAAY,CAAC;AAuB3E,eAAO,MAAM,aAAa,EAAE,aA6B3B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,aA+B3B,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file cursor-vscode.ts
|
|
3
|
+
* @description Cursor and VS Code adapters. Both keep a JSON MCP config and both expand
|
|
4
|
+
* `${env:NAME}` inside header values, so the token stays in the environment. They differ in the
|
|
5
|
+
* top-level key (`mcpServers` vs `servers`), in whether `type` is required, and in where the file
|
|
6
|
+
* lives.
|
|
7
|
+
* @structure
|
|
8
|
+
* - cursorAdapter — ~/.cursor/mcp.json, `mcpServers`.
|
|
9
|
+
* - vscodeAdapter — per-platform user mcp.json, `servers` with `type: http`.
|
|
10
|
+
* @usage Registered in clients/registry.ts as `cursor` and `vscode`.
|
|
11
|
+
* @version-history
|
|
12
|
+
* v1.0.0 — 2026-08-02 — Initial creation: one-command client connect.
|
|
13
|
+
*/
|
|
14
|
+
import { homedir } from 'node:os';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
import { backup, objectAt, readJsonFile, writeJsonFile } from './fs-merge.js';
|
|
17
|
+
import { writeLauncher } from './launcher.js';
|
|
18
|
+
/** Both clients read the token from the environment; this is the value they expand. */
|
|
19
|
+
const HEADER_VALUE = 'Bearer ${env:AIMEAT_AGENT_TOKEN}';
|
|
20
|
+
function cursorConfigPath() {
|
|
21
|
+
return join(homedir(), '.cursor', 'mcp.json');
|
|
22
|
+
}
|
|
23
|
+
function vscodeConfigPath() {
|
|
24
|
+
if (process.platform === 'win32') {
|
|
25
|
+
const appData = process.env.APPDATA ?? join(homedir(), 'AppData', 'Roaming');
|
|
26
|
+
return join(appData, 'Code', 'User', 'mcp.json');
|
|
27
|
+
}
|
|
28
|
+
if (process.platform === 'darwin') {
|
|
29
|
+
return join(homedir(), 'Library', 'Application Support', 'Code', 'User', 'mcp.json');
|
|
30
|
+
}
|
|
31
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config');
|
|
32
|
+
return join(xdg, 'Code', 'User', 'mcp.json');
|
|
33
|
+
}
|
|
34
|
+
export const cursorAdapter = {
|
|
35
|
+
id: 'cursor',
|
|
36
|
+
label: 'Cursor',
|
|
37
|
+
transport: 'http',
|
|
38
|
+
configPath: cursorConfigPath,
|
|
39
|
+
async apply(target) {
|
|
40
|
+
const file = cursorConfigPath();
|
|
41
|
+
const config = readJsonFile(file);
|
|
42
|
+
const bak = backup(file);
|
|
43
|
+
objectAt(config, 'mcpServers')[target.serverName] = {
|
|
44
|
+
url: target.mcpUrl,
|
|
45
|
+
headers: { Authorization: HEADER_VALUE },
|
|
46
|
+
};
|
|
47
|
+
writeJsonFile(file, config);
|
|
48
|
+
const scripts = writeLauncher(target, 'cursor', 'cursor', ['.']);
|
|
49
|
+
return {
|
|
50
|
+
written: [file, ...scripts],
|
|
51
|
+
backedUp: bak ? [bak] : [],
|
|
52
|
+
nextSteps: [
|
|
53
|
+
`Cursor must see AIMEAT_AGENT_TOKEN in its environment. Launch it with: ${scripts[0]}`,
|
|
54
|
+
'Or export the variable in your shell profile and start Cursor normally.',
|
|
55
|
+
'Check it under Settings > MCP: the server should list its tools.',
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
export const vscodeAdapter = {
|
|
61
|
+
id: 'vscode',
|
|
62
|
+
label: 'VS Code',
|
|
63
|
+
transport: 'http',
|
|
64
|
+
configPath: vscodeConfigPath,
|
|
65
|
+
async apply(target) {
|
|
66
|
+
const file = vscodeConfigPath();
|
|
67
|
+
const config = readJsonFile(file);
|
|
68
|
+
const bak = backup(file);
|
|
69
|
+
objectAt(config, 'servers')[target.serverName] = {
|
|
70
|
+
type: 'http',
|
|
71
|
+
url: target.mcpUrl,
|
|
72
|
+
headers: { Authorization: HEADER_VALUE },
|
|
73
|
+
};
|
|
74
|
+
writeJsonFile(file, config);
|
|
75
|
+
const scripts = writeLauncher(target, 'vscode', 'code', ['.']);
|
|
76
|
+
return {
|
|
77
|
+
written: [file, ...scripts],
|
|
78
|
+
backedUp: bak ? [bak] : [],
|
|
79
|
+
nextSteps: [
|
|
80
|
+
`VS Code must see AIMEAT_AGENT_TOKEN in its environment. Launch it with: ${scripts[0]}`,
|
|
81
|
+
'Then run "MCP: List Servers" from the command palette and start the aimeat server.',
|
|
82
|
+
'If your build does not expand ${env:...} in headers, replace the header value with',
|
|
83
|
+
' "Bearer ${input:aimeat_token}" and add an inputs entry of type promptString.',
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=cursor-vscode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-vscode.js","sourceRoot":"","sources":["../../../../../src/cli/connect/clients/cursor-vscode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file fs-merge.ts
|
|
3
|
+
* @description Read-modify-write helpers shared by the client adapters. Every adapter edits a file
|
|
4
|
+
* the user already owns and that usually holds OTHER servers, so the rules here are the same for
|
|
5
|
+
* all of them: parse what is there, replace only our own key, back the file up first, and never
|
|
6
|
+
* drop a key we did not put there.
|
|
7
|
+
* @structure
|
|
8
|
+
* - readJsonFile / writeJsonFile — tolerant JSON round-trip (missing file = {}).
|
|
9
|
+
* - readYamlFile / writeYamlFile — same for YAML (Goose).
|
|
10
|
+
* - backup — timestamp-free `.aimeat-bak` copy, taken once per run before the first write.
|
|
11
|
+
* - ensureDirFor — mkdir -p for a file path.
|
|
12
|
+
* @usage Imported by clients/goose.ts, cursor.ts, vscode.ts, claude-desktop.ts.
|
|
13
|
+
* @version-history
|
|
14
|
+
* v1.0.0 — 2026-08-02 — Initial creation: one-command client connect.
|
|
15
|
+
*/
|
|
16
|
+
/** mkdir -p for the directory holding `file`. */
|
|
17
|
+
export declare function ensureDirFor(file: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Copy `file` to `<file>.aimeat-bak` before we touch it. Returns the backup path, or null when
|
|
20
|
+
* there was nothing to back up (first-time config). A single fixed suffix keeps the user's config
|
|
21
|
+
* directory from filling with copies on every re-run.
|
|
22
|
+
*/
|
|
23
|
+
export declare function backup(file: string): string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Parse a JSON config. A missing file yields `{}`. A file that exists but does not parse THROWS —
|
|
26
|
+
* silently starting from `{}` there would delete every server the user had configured.
|
|
27
|
+
*/
|
|
28
|
+
export declare function readJsonFile(file: string): Record<string, unknown>;
|
|
29
|
+
export declare function writeJsonFile(file: string, data: Record<string, unknown>): void;
|
|
30
|
+
/** Same contract as readJsonFile, for YAML. */
|
|
31
|
+
export declare function readYamlFile(file: string): Record<string, unknown>;
|
|
32
|
+
export declare function writeYamlFile(file: string, data: Record<string, unknown>): void;
|
|
33
|
+
/** Fetch (or create) a nested object property without discarding what is already inside it. */
|
|
34
|
+
export declare function objectAt(root: Record<string, unknown>, key: string): Record<string, unknown>;
|
|
35
|
+
//# sourceMappingURL=fs-merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-merge.d.ts","sourceRoot":"","sources":["../../../../../src/cli/connect/clients/fs-merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,iDAAiD;AACjD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG/C;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKlD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUlE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAG/E;AAED,+CAA+C;AAC/C,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUlE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAG/E;AAED,+FAA+F;AAC/F,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAM5F"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file fs-merge.ts
|
|
3
|
+
* @description Read-modify-write helpers shared by the client adapters. Every adapter edits a file
|
|
4
|
+
* the user already owns and that usually holds OTHER servers, so the rules here are the same for
|
|
5
|
+
* all of them: parse what is there, replace only our own key, back the file up first, and never
|
|
6
|
+
* drop a key we did not put there.
|
|
7
|
+
* @structure
|
|
8
|
+
* - readJsonFile / writeJsonFile — tolerant JSON round-trip (missing file = {}).
|
|
9
|
+
* - readYamlFile / writeYamlFile — same for YAML (Goose).
|
|
10
|
+
* - backup — timestamp-free `.aimeat-bak` copy, taken once per run before the first write.
|
|
11
|
+
* - ensureDirFor — mkdir -p for a file path.
|
|
12
|
+
* @usage Imported by clients/goose.ts, cursor.ts, vscode.ts, claude-desktop.ts.
|
|
13
|
+
* @version-history
|
|
14
|
+
* v1.0.0 — 2026-08-02 — Initial creation: one-command client connect.
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from 'node:fs';
|
|
17
|
+
import { dirname } from 'node:path';
|
|
18
|
+
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
19
|
+
/** mkdir -p for the directory holding `file`. */
|
|
20
|
+
export function ensureDirFor(file) {
|
|
21
|
+
const dir = dirname(file);
|
|
22
|
+
if (!existsSync(dir))
|
|
23
|
+
mkdirSync(dir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Copy `file` to `<file>.aimeat-bak` before we touch it. Returns the backup path, or null when
|
|
27
|
+
* there was nothing to back up (first-time config). A single fixed suffix keeps the user's config
|
|
28
|
+
* directory from filling with copies on every re-run.
|
|
29
|
+
*/
|
|
30
|
+
export function backup(file) {
|
|
31
|
+
if (!existsSync(file))
|
|
32
|
+
return null;
|
|
33
|
+
const bak = `${file}.aimeat-bak`;
|
|
34
|
+
copyFileSync(file, bak);
|
|
35
|
+
return bak;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Parse a JSON config. A missing file yields `{}`. A file that exists but does not parse THROWS —
|
|
39
|
+
* silently starting from `{}` there would delete every server the user had configured.
|
|
40
|
+
*/
|
|
41
|
+
export function readJsonFile(file) {
|
|
42
|
+
if (!existsSync(file))
|
|
43
|
+
return {};
|
|
44
|
+
const raw = readFileSync(file, 'utf8').trim();
|
|
45
|
+
if (!raw)
|
|
46
|
+
return {};
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(raw);
|
|
49
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
throw new Error(`${file} is not valid JSON. Fix or move it, then re-run — refusing to overwrite it.`, { cause: e });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function writeJsonFile(file, data) {
|
|
56
|
+
ensureDirFor(file);
|
|
57
|
+
writeFileSync(file, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
|
|
58
|
+
}
|
|
59
|
+
/** Same contract as readJsonFile, for YAML. */
|
|
60
|
+
export function readYamlFile(file) {
|
|
61
|
+
if (!existsSync(file))
|
|
62
|
+
return {};
|
|
63
|
+
const raw = readFileSync(file, 'utf8').trim();
|
|
64
|
+
if (!raw)
|
|
65
|
+
return {};
|
|
66
|
+
try {
|
|
67
|
+
const parsed = parseYaml(raw);
|
|
68
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
throw new Error(`${file} is not valid YAML. Fix or move it, then re-run — refusing to overwrite it.`, { cause: e });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export function writeYamlFile(file, data) {
|
|
75
|
+
ensureDirFor(file);
|
|
76
|
+
writeFileSync(file, stringifyYaml(data), 'utf8');
|
|
77
|
+
}
|
|
78
|
+
/** Fetch (or create) a nested object property without discarding what is already inside it. */
|
|
79
|
+
export function objectAt(root, key) {
|
|
80
|
+
const cur = root[key];
|
|
81
|
+
if (cur && typeof cur === 'object' && !Array.isArray(cur))
|
|
82
|
+
return cur;
|
|
83
|
+
const fresh = {};
|
|
84
|
+
root[key] = fresh;
|
|
85
|
+
return fresh;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=fs-merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-merge.js","sourceRoot":"","sources":["../../../../../src/cli/connect/clients/fs-merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file goose.ts
|
|
3
|
+
* @description Goose adapter. Goose keeps one YAML config with an `extensions` map and speaks
|
|
4
|
+
* Streamable HTTP natively, and it expands `${VAR}` inside header values from the merged
|
|
5
|
+
* env/env_keys map — so the agent token stays in the environment and never in the file.
|
|
6
|
+
* @structure
|
|
7
|
+
* - configPath() — per-platform config.yaml location.
|
|
8
|
+
* - apply() — merge one `extensions.<name>` entry, write the launcher, report next steps.
|
|
9
|
+
* @usage Registered in clients/registry.ts as `goose`.
|
|
10
|
+
* @version-history
|
|
11
|
+
* v1.0.0 — 2026-08-02 — Initial creation: one-command client connect.
|
|
12
|
+
*/
|
|
13
|
+
import type { ClientAdapter } from './types.js';
|
|
14
|
+
export declare const gooseAdapter: ClientAdapter;
|
|
15
|
+
//# sourceMappingURL=goose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goose.d.ts","sourceRoot":"","sources":["../../../../../src/cli/connect/clients/goose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,aAAa,EAA6B,MAAM,YAAY,CAAC;AAc3E,eAAO,MAAM,YAAY,EAAE,aA6C1B,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file goose.ts
|
|
3
|
+
* @description Goose adapter. Goose keeps one YAML config with an `extensions` map and speaks
|
|
4
|
+
* Streamable HTTP natively, and it expands `${VAR}` inside header values from the merged
|
|
5
|
+
* env/env_keys map — so the agent token stays in the environment and never in the file.
|
|
6
|
+
* @structure
|
|
7
|
+
* - configPath() — per-platform config.yaml location.
|
|
8
|
+
* - apply() — merge one `extensions.<name>` entry, write the launcher, report next steps.
|
|
9
|
+
* @usage Registered in clients/registry.ts as `goose`.
|
|
10
|
+
* @version-history
|
|
11
|
+
* v1.0.0 — 2026-08-02 — Initial creation: one-command client connect.
|
|
12
|
+
*/
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { backup, objectAt, readYamlFile, writeYamlFile } from './fs-merge.js';
|
|
16
|
+
import { writeLauncher } from './launcher.js';
|
|
17
|
+
function gooseConfigPath() {
|
|
18
|
+
if (process.platform === 'win32') {
|
|
19
|
+
const appData = process.env.APPDATA ?? join(homedir(), 'AppData', 'Roaming');
|
|
20
|
+
return join(appData, 'Block', 'goose', 'config', 'config.yaml');
|
|
21
|
+
}
|
|
22
|
+
// macOS and Linux both use the XDG-style path.
|
|
23
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config');
|
|
24
|
+
return join(xdg, 'goose', 'config.yaml');
|
|
25
|
+
}
|
|
26
|
+
export const gooseAdapter = {
|
|
27
|
+
id: 'goose',
|
|
28
|
+
label: 'Goose',
|
|
29
|
+
transport: 'http',
|
|
30
|
+
configPath: gooseConfigPath,
|
|
31
|
+
async apply(target) {
|
|
32
|
+
const file = gooseConfigPath();
|
|
33
|
+
const config = readYamlFile(file);
|
|
34
|
+
const bak = backup(file);
|
|
35
|
+
const extensions = objectAt(config, 'extensions');
|
|
36
|
+
extensions[target.serverName] = {
|
|
37
|
+
type: 'streamable_http',
|
|
38
|
+
name: target.serverName,
|
|
39
|
+
description: `AIMEAT node tools from ${target.nodeUrl}`,
|
|
40
|
+
uri: target.mcpUrl,
|
|
41
|
+
headers: { Authorization: 'Bearer ${AIMEAT_AGENT_TOKEN}' },
|
|
42
|
+
env_keys: ['AIMEAT_AGENT_TOKEN'],
|
|
43
|
+
enabled: true,
|
|
44
|
+
timeout: 600,
|
|
45
|
+
};
|
|
46
|
+
// Goose needs its own file/shell extension to write the apps it builds. Leave an existing
|
|
47
|
+
// entry exactly as the user set it; only add it when it is absent.
|
|
48
|
+
if (!extensions.developer) {
|
|
49
|
+
extensions.developer = {
|
|
50
|
+
type: 'builtin', name: 'developer', display_name: 'Developer',
|
|
51
|
+
enabled: true, bundled: true, timeout: 300,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
writeYamlFile(file, config);
|
|
55
|
+
const scripts = writeLauncher(target, 'goose', 'goose', ['session']);
|
|
56
|
+
return {
|
|
57
|
+
written: [file, ...scripts],
|
|
58
|
+
backedUp: bak ? [bak] : [],
|
|
59
|
+
nextSteps: [
|
|
60
|
+
`Start it with: ${scripts[0]}`,
|
|
61
|
+
'Inside the session, /mode auto stops the per-tool confirmations and /model <id> switches model.',
|
|
62
|
+
'Set OPENROUTER_API_KEY (or your provider key) in the environment before launching.',
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=goose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goose.js","sourceRoot":"","sources":["../../../../../src/cli/connect/clients/goose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,SAAS,eAAe;IACpB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC7E,OAAO,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IACpE,CAAC;IACD,+CAA+C;IAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAkB;IACvC,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,eAAe;IAE3B,KAAK,CAAC,KAAK,CAAC,MAAoB;QAC5B,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAEzB,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAClD,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG;YAC5B,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,MAAM,CAAC,UAAU;YACvB,WAAW,EAAE,0BAA0B,MAAM,CAAC,OAAO,EAAE;YACvD,GAAG,EAAE,MAAM,CAAC,MAAM;YAClB,OAAO,EAAE,EAAE,aAAa,EAAE,8BAA8B,EAAE;YAC1D,QAAQ,EAAE,CAAC,oBAAoB,CAAC;YAChC,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,GAAG;SACf,CAAC;QAEF,0FAA0F;QAC1F,mEAAmE;QACnE,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YACxB,UAAU,CAAC,SAAS,GAAG;gBACnB,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW;gBAC7D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG;aAC7C,CAAC;QACN,CAAC;QAED,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAErE,OAAO;YACH,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC;YAC3B,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;YAC1B,SAAS,EAAE;gBACP,mBAAmB,OAAO,CAAC,CAAC,CAAC,EAAE;gBAC/B,iGAAiG;gBACjG,oFAAoF;aACvF;SACJ,CAAC;IACN,CAAC;CACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file index.ts
|
|
3
|
+
* @description `aimeat connect client <id>` — one command that points a chat client at this node:
|
|
4
|
+
* it authorizes a dedicated agent into its own connector home, writes the client's MCP config,
|
|
5
|
+
* and leaves a launcher that supplies the token at run time. The point is that talking to AIMEAT
|
|
6
|
+
* from a client of your choice should be one command, not a page of manual steps.
|
|
7
|
+
* @structure
|
|
8
|
+
* - CLIENTS — the adapter registry (goose, claude-code, cursor, vscode, claude-desktop).
|
|
9
|
+
* - runConnectClient() — resolve client, ensure credential, apply adapter, report.
|
|
10
|
+
* - resolveTarget() — flags + defaults into a ClientTarget (home, workdir, server name, surface).
|
|
11
|
+
* @usage Dispatched from src/index-connect.ts on `aimeat connect client <id> [flags]`.
|
|
12
|
+
* @version-history
|
|
13
|
+
* v1.0.0 — 2026-08-02 — Initial creation: one-command client connect.
|
|
14
|
+
*/
|
|
15
|
+
import type { ClientAdapter } from './types.js';
|
|
16
|
+
export declare const CLIENTS: ClientAdapter[];
|
|
17
|
+
/**
|
|
18
|
+
* Run the one-command connect. Device authorization happens FIRST and inside the client's own
|
|
19
|
+
* home, so a failed or cancelled login never leaves a config pointing at an agent that does not
|
|
20
|
+
* exist.
|
|
21
|
+
*/
|
|
22
|
+
export declare function runConnectClient(clientId: string | undefined, flags: Record<string, string>): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/connect/clients/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAC;AAK9D,eAAO,MAAM,OAAO,EAAE,aAAa,EAElC,CAAC;AAoEF;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDjH"}
|