@tempoxyz/mercator 0.0.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 +208 -0
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/dist/agents.d.ts +26 -0
- package/dist/agents.js +152 -0
- package/dist/agents.js.map +1 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +4 -0
- package/dist/bin.js.map +1 -0
- package/dist/client-selection.d.ts +13 -0
- package/dist/client-selection.js +97 -0
- package/dist/client-selection.js.map +1 -0
- package/dist/clients.d.ts +70 -0
- package/dist/clients.js +282 -0
- package/dist/clients.js.map +1 -0
- package/dist/codex-plugin.d.ts +52 -0
- package/dist/codex-plugin.js +417 -0
- package/dist/codex-plugin.js.map +1 -0
- package/dist/command.d.ts +17 -0
- package/dist/command.js +59 -0
- package/dist/command.js.map +1 -0
- package/dist/doctor.d.ts +10 -0
- package/dist/doctor.js +105 -0
- package/dist/doctor.js.map +1 -0
- package/dist/globe-frames.d.ts +6 -0
- package/dist/globe-frames.js +208 -0
- package/dist/globe-frames.js.map +1 -0
- package/dist/globe.d.ts +12 -0
- package/dist/globe.js +73 -0
- package/dist/globe.js.map +1 -0
- package/dist/index.d.ts +118 -0
- package/dist/index.js +568 -0
- package/dist/index.js.map +1 -0
- package/dist/native-payments.d.ts +34 -0
- package/dist/native-payments.js +191 -0
- package/dist/native-payments.js.map +1 -0
- package/dist/plugin-bundle/.codex-plugin/plugin.json +35 -0
- package/dist/plugin-bundle/.mcp.json +9 -0
- package/dist/plugin-bundle/README.md +26 -0
- package/dist/plugin-bundle/assets/favicon.svg +7 -0
- package/dist/plugin-bundle/assets/mercator-overview.png +0 -0
- package/dist/plugin-bundle/assets/service-network.png +0 -0
- package/dist/plugin-bundle/assets/workflow-composition.png +0 -0
- package/dist/setup-progress.d.ts +13 -0
- package/dist/setup-progress.js +22 -0
- package/dist/setup-progress.js.map +1 -0
- package/dist/submit.d.ts +15 -0
- package/dist/submit.js +127 -0
- package/dist/submit.js.map +1 -0
- package/dist/wallet.d.ts +77 -0
- package/dist/wallet.js +319 -0
- package/dist/wallet.js.map +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# `@tempoxyz/mercator`
|
|
2
|
+
|
|
3
|
+
Install and diagnose the Mercator remote MCP server, desktop plugin, and a session-capable payment
|
|
4
|
+
wallet across supported agent clients.
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
curl -fsSL https://mercator.tempo.xyz/install.sh | sh
|
|
8
|
+
mercator doctor
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The installer places the CLI under `~/.local`, links `mercator` into `~/.local/bin`, and launches
|
|
12
|
+
the same interactive setup flow. Pass CLI arguments after `sh -s --`, for example:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
curl -fsSL https://mercator.tempo.xyz/install.sh | sh -s -- --client codex
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Setup flow
|
|
19
|
+
|
|
20
|
+
```mermaid
|
|
21
|
+
flowchart LR
|
|
22
|
+
START["Start setup"] --> DETECT["Detect supported clients"]
|
|
23
|
+
DETECT --> PLUGIN["Bootstrap local desktop plugin"]
|
|
24
|
+
PLUGIN -->|Agent CLI found| CONFIGURE["Install Mercator MCP entry"]
|
|
25
|
+
PLUGIN -->|No agent CLI| GUIDANCE
|
|
26
|
+
CONFIGURE --> GUIDANCE["Update managed guidance"]
|
|
27
|
+
GUIDANCE --> WALLET{"Ready payment runtime?"}
|
|
28
|
+
WALLET -->|Yes| VERIFY["Run readiness checks"]
|
|
29
|
+
WALLET -->|No| ONBOARD["Create local wallet or connect Tempo Wallet"]
|
|
30
|
+
ONBOARD --> VERIFY
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Supported clients:
|
|
34
|
+
|
|
35
|
+
- Codex
|
|
36
|
+
- Claude Code
|
|
37
|
+
- Gemini CLI
|
|
38
|
+
- Cursor
|
|
39
|
+
- VS Code
|
|
40
|
+
- Windsurf
|
|
41
|
+
- Cline
|
|
42
|
+
- Continue
|
|
43
|
+
- OpenClaw
|
|
44
|
+
- Hermes
|
|
45
|
+
|
|
46
|
+
Normal setup always bootstraps the bundled [Mercator plugin](../../plugins/mercator) into Codex's
|
|
47
|
+
user-local plugin index. Nothing is published, and users do not need to create or manage a
|
|
48
|
+
marketplace. The plugin connects Codex or ChatGPT desktop directly to the production Mercator MCP
|
|
49
|
+
server without requiring the Codex CLI. Restart ChatGPT desktop after installation. Use
|
|
50
|
+
`--no-plugin` for a CLI-only installation, such as CI or a headless server.
|
|
51
|
+
|
|
52
|
+
Selection options:
|
|
53
|
+
|
|
54
|
+
| Option | Behavior |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| No subcommand | Bootstrap the local plugin and run interactive `setup` |
|
|
57
|
+
| Picker | Show detected clients; select several entries or `all` |
|
|
58
|
+
| `--client <name>` | Configure one named client; repeatable |
|
|
59
|
+
| `--all` | Configure every supported client non-interactively |
|
|
60
|
+
| `--dry-run` | Preview configuration changes |
|
|
61
|
+
| `--force` | Recreate Mercator registrations and refresh managed guidance |
|
|
62
|
+
| `--no-plugin` | Skip local desktop plugin installation |
|
|
63
|
+
| `--no-agents` | Skip Codex `AGENTS.md` guidance |
|
|
64
|
+
| `--remove-agents` | Remove installed Codex guidance |
|
|
65
|
+
|
|
66
|
+
Setup guarantees:
|
|
67
|
+
|
|
68
|
+
- Reuses matching existing configuration safely.
|
|
69
|
+
- Serializes plugin index updates and preserves unrelated local plugins.
|
|
70
|
+
- Shows a rotating [adamsky/globe](https://github.com/adamsky/globe) with live setup progress.
|
|
71
|
+
- Keeps the globe active while the interactive client picker is open.
|
|
72
|
+
- `--force` never removes or recreates wallets, keys, accounts, balances, sessions, or shared MPP
|
|
73
|
+
plugins.
|
|
74
|
+
- Wallet and native payment checks remain read-only during forced setup.
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
mercator setup --client codex --force
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Codex guidance
|
|
83
|
+
|
|
84
|
+
Codex setup maintains a bounded block in the active global `AGENTS.md`:
|
|
85
|
+
|
|
86
|
+
- Explains when to use Mercator.
|
|
87
|
+
- Requires quote and budget approval before paid execution.
|
|
88
|
+
- Excludes local files and repository work.
|
|
89
|
+
- Preserves content outside `mercator:begin` and `mercator:end` HTML comments.
|
|
90
|
+
- Leaves an existing `AGENTS.override.md` untouched and reports when it shadows the guidance.
|
|
91
|
+
- Applies new guidance to the next Codex session.
|
|
92
|
+
|
|
93
|
+
Mercator always manages persistent `AGENTS.md`; use `--no-agents` to skip installation or
|
|
94
|
+
`--remove-agents` to remove the managed block.
|
|
95
|
+
|
|
96
|
+
## Payment runtime selection
|
|
97
|
+
|
|
98
|
+
Mercator uses one active payment wallet. `mercator wallet connect` and `mercator wallet create`
|
|
99
|
+
record that selection. Existing installations without an active selection continue using their
|
|
100
|
+
Tempo Wallet credentials when present, otherwise their local disk wallet.
|
|
101
|
+
|
|
102
|
+
| Runtime | Paid-request path | Session behavior |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| Local disk wallet | `mercator submit` | Uses Mercator-owned Accounts SDK storage |
|
|
105
|
+
| Tempo Wallet | `mercator submit` | Uses a scoped access key authorized through Accounts |
|
|
106
|
+
| OpenClaw | Native `mpp_fetch` | Uses official `openclaw-mpp` integration |
|
|
107
|
+
| Hermes | Native `mpp_fetch` | Uses official `hermes-mpp` integration |
|
|
108
|
+
|
|
109
|
+
Mercator requires neither the Tempo Wallet CLI nor the MPPX CLI. Connecting or creating an unfunded
|
|
110
|
+
wallet opens Mercator's MACH funding page with its address selected. The page offers fixed amounts
|
|
111
|
+
and redirects to Stripe-hosted Checkout with card and Apple Pay support. Run `mercator wallet fund`
|
|
112
|
+
to open it again later.
|
|
113
|
+
|
|
114
|
+
OpenClaw and Hermes setup:
|
|
115
|
+
|
|
116
|
+
- Installs or verifies the official
|
|
117
|
+
[openclaw-mpp](https://github.com/tempoxyz/openclaw-mpp) or
|
|
118
|
+
[hermes-mpp](https://github.com/tempoxyz/hermes-mpp) integration.
|
|
119
|
+
- Preserves existing Hermes allowed origins before adding Mercator.
|
|
120
|
+
|
|
121
|
+
## Wallet onboarding
|
|
122
|
+
|
|
123
|
+
Run wallet setup separately:
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
mercator wallet
|
|
127
|
+
mercator wallet connect
|
|
128
|
+
mercator wallet create
|
|
129
|
+
mercator wallet status
|
|
130
|
+
mercator wallet balance
|
|
131
|
+
mercator wallet fund
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
With no active wallet, `mercator wallet` asks whether to connect an existing wallet or create one
|
|
135
|
+
on this machine. `wallet connect` opens the Accounts SDK device flow and stores only its Mercator
|
|
136
|
+
access key locally. Local-wallet private material, connected-wallet access keys, and the active
|
|
137
|
+
selection share the Accounts SDK filesystem store at `~/.mercator/wallet.json`, secured with
|
|
138
|
+
user-only file permissions.
|
|
139
|
+
|
|
140
|
+
`mercator wallet status` inspects readiness without onboarding. `mercator wallet`,
|
|
141
|
+
`mercator wallet balance`, and `mercator wallet fund` report the active wallet's balances. Creating
|
|
142
|
+
or connecting an unfunded wallet opens Mercator's card onramp; inspecting an existing wallet does
|
|
143
|
+
not.
|
|
144
|
+
|
|
145
|
+
## Paid job submission
|
|
146
|
+
|
|
147
|
+
```mermaid
|
|
148
|
+
flowchart LR
|
|
149
|
+
MCP["MCP: discover + quote"] --> REST["POST /v1/jobs"]
|
|
150
|
+
REST --> PAYMENT["Mercator wallet"]
|
|
151
|
+
PAYMENT --> POLL["MCP or REST: poll result"]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Recommended path:
|
|
155
|
+
|
|
156
|
+
- Use MCP for discovery, quoting, and result polling.
|
|
157
|
+
- Use the bounded `mercator submit` handoff returned by `create_job`.
|
|
158
|
+
- The REST endpoint offers both `tempo/session` and `tempo/charge`.
|
|
159
|
+
- Some MCP harnesses cannot answer the payment-required protocol error from `create_job`.
|
|
160
|
+
- Use `mpp_fetch` in OpenClaw or Hermes.
|
|
161
|
+
- Other clients use the same Mercator wallet created during setup.
|
|
162
|
+
|
|
163
|
+
## Diagnostics
|
|
164
|
+
|
|
165
|
+
`doctor` performs read-only checks:
|
|
166
|
+
|
|
167
|
+
- MCP transport.
|
|
168
|
+
- Six-tool contract.
|
|
169
|
+
- Free service discovery.
|
|
170
|
+
- Unsigned Mercator session challenge.
|
|
171
|
+
- Local wallet session capability.
|
|
172
|
+
- Local plugin path, installed and expected versions, registration state, and desktop restart
|
|
173
|
+
requirement.
|
|
174
|
+
|
|
175
|
+
Plugin state is advisory so `--no-plugin` installations remain healthy. Funding is reported
|
|
176
|
+
separately from session capability. Paid execution remains `not_verified`.
|
|
177
|
+
|
|
178
|
+
## Uninstall
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
mercator uninstall --client codex
|
|
182
|
+
mercator uninstall --client openclaw --client hermes
|
|
183
|
+
mercator uninstall --dry-run
|
|
184
|
+
mercator uninstall
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Uninstall behavior:
|
|
188
|
+
|
|
189
|
+
- Removes only the `mercator` MCP entry, CLI-managed local plugin bundle and registration, and
|
|
190
|
+
installer-managed Codex guidance.
|
|
191
|
+
- Preserves other MCP servers, local plugin entries, and user instructions.
|
|
192
|
+
- Preserves wallets, keys, balances, sessions, and shared MPP plugins.
|
|
193
|
+
- `--dry-run` previews removal.
|
|
194
|
+
- A scoped uninstall removes the plugin only for `--client codex`; an unscoped uninstall removes it
|
|
195
|
+
with all other Mercator integrations.
|
|
196
|
+
- VS Code removal covers the default user profile; use **MCP: Open User Configuration** for other
|
|
197
|
+
profiles.
|
|
198
|
+
|
|
199
|
+
## Command discovery
|
|
200
|
+
|
|
201
|
+
```sh
|
|
202
|
+
mercator clients
|
|
203
|
+
mercator --help
|
|
204
|
+
mercator --llms
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
The CLI uses Incur for validated options, generated help, machine-readable manifests, structured
|
|
208
|
+
errors, shell completions, and agent integrations.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
## globe
|
|
4
|
+
|
|
5
|
+
The CLI's terminal globe frames were generated using
|
|
6
|
+
[adamsky/globe](https://github.com/adamsky/globe) commit
|
|
7
|
+
`b0d2eb545672c52a8e6c6fa13faf4ec3c9174b01` and its built-in Earth texture.
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2022 Adam Kelly. Licensed under the GNU General Public License v3.0.
|
|
10
|
+
The Mercator source distribution contains the generated frames and identifies the generating
|
|
11
|
+
source in `src/globe-frames.ts`.
|
package/dist/agents.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Opening boundary for installer-managed Mercator guidance. */
|
|
2
|
+
export declare const MERCATOR_AGENTS_BEGIN = "<!-- mercator:begin \u2014 managed by mercator-cli; edits inside will be overwritten -->";
|
|
3
|
+
/** Closing boundary for installer-managed Mercator guidance. */
|
|
4
|
+
export declare const MERCATOR_AGENTS_END = "<!-- mercator:end -->";
|
|
5
|
+
/** Durable, budget-aware activation guidance installed for Codex. */
|
|
6
|
+
export declare const MERCATOR_AGENTS_BLOCK = "<!-- mercator:begin \u2014 managed by mercator-cli; edits inside will be overwritten -->\n## Mercator\n\nMercator is an optional gateway for fresh external data and API actions.\n\n- Consider Mercator when a task needs research, extraction, enrichment, social, maps, travel, communications, media, financial, or on-chain data and no installed direct tool is a better fit.\n- Search with `search_services` using the user's complete intended outcome. Discovery and `quote_plan` are free.\n- Before paid execution, show the quoted total and get approval unless the user already supplied a sufficient budget. Never exceed that budget.\n- Once approved, complete the workflow instead of merely naming a service: call `create_job` once with a stable idempotency key, then poll `get_job`. Never create another job to check its status.\n- Do not use Mercator for local files, repository work, reasoning over supplied content, or when the user forbids external or paid services.\n- Never request or expose private keys or provider credentials.\n<!-- mercator:end -->";
|
|
7
|
+
/** Options controlling where and whether Codex guidance is written. */
|
|
8
|
+
export type CodexAgentsInstallOptions = {
|
|
9
|
+
codexHome?: string;
|
|
10
|
+
dryRun?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/** Result of planning or applying the managed Codex guidance block. */
|
|
13
|
+
export type CodexAgentsInstallResult = {
|
|
14
|
+
path: string;
|
|
15
|
+
shadowed: boolean;
|
|
16
|
+
state: 'created' | 'current' | 'planned' | 'updated';
|
|
17
|
+
};
|
|
18
|
+
/** Result of planning or removing managed Codex guidance. */
|
|
19
|
+
export type CodexAgentsRemoveResult = {
|
|
20
|
+
paths: string[];
|
|
21
|
+
state: 'missing' | 'planned' | 'removed';
|
|
22
|
+
};
|
|
23
|
+
/** Installs or refreshes Mercator guidance in persistent global Codex instructions. */
|
|
24
|
+
export declare function installCodexAgents(options?: CodexAgentsInstallOptions): Promise<CodexAgentsInstallResult>;
|
|
25
|
+
/** Removes every installer-managed Mercator block from global Codex instructions. */
|
|
26
|
+
export declare function removeCodexAgents(options?: CodexAgentsInstallOptions): Promise<CodexAgentsRemoveResult>;
|
package/dist/agents.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { lstat, mkdir, readFile, realpath, rename, stat, unlink, writeFile, } from 'node:fs/promises';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
/** Opening boundary for installer-managed Mercator guidance. */
|
|
5
|
+
export const MERCATOR_AGENTS_BEGIN = '<!-- mercator:begin — managed by mercator-cli; edits inside will be overwritten -->';
|
|
6
|
+
/** Closing boundary for installer-managed Mercator guidance. */
|
|
7
|
+
export const MERCATOR_AGENTS_END = '<!-- mercator:end -->';
|
|
8
|
+
/** Durable, budget-aware activation guidance installed for Codex. */
|
|
9
|
+
export const MERCATOR_AGENTS_BLOCK = `${MERCATOR_AGENTS_BEGIN}
|
|
10
|
+
## Mercator
|
|
11
|
+
|
|
12
|
+
Mercator is an optional gateway for fresh external data and API actions.
|
|
13
|
+
|
|
14
|
+
- Consider Mercator when a task needs research, extraction, enrichment, social, maps, travel, communications, media, financial, or on-chain data and no installed direct tool is a better fit.
|
|
15
|
+
- Search with \`search_services\` using the user's complete intended outcome. Discovery and \`quote_plan\` are free.
|
|
16
|
+
- Before paid execution, show the quoted total and get approval unless the user already supplied a sufficient budget. Never exceed that budget.
|
|
17
|
+
- Once approved, complete the workflow instead of merely naming a service: call \`create_job\` once with a stable idempotency key, then poll \`get_job\`. Never create another job to check its status.
|
|
18
|
+
- Do not use Mercator for local files, repository work, reasoning over supplied content, or when the user forbids external or paid services.
|
|
19
|
+
- Never request or expose private keys or provider credentials.
|
|
20
|
+
${MERCATOR_AGENTS_END}`;
|
|
21
|
+
/** Installs or refreshes Mercator guidance in persistent global Codex instructions. */
|
|
22
|
+
export async function installCodexAgents(options = {}) {
|
|
23
|
+
const codexHome = options.codexHome ?? process.env.CODEX_HOME ?? join(homedir(), '.codex');
|
|
24
|
+
const target = await readAgentsFile(join(codexHome, 'AGENTS.md'));
|
|
25
|
+
const override = await readOptionalFile(join(codexHome, 'AGENTS.override.md'));
|
|
26
|
+
const shadowed = Boolean(override?.trim());
|
|
27
|
+
const content = mergeManagedBlock(target.content);
|
|
28
|
+
if (content === target.content) {
|
|
29
|
+
return { path: target.path, shadowed, state: 'current' };
|
|
30
|
+
}
|
|
31
|
+
if (options.dryRun)
|
|
32
|
+
return { path: target.path, shadowed, state: 'planned' };
|
|
33
|
+
await writeAtomically(target.writePath, content, target.mode);
|
|
34
|
+
return {
|
|
35
|
+
path: target.path,
|
|
36
|
+
shadowed,
|
|
37
|
+
state: target.exists ? 'updated' : 'created',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Removes every installer-managed Mercator block from global Codex instructions. */
|
|
41
|
+
export async function removeCodexAgents(options = {}) {
|
|
42
|
+
const codexHome = options.codexHome ?? process.env.CODEX_HOME ?? join(homedir(), '.codex');
|
|
43
|
+
const targets = await Promise.all(['AGENTS.md', 'AGENTS.override.md'].map(async (name) => {
|
|
44
|
+
const target = await readAgentsFile(join(codexHome, name));
|
|
45
|
+
return { ...target, content: removeManagedBlock(target.content) };
|
|
46
|
+
}));
|
|
47
|
+
const changed = targets.filter((target) => target.content !== target.original);
|
|
48
|
+
if (changed.length === 0)
|
|
49
|
+
return { paths: [], state: 'missing' };
|
|
50
|
+
const paths = changed.map((target) => target.path);
|
|
51
|
+
if (options.dryRun)
|
|
52
|
+
return { paths, state: 'planned' };
|
|
53
|
+
await Promise.all(changed.map(async (target) => {
|
|
54
|
+
if (target.content.trim().length > 0 || target.symlink) {
|
|
55
|
+
await writeAtomically(target.writePath, target.content, target.mode);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
await unlink(target.path);
|
|
59
|
+
}
|
|
60
|
+
}));
|
|
61
|
+
return { paths, state: 'removed' };
|
|
62
|
+
}
|
|
63
|
+
function mergeManagedBlock(existing) {
|
|
64
|
+
const managed = managedBlockRange(existing);
|
|
65
|
+
if (managed) {
|
|
66
|
+
return `${existing.slice(0, managed.begin)}${MERCATOR_AGENTS_BLOCK}${existing.slice(managed.end)}`;
|
|
67
|
+
}
|
|
68
|
+
if (existing.length === 0)
|
|
69
|
+
return `${MERCATOR_AGENTS_BLOCK}\n`;
|
|
70
|
+
const separator = existing.endsWith('\n\n')
|
|
71
|
+
? ''
|
|
72
|
+
: existing.endsWith('\n')
|
|
73
|
+
? '\n'
|
|
74
|
+
: '\n\n';
|
|
75
|
+
return `${existing}${separator}${MERCATOR_AGENTS_BLOCK}\n`;
|
|
76
|
+
}
|
|
77
|
+
function removeManagedBlock(existing) {
|
|
78
|
+
const managed = managedBlockRange(existing);
|
|
79
|
+
if (!managed)
|
|
80
|
+
return existing;
|
|
81
|
+
const before = existing.slice(0, managed.begin).trimEnd();
|
|
82
|
+
const after = existing.slice(managed.end).trimStart();
|
|
83
|
+
if (before && after)
|
|
84
|
+
return `${before}\n\n${after}`;
|
|
85
|
+
if (before)
|
|
86
|
+
return `${before}\n`;
|
|
87
|
+
return after;
|
|
88
|
+
}
|
|
89
|
+
function managedBlockRange(existing) {
|
|
90
|
+
const begin = existing.indexOf(MERCATOR_AGENTS_BEGIN);
|
|
91
|
+
const end = existing.indexOf(MERCATOR_AGENTS_END);
|
|
92
|
+
if ((begin === -1) !== (end === -1)) {
|
|
93
|
+
throw new Error('Mercator guidance has an incomplete managed boundary; repair it before rerunning setup.');
|
|
94
|
+
}
|
|
95
|
+
if (begin === -1)
|
|
96
|
+
return undefined;
|
|
97
|
+
if (end < begin ||
|
|
98
|
+
existing.indexOf(MERCATOR_AGENTS_BEGIN, begin + 1) !== -1 ||
|
|
99
|
+
existing.indexOf(MERCATOR_AGENTS_END, end + 1) !== -1) {
|
|
100
|
+
throw new Error('Mercator guidance has ambiguous managed boundaries; repair them before rerunning setup.');
|
|
101
|
+
}
|
|
102
|
+
return { begin, end: end + MERCATOR_AGENTS_END.length };
|
|
103
|
+
}
|
|
104
|
+
async function readAgentsFile(path) {
|
|
105
|
+
const link = await readOptionalLink(path);
|
|
106
|
+
const content = await readOptionalFile(path);
|
|
107
|
+
if (link?.isSymbolicLink() && content === undefined) {
|
|
108
|
+
throw new Error(`Cannot update broken AGENTS.md symlink: ${path}`);
|
|
109
|
+
}
|
|
110
|
+
const exists = content !== undefined;
|
|
111
|
+
const writePath = exists ? await realpath(path) : path;
|
|
112
|
+
const mode = exists ? (await stat(path)).mode & 0o777 : undefined;
|
|
113
|
+
return {
|
|
114
|
+
content: content ?? '',
|
|
115
|
+
exists,
|
|
116
|
+
mode,
|
|
117
|
+
original: content ?? '',
|
|
118
|
+
path,
|
|
119
|
+
symlink: Boolean(link?.isSymbolicLink()),
|
|
120
|
+
writePath,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async function readOptionalLink(path) {
|
|
124
|
+
try {
|
|
125
|
+
return await lstat(path);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (isMissingFile(error))
|
|
129
|
+
return undefined;
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async function readOptionalFile(path) {
|
|
134
|
+
try {
|
|
135
|
+
return await readFile(path, 'utf8');
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
if (isMissingFile(error))
|
|
139
|
+
return undefined;
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function isMissingFile(error) {
|
|
144
|
+
return error instanceof Error && 'code' in error && error.code === 'ENOENT';
|
|
145
|
+
}
|
|
146
|
+
async function writeAtomically(path, content, mode = 0o600) {
|
|
147
|
+
await mkdir(dirname(path), { recursive: true });
|
|
148
|
+
const temporary = `${path}.${process.pid}.tmp`;
|
|
149
|
+
await writeFile(temporary, content, { encoding: 'utf8', mode });
|
|
150
|
+
await rename(temporary, path);
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
|
package/dist/bin.d.ts
ADDED
package/dist/bin.js
ADDED
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAA;AAEhC,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ClientId } from './clients.js';
|
|
2
|
+
import { type GlobeAnimation, startMercatorGlobe } from './globe.js';
|
|
3
|
+
type ClientSelectionStreams = {
|
|
4
|
+
readonly animateGlobe?: boolean;
|
|
5
|
+
readonly globe?: GlobeAnimation;
|
|
6
|
+
readonly input: NodeJS.ReadableStream;
|
|
7
|
+
readonly interactive: boolean;
|
|
8
|
+
readonly output: NodeJS.WritableStream;
|
|
9
|
+
readonly startGlobe?: typeof startMercatorGlobe;
|
|
10
|
+
};
|
|
11
|
+
/** Selects detected clients interactively, or requires explicit clients outside a TTY. */
|
|
12
|
+
export declare function selectClients(clients: readonly ClientId[], overrides?: Partial<ClientSelectionStreams>): Promise<ClientId[]>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline/promises';
|
|
2
|
+
import { startMercatorGlobe } from './globe.js';
|
|
3
|
+
const CLIENT_LABELS = {
|
|
4
|
+
claude: 'Claude Code',
|
|
5
|
+
cline: 'Cline',
|
|
6
|
+
codex: 'Codex',
|
|
7
|
+
continue: 'Continue',
|
|
8
|
+
cursor: 'Cursor',
|
|
9
|
+
gemini: 'Gemini CLI',
|
|
10
|
+
hermes: 'Hermes',
|
|
11
|
+
openclaw: 'OpenClaw',
|
|
12
|
+
vscode: 'VS Code',
|
|
13
|
+
windsurf: 'Windsurf',
|
|
14
|
+
};
|
|
15
|
+
const defaultStreams = () => ({
|
|
16
|
+
animateGlobe: Boolean(process.stdout.isTTY) &&
|
|
17
|
+
process.env.CI === undefined &&
|
|
18
|
+
process.env.TERM !== 'dumb',
|
|
19
|
+
input: process.stdin,
|
|
20
|
+
interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
21
|
+
output: process.stdout,
|
|
22
|
+
startGlobe: startMercatorGlobe,
|
|
23
|
+
});
|
|
24
|
+
/** Selects detected clients interactively, or requires explicit clients outside a TTY. */
|
|
25
|
+
export async function selectClients(clients, overrides = {}) {
|
|
26
|
+
const streams = { ...defaultStreams(), ...overrides };
|
|
27
|
+
if (clients.length === 0) {
|
|
28
|
+
throw new Error('No supported clients detected. Run mercator setup --client <client>.');
|
|
29
|
+
}
|
|
30
|
+
const onlyClient = clients.length === 1 ? clients[0] : undefined;
|
|
31
|
+
if (onlyClient !== undefined) {
|
|
32
|
+
return [onlyClient];
|
|
33
|
+
}
|
|
34
|
+
if (!streams.interactive) {
|
|
35
|
+
throw new Error(`Multiple clients detected (${clients.join(', ')}). Run mercator setup --client <client>.`);
|
|
36
|
+
}
|
|
37
|
+
const ownsGlobe = streams.globe === undefined;
|
|
38
|
+
if (ownsGlobe)
|
|
39
|
+
streams.output.write('\n');
|
|
40
|
+
const globe = streams.globe ??
|
|
41
|
+
(streams.startGlobe ?? startMercatorGlobe)(streams.output, {
|
|
42
|
+
animate: streams.animateGlobe ?? false,
|
|
43
|
+
});
|
|
44
|
+
const write = (value) => {
|
|
45
|
+
streams.output.write(value);
|
|
46
|
+
globe.addLinesBelow(value.match(/\n/g)?.length ?? 0);
|
|
47
|
+
};
|
|
48
|
+
write('\nSelect clients to configure:\n\n');
|
|
49
|
+
const indexWidth = String(clients.length).length;
|
|
50
|
+
const labelWidth = Math.max(...clients.map((client) => CLIENT_LABELS[client].length));
|
|
51
|
+
clients.forEach((client, index) => {
|
|
52
|
+
const number = String(index + 1).padStart(indexWidth);
|
|
53
|
+
const label = CLIENT_LABELS[client].padEnd(labelWidth);
|
|
54
|
+
write(` ${number}. ${label} (${client})\n`);
|
|
55
|
+
});
|
|
56
|
+
write('\nManual mode: mercator setup --client <client> (repeat --client as needed)\n\n');
|
|
57
|
+
const readline = createInterface({
|
|
58
|
+
input: streams.input,
|
|
59
|
+
output: streams.output,
|
|
60
|
+
terminal: false,
|
|
61
|
+
});
|
|
62
|
+
try {
|
|
63
|
+
write('Selection (numbers, names, or all): ');
|
|
64
|
+
for await (const line of readline) {
|
|
65
|
+
globe.addLinesBelow(1);
|
|
66
|
+
const answer = line.trim().toLowerCase();
|
|
67
|
+
if (answer === 'a' || answer === 'all')
|
|
68
|
+
return [...clients];
|
|
69
|
+
const selected = answer
|
|
70
|
+
.split(',')
|
|
71
|
+
.map((value) => value.trim())
|
|
72
|
+
.filter(Boolean)
|
|
73
|
+
.map((value) => {
|
|
74
|
+
const selectedIndex = Number.parseInt(value, 10) - 1;
|
|
75
|
+
return /^\d+$/.test(value)
|
|
76
|
+
? clients[selectedIndex]
|
|
77
|
+
: clients.find((client) => client === value);
|
|
78
|
+
});
|
|
79
|
+
if (selected.length > 0 && selected.every((client) => client !== undefined)) {
|
|
80
|
+
return [...new Set(selected)];
|
|
81
|
+
}
|
|
82
|
+
write(`Choose 1-${clients.length}, comma-separated client names, or all.\nSelection (numbers, names, or all): `);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
throw new Error('Client selection cancelled. Run mercator setup --client <client>.', {
|
|
87
|
+
cause: error,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
readline.close();
|
|
92
|
+
if (ownsGlobe)
|
|
93
|
+
await globe.stop();
|
|
94
|
+
}
|
|
95
|
+
throw new Error('Client selection cancelled. Run mercator setup --client <client>.');
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=client-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-selection.js","sourceRoot":"","sources":["../src/client-selection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type CommandResult } from './command.js';
|
|
2
|
+
export declare const Client: {
|
|
3
|
+
readonly Claude: "claude";
|
|
4
|
+
readonly Cline: "cline";
|
|
5
|
+
readonly Codex: "codex";
|
|
6
|
+
readonly Continue: "continue";
|
|
7
|
+
readonly Cursor: "cursor";
|
|
8
|
+
readonly Gemini: "gemini";
|
|
9
|
+
readonly Hermes: "hermes";
|
|
10
|
+
readonly OpenClaw: "openclaw";
|
|
11
|
+
readonly VsCode: "vscode";
|
|
12
|
+
readonly Windsurf: "windsurf";
|
|
13
|
+
};
|
|
14
|
+
export type ClientId = (typeof Client)[keyof typeof Client];
|
|
15
|
+
type CommandPlan = {
|
|
16
|
+
args: string[];
|
|
17
|
+
check?: CommandCheck;
|
|
18
|
+
command: string;
|
|
19
|
+
kind: 'command';
|
|
20
|
+
undo: string;
|
|
21
|
+
};
|
|
22
|
+
type CommandCheck = {
|
|
23
|
+
args: string[];
|
|
24
|
+
command: string;
|
|
25
|
+
serverName?: string;
|
|
26
|
+
url: string;
|
|
27
|
+
};
|
|
28
|
+
type FilePlan = {
|
|
29
|
+
config: Record<string, unknown>;
|
|
30
|
+
kind: 'file';
|
|
31
|
+
path: string;
|
|
32
|
+
undo: string;
|
|
33
|
+
};
|
|
34
|
+
export type SetupPlan = CommandPlan | FilePlan;
|
|
35
|
+
/** A precise, client-specific operation for removing the Mercator MCP registration. */
|
|
36
|
+
export type RemovalPlan = {
|
|
37
|
+
args: string[];
|
|
38
|
+
command: string;
|
|
39
|
+
kind: 'command';
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'file';
|
|
42
|
+
path: string;
|
|
43
|
+
serverContainer: 'mcpServers' | 'servers';
|
|
44
|
+
} | {
|
|
45
|
+
instructions: string;
|
|
46
|
+
kind: 'manual';
|
|
47
|
+
};
|
|
48
|
+
export type ConfigurationState = 'current' | 'different' | 'missing' | 'unknown';
|
|
49
|
+
type RunCheck = (check: CommandCheck) => Promise<CommandResult>;
|
|
50
|
+
export declare const CLIENT_IDS: ("claude" | "cline" | "codex" | "continue" | "cursor" | "gemini" | "hermes" | "openclaw" | "vscode" | "windsurf")[];
|
|
51
|
+
export declare function setupPlan(client: ClientId, url: string, options?: {
|
|
52
|
+
cwd?: string;
|
|
53
|
+
home?: string;
|
|
54
|
+
}): SetupPlan;
|
|
55
|
+
/** Builds a conservative removal plan that never includes wallet state. */
|
|
56
|
+
export declare function removalPlan(client: ClientId, options?: {
|
|
57
|
+
cwd?: string;
|
|
58
|
+
home?: string;
|
|
59
|
+
platform?: NodeJS.Platform;
|
|
60
|
+
}): RemovalPlan;
|
|
61
|
+
export declare function configurationState(plan: SetupPlan, runCheck?: RunCheck): Promise<ConfigurationState>;
|
|
62
|
+
export declare function installedClients(isAvailable?: (command: string) => Promise<boolean>): Promise<ClientId[]>;
|
|
63
|
+
export declare function mergeConfigFile(plan: FilePlan): Promise<void>;
|
|
64
|
+
/** Removes only the Mercator server entry while preserving the rest of the file. */
|
|
65
|
+
export declare function removeConfigFile(plan: Extract<RemovalPlan, {
|
|
66
|
+
kind: 'file';
|
|
67
|
+
}>, options?: {
|
|
68
|
+
dryRun?: boolean;
|
|
69
|
+
}): Promise<'missing' | 'planned' | 'removed'>;
|
|
70
|
+
export {};
|