mcpocket 0.1.0 → 0.2.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE +1 -1
  3. package/README.md +309 -37
  4. package/dist/cli.js +30 -9
  5. package/dist/cli.js.map +1 -1
  6. package/dist/clients/antigravity.d.ts +5 -0
  7. package/dist/clients/antigravity.d.ts.map +1 -0
  8. package/dist/clients/antigravity.js +94 -0
  9. package/dist/clients/antigravity.js.map +1 -0
  10. package/dist/clients/claude-code.js +2 -2
  11. package/dist/clients/claude-desktop.js +2 -2
  12. package/dist/clients/codex.d.ts +5 -0
  13. package/dist/clients/codex.d.ts.map +1 -0
  14. package/dist/clients/codex.js +78 -0
  15. package/dist/clients/codex.js.map +1 -0
  16. package/dist/clients/copilot-cli.d.ts +5 -0
  17. package/dist/clients/copilot-cli.d.ts.map +1 -0
  18. package/dist/clients/copilot-cli.js +90 -0
  19. package/dist/clients/copilot-cli.js.map +1 -0
  20. package/dist/clients/cursor.d.ts +5 -0
  21. package/dist/clients/cursor.d.ts.map +1 -0
  22. package/dist/clients/cursor.js +77 -0
  23. package/dist/clients/cursor.js.map +1 -0
  24. package/dist/clients/opencode.js +2 -2
  25. package/dist/clients/providers.d.ts +7 -0
  26. package/dist/clients/providers.d.ts.map +1 -0
  27. package/dist/clients/providers.js +80 -0
  28. package/dist/clients/providers.js.map +1 -0
  29. package/dist/clients/types.d.ts +27 -1
  30. package/dist/clients/types.d.ts.map +1 -1
  31. package/dist/commands/dedupe.d.ts +2 -0
  32. package/dist/commands/dedupe.d.ts.map +1 -0
  33. package/dist/commands/dedupe.js +114 -0
  34. package/dist/commands/dedupe.js.map +1 -0
  35. package/dist/commands/init.d.ts.map +1 -1
  36. package/dist/commands/init.js +111 -43
  37. package/dist/commands/init.js.map +1 -1
  38. package/dist/commands/provider-options.d.ts +18 -0
  39. package/dist/commands/provider-options.d.ts.map +1 -0
  40. package/dist/commands/provider-options.js +34 -0
  41. package/dist/commands/provider-options.js.map +1 -0
  42. package/dist/commands/pull.d.ts +2 -1
  43. package/dist/commands/pull.d.ts.map +1 -1
  44. package/dist/commands/pull.js +101 -72
  45. package/dist/commands/pull.js.map +1 -1
  46. package/dist/commands/push.d.ts +2 -1
  47. package/dist/commands/push.d.ts.map +1 -1
  48. package/dist/commands/push.js +107 -51
  49. package/dist/commands/push.js.map +1 -1
  50. package/dist/commands/status.d.ts.map +1 -1
  51. package/dist/commands/status.js +38 -23
  52. package/dist/commands/status.js.map +1 -1
  53. package/dist/config.d.ts +11 -7
  54. package/dist/config.d.ts.map +1 -1
  55. package/dist/config.js +14 -9
  56. package/dist/config.js.map +1 -1
  57. package/dist/storage/gist.d.ts +21 -0
  58. package/dist/storage/gist.d.ts.map +1 -0
  59. package/dist/storage/gist.js +149 -0
  60. package/dist/storage/gist.js.map +1 -0
  61. package/dist/storage/github.d.ts +1 -1
  62. package/dist/storage/github.js +8 -8
  63. package/dist/sync/agents.d.ts +6 -2
  64. package/dist/sync/agents.d.ts.map +1 -1
  65. package/dist/sync/agents.js +35 -33
  66. package/dist/sync/agents.js.map +1 -1
  67. package/dist/sync/mcp.d.ts.map +1 -1
  68. package/dist/sync/mcp.js +75 -9
  69. package/dist/sync/mcp.js.map +1 -1
  70. package/dist/sync/plugins.d.ts +5 -1
  71. package/dist/sync/plugins.d.ts.map +1 -1
  72. package/dist/sync/plugins.js +16 -2
  73. package/dist/sync/plugins.js.map +1 -1
  74. package/dist/sync/pocket.d.ts +3 -0
  75. package/dist/sync/pocket.d.ts.map +1 -0
  76. package/dist/sync/pocket.js +16 -0
  77. package/dist/sync/pocket.js.map +1 -0
  78. package/dist/sync/skills.d.ts +3 -2
  79. package/dist/sync/skills.d.ts.map +1 -1
  80. package/dist/sync/skills.js +28 -18
  81. package/dist/sync/skills.js.map +1 -1
  82. package/dist/utils/crypto.d.ts +12 -1
  83. package/dist/utils/crypto.d.ts.map +1 -1
  84. package/dist/utils/crypto.js +19 -5
  85. package/dist/utils/crypto.js.map +1 -1
  86. package/dist/utils/files.d.ts +16 -0
  87. package/dist/utils/files.d.ts.map +1 -0
  88. package/dist/utils/files.js +168 -0
  89. package/dist/utils/files.js.map +1 -0
  90. package/dist/utils/paths.d.ts +20 -4
  91. package/dist/utils/paths.d.ts.map +1 -1
  92. package/dist/utils/paths.js +46 -11
  93. package/dist/utils/paths.js.map +1 -1
  94. package/dist/utils/sparkle.d.ts +60 -0
  95. package/dist/utils/sparkle.d.ts.map +1 -0
  96. package/dist/utils/sparkle.js +131 -0
  97. package/dist/utils/sparkle.js.map +1 -0
  98. package/package.json +6 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.2.0] - 2026-04-09
6
+
7
+ ### Added
8
+ - GitHub Gist storage as an alternative backend for syncing configuration.
9
+ - A `de-dupe` command to clean up stale synced agents, skills, and plugins.
10
+ - Multi-provider push and pull targeting with provider-specific CLI flags.
11
+
12
+ ### Changed
13
+ - Push and pull now mirror synced agent and skill files to prevent stale duplicates from accumulating.
14
+ - Sync logic was cleaned up to better handle provider-scoped MCP configuration flows.
15
+ - Internal imports were updated to use the `node:` prefix consistently.
16
+
17
+ ### Fixed
18
+ - README package assets and branding were aligned with the published `mcpocket` package.
19
+ - Error messages and package metadata were updated to reflect the `mcpocket` name.
20
+
21
+ ## [0.1.1] - 2026-04-09
22
+
23
+ ### Changed
24
+ - Renamed the package to `mcpocket` for npm publishing.
25
+ - Refreshed package branding and metadata for the npm release.
26
+
27
+ ## [0.1.0] - 2026-04-09
28
+
29
+ ### Added
30
+ - Initial release of `carry-on`, including encrypted MCP configuration sync across supported clients.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 davidsmorais
3
+ Copyright (c) 2026 David Morais <david@davidmorais.com>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,12 +1,39 @@
1
- # carry-on
1
+ <p align="center">
2
+ <img src="https://img.shields.io/npm/v/mcpocket?color=blue&label=npm" alt="npm version" />
3
+ <img src="https://img.shields.io/node/v/mcpocket" alt="node version" />
4
+ <img src="https://img.shields.io/github/license/davidsmorais/carry-on" alt="license" />
5
+ </p>
2
6
 
3
- > Your AI setup. Everywhere you work.
7
+ <p align="center">
8
+ <img src="./logo.png" alt="mcpocket logo" width="200" />
9
+ </p>
4
10
 
5
- `carry-on` syncs your Claude Code agents, skills, plugins, and MCP server configurations across machines — so your full AI loadout follows you everywhere.
11
+ # mcpocket
12
+
13
+ > Your AI setup. Every pocket. ✨
14
+
15
+ **mcpocket** syncs your Claude Code agents, skills, plugins, and MCP server configurations across machines — so your full AI loadout follows you everywhere, like magic.
16
+
17
+ ---
6
18
 
7
19
  ## The Problem
8
20
 
9
- You install 8 MCP servers, configure your Claude Code plugins, and build up a library of agents on your Linux machine. Then you switch to Windows and have nothing. `carry-on` fixes that with two commands.
21
+ You install 8 MCP servers, configure your Claude Code plugins, and build up a library of agents on your Linux workstation. Then you switch to your Windows laptop and nothing. You start from scratch. Again.
22
+
23
+ **mcpocket** fixes that with two commands: `push` from your source machine, `pull` on any other.
24
+
25
+ ## Features
26
+
27
+ - **Multi-client sync** — Claude Desktop, Claude Code, OpenCode, Copilot CLI, Cursor, Codex, and Antigravity configs in one shot
28
+ - **Two storage backends** — private GitHub repo (full git history) or lightweight GitHub Gist
29
+ - **Provider-scoped sync** — target one or more providers with flags like `--copilot-cli` or `--opencode`
30
+ - **End-to-end encryption** — secrets in MCP `env`, `headers`, and `http_headers` are encrypted with AES-256-GCM using a passphrase you choose
31
+ - **Cross-platform paths** — Windows ↔ Linux ↔ macOS paths round-trip seamlessly
32
+ - **Additive pull** — pulling merges remote servers into your local config without overwriting anything
33
+ - **De-duplicated file sync** — push/pull mirror synced files so stale agent, skill, and plugin files don't pile up
34
+ - **Zero dependencies on external services** — only GitHub and Git
35
+
36
+ ---
10
37
 
11
38
  ## Install
12
39
 
@@ -14,73 +41,318 @@ You install 8 MCP servers, configure your Claude Code plugins, and build up a li
14
41
  npm install -g mcpocket
15
42
  ```
16
43
 
17
- ## Usage
44
+ Or with pnpm / yarn:
18
45
 
19
- ### 1. Initialize (once per machine)
46
+ ```bash
47
+ pnpm add -g mcpocket
48
+ # or
49
+ yarn global add mcpocket
50
+ ```
51
+
52
+ ## Quick Start
20
53
 
21
54
  ```bash
22
- carry-on init
55
+ # 1. Initialize (once per machine)
56
+ mcpocket init
57
+
58
+ # 2. Push your setup to the cloud
59
+ mcpocket push
60
+
61
+ # 3. Pull on a new machine
62
+ mcpocket pull
63
+
64
+ # 4. Clean up stale synced files if needed
65
+ mcpocket de-dupe
66
+
67
+ # 5. Check sync status
68
+ mcpocket status
23
69
  ```
24
70
 
25
- Connects to GitHub, creates a private `carry-on-sync` repo, and clones it locally. Requires a [GitHub personal access token](https://github.com/settings/tokens/new) with `repo` scope.
71
+ ---
72
+
73
+ ## Commands
74
+
75
+ ### `mcpocket init`
76
+
77
+ Interactive setup wizard. Links your GitHub account, chooses a storage backend, and creates the remote pocket.
78
+
79
+ ```
80
+ $ mcpocket init
81
+
82
+ ✦ First, let's link your GitHub account.
83
+ Required scopes: repo (full control of private repositories)
84
+
85
+ 🔑 GitHub token: ****
86
+
87
+ ✦ Authenticated as davidsmorais — nice to meet you!
88
+
89
+ ✦ Where should mcpocket store your config?
90
+ [1] GitHub repo (private repo, full git history)
91
+ [2] GitHub gist (lighter, no git clone needed)
92
+
93
+ Pick one [1/2]: 1
94
+ ```
95
+
96
+ **Storage options:**
97
+
98
+ | Option | Backend | Requires Git? | History |
99
+ |---|---|---|---|
100
+ | `1` — Repo | Private `mcpocket-sync` repo | Yes | Full git log |
101
+ | `2` — Gist | Private GitHub Gist | No | Gist revisions |
26
102
 
27
- ### 2. Push your setup
103
+ Requires a [GitHub personal access token](https://github.com/settings/tokens/new) with **`repo`** scope (for repo mode) or **`gist`** scope (for gist mode).
104
+
105
+ ### `mcpocket push`
106
+
107
+ Reads MCP configs, plugin manifests, agents, and skills from the current machine. Encrypts secrets with a passphrase you choose, then uploads to your private pocket.
108
+
109
+ ```bash
110
+ mcpocket push
111
+ ```
112
+
113
+ Target specific providers by passing one or more flags:
114
+
115
+ ```bash
116
+ mcpocket push --copilot-cli
117
+ mcpocket push --cursor --codex
118
+ ```
119
+
120
+ When provider flags are present, they scope the whole command:
121
+
122
+ - Only the selected providers' MCP configs are read and packed into `mcp-config.json`
123
+ - Claude home assets (`~/.claude/plugins`, `~/.claude/agents`, `~/.claude/skills`) are only synced when `--claude-code` is included
124
+
125
+ - In **repo mode**: commits and pushes to your private GitHub repo.
126
+ - In **gist mode**: uploads files to your private GitHub Gist (directory structure is flattened with `__` separators).
127
+
128
+ ### `mcpocket pull`
129
+
130
+ Downloads your config from the remote pocket, decrypts secrets with your passphrase, and writes everything to the appropriate client config files:
28
131
 
29
132
  ```bash
30
- carry-on push
133
+ mcpocket pull
31
134
  ```
32
135
 
33
- Reads MCP configs, plugin manifests, agents, and skills from your current machine. Encrypts any secrets (API keys in MCP env vars) with a passphrase you choose, then commits and pushes to your private GitHub repo.
136
+ You can also pull into only the providers you want:
137
+
138
+ ```bash
139
+ mcpocket pull --opencode
140
+ mcpocket pull --cursor --copilot-cli
141
+ ```
142
+
143
+ With provider flags, pull only writes MCP servers to those selected providers. Claude home assets are only restored when `--claude-code` is included.
144
+
145
+ | Client | Config file |
146
+ |---|---|
147
+ | Claude Desktop | `claude_desktop_config.json` |
148
+ | Claude Code | `~/.claude/settings.json` |
149
+ | OpenCode | `~/.config/opencode/config.json` |
150
+ | Copilot CLI | VS Code/Copilot user `mcp.json` |
151
+ | Cursor | `~/.cursor/mcp.json` |
152
+ | Codex | `~/.codex/config.toml` |
153
+ | Antigravity | `~/.gemini/antigravity/mcp_config.json` |
34
154
 
35
- ### 3. Pull on a new machine
155
+ Pull is **additive** — it adds servers that exist remotely but not locally, without overwriting your existing local config. Restart Claude Desktop after pulling to apply MCP changes.
156
+
157
+ For synced files, pull also removes stale agent and skill files that were previously synced but no longer exist in your pocket.
158
+
159
+ ### `mcpocket de-dupe`
160
+
161
+ Refreshes the pocket, mirrors the current synced files, removes stale duplicates on both sides, and writes the cleaned result back to your configured backend.
36
162
 
37
163
  ```bash
38
- carry-on pull
164
+ mcpocket de-dupe
39
165
  ```
40
166
 
41
- Pulls your config from GitHub, decrypts secrets with your passphrase, and writes everything to:
42
- - **Claude Desktop** — `claude_desktop_config.json`
43
- - **Claude Code** — `~/.claude/settings.json`
44
- - **OpenCode** — `~/.config/opencode/config.json`
167
+ Use this if you already have duplicate or renamed agent/skill/plugin files from earlier syncs. In normal use, `push` and `pull` now keep these folders de-duplicated automatically.
45
168
 
46
- Then restart Claude Desktop to apply MCP changes.
169
+ ### `mcpocket status`
47
170
 
48
- ### Check sync status
171
+ Shows a diff of what's synced, what's local-only, and what's remote-only:
49
172
 
50
173
  ```bash
51
- carry-on status
174
+ mcpocket status
52
175
  ```
53
176
 
54
- Shows which MCP servers, plugins, agents, and skills are synced vs. local-only vs. remote-only.
177
+ ```
178
+ ── MCP Servers ──
179
+
180
+ Synced:
181
+ ✓ filesystem
182
+ ✓ github
183
+
184
+ Local only (run push):
185
+ ↑ sqlite
186
+
187
+ In pocket, not here (run pull):
188
+ ↓ postgres
189
+ ```
190
+
191
+ ---
55
192
 
56
193
  ## What Gets Synced
57
194
 
58
- | What | Where |
59
- |---|---|
60
- | MCP server configs | All clients — Claude Desktop, Claude Code, OpenCode |
61
- | Plugin manifests | `installed_plugins.json`, `blocklist.json`, `known_marketplaces.json` |
62
- | Agents | `~/.claude/agents/**/*.md` |
63
- | Skills | `~/.claude/skills/**` (excluding `node_modules`) |
195
+ | Category | Source | Details |
196
+ |---|---|---|
197
+ | MCP server configs | Claude Desktop, Claude Code, OpenCode, Copilot CLI, Cursor, Codex, Antigravity | Merged across all selected providers |
198
+ | Plugin manifests | `~/.claude/plugins/` | `installed_plugins.json`, `blocklist.json`, `known_marketplaces.json` |
199
+ | Agents | `~/.claude/agents/` | All `*.md` files, recursively |
200
+ | Skills | `~/.claude/skills/` | All files, recursively (excluding `node_modules`) |
201
+
202
+ If you do not pass provider flags, `push` and `pull` operate on every supported provider. If you do pass flags, only those providers participate in the command.
203
+
204
+ ### Never Synced
205
+
206
+ - `.credentials.json`
207
+ - `plugins/cache/`
208
+ - Sessions and telemetry data
209
+ - Your GitHub token (stays in local `~/.mcpocket/config.json`)
64
210
 
65
- **Never synced:** `.credentials.json`, `plugins/cache/`, sessions, telemetry.
211
+ ---
66
212
 
67
213
  ## Security
68
214
 
69
- - Secrets (MCP `env` vars) are encrypted with AES-256-GCM before upload
70
- - Your passphrase is never stored anywhere
71
- - Config repo is always private
72
- - GitHub token is stored in `~/.carry-on/config.json` (chmod 600 on Linux/Mac)
215
+ | Concern | How mcpocket handles it |
216
+ |---|---|
217
+ | API keys & tokens | Encrypted with **AES-256-GCM** (via `scrypt` key derivation) before leaving your machine |
218
+ | Passphrase storage | **Never stored** you enter it on every push/pull |
219
+ | Remote storage | Always **private** (private repo or secret gist) |
220
+ | Local config | `~/.mcpocket/config.json` is `chmod 600` on Linux/macOS |
221
+ | Git auth | Token is injected at runtime into HTTPS URLs, never persisted in git config |
222
+ | Error output | Git errors are sanitized to strip tokens before display |
223
+
224
+ ### Encryption Format
225
+
226
+ Encrypted values are stored as:
227
+
228
+ ```
229
+ ENCRYPTED:<iv_hex>:<salt_hex>:<authTag_hex>:<ciphertext_hex>
230
+ ```
231
+
232
+ Each value uses a unique random salt and IV, so identical plaintext values produce different ciphertexts.
233
+
234
+ ---
73
235
 
74
236
  ## Path Handling
75
237
 
76
- `carry-on` normalizes paths on push (`/home/user/...` → `~/...`) and expands them for the current platform on pull. Windows and Linux absolute paths round-trip correctly.
238
+ mcpocket normalizes paths for portability:
239
+
240
+ | Direction | Transformation |
241
+ |---|---|
242
+ | Push | `/home/user/...` or `C:\Users\user\...` → `~/...` |
243
+ | Pull | `~/...` → platform-native absolute path |
244
+ | Commands | `.cmd` / `.exe` extensions stripped on push, restored on pull (Windows) |
245
+
246
+ This means a config pushed from Linux works on Windows and vice versa.
247
+
248
+ ---
249
+
250
+ ## Configuration
251
+
252
+ mcpocket stores its own config at `~/.mcpocket/config.json`:
253
+
254
+ ```jsonc
255
+ {
256
+ "githubToken": "ghp_...",
257
+ "storageType": "repo", // "repo" or "gist"
258
+ // Repo mode:
259
+ "repoFullName": "user/mcpocket-sync",
260
+ "repoCloneUrl": "https://github.com/user/mcpocket-sync.git",
261
+ "repoHtmlUrl": "https://github.com/user/mcpocket-sync",
262
+ // Gist mode:
263
+ "gistId": "abc123...",
264
+ "gistUrl": "https://gist.github.com/abc123..."
265
+ }
266
+ ```
267
+
268
+ The local repo clone (used as a staging area) lives at `~/.mcpocket/repo/`.
269
+
270
+ ---
77
271
 
78
272
  ## Requirements
79
273
 
80
- - Node.js 18+
81
- - Git (must be in PATH)
82
- - A GitHub account
274
+ - **Node.js** 18+
275
+ - **Git** in PATH (repo mode only — gist mode doesn't need git)
276
+ - A **GitHub account** with a personal access token
277
+
278
+ ---
279
+
280
+ ## Project Structure
281
+
282
+ ```
283
+ src/
284
+ cli.ts # Entry point, Commander setup
285
+ config.ts # Config read/write, storage type definitions
286
+ clients/
287
+ claude-desktop.ts # Claude Desktop config reader/writer
288
+ claude-code.ts # Claude Code settings reader/writer
289
+ opencode.ts # OpenCode config reader/writer
290
+ types.ts # Shared MCP server type definitions
291
+ commands/
292
+ init.ts # Interactive setup wizard
293
+ push.ts # Push local config to remote
294
+ pull.ts # Pull remote config to local
295
+ status.ts # Diff local vs. remote
296
+ storage/
297
+ github.ts # GitHub repo CRUD + git operations
298
+ gist.ts # GitHub Gist CRUD + file flattening
299
+ sync/
300
+ agents.ts # Agent file sync logic
301
+ mcp.ts # MCP server merge, pack/unpack, encrypt/decrypt
302
+ plugins.ts # Plugin manifest sync logic
303
+ skills.ts # Skills file sync logic
304
+ utils/
305
+ crypto.ts # AES-256-GCM encrypt/decrypt helpers
306
+ paths.ts # Cross-platform path normalization
307
+ prompt.ts # Interactive CLI input helpers
308
+ sparkle.ts # CLI banners, spinners, and personality
309
+ ```
310
+
311
+ ---
312
+
313
+ ## Troubleshooting
314
+
315
+ ### "mcpocket is not initialized"
316
+
317
+ Run `mcpocket init` first to set up your GitHub connection and storage backend.
318
+
319
+ ### "Decryption failed — wrong passphrase"
320
+
321
+ The passphrase you entered doesn't match the one used during `mcpocket push`. Passphrases are never stored — you need to remember the one you used.
322
+
323
+ ### Push says "Nothing changed"
324
+
325
+ Your local config matches what's already in the remote pocket. No commit/upload needed.
326
+
327
+ ### MCP servers not appearing after pull
328
+
329
+ Restart Claude Desktop to reload MCP server configurations. Claude Code and OpenCode pick up changes automatically.
330
+
331
+ ### Git errors on push/pull (repo mode)
332
+
333
+ Make sure `git` is installed and in your PATH. If you see auth errors, your GitHub token may have expired — run `mcpocket init` to re-authenticate.
334
+
335
+ ---
336
+
337
+ ## Contributing
338
+
339
+ Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/davidsmorais/carry-on).
340
+
341
+ ```bash
342
+ git clone https://github.com/davidsmorais/carry-on.git
343
+ cd carry-on
344
+ pnpm install
345
+ pnpm build
346
+ ```
347
+
348
+ ---
349
+
350
+ ## Author
351
+
352
+ **David Morais** — [david@davidmorais.com](mailto:david@davidmorais.com)
353
+
354
+ - GitHub: [@davidsmorais](https://github.com/davidsmorais)
83
355
 
84
356
  ## License
85
357
 
86
- MIT
358
+ [MIT](LICENSE) © David Morais
package/dist/cli.js CHANGED
@@ -5,31 +5,52 @@ const commander_1 = require("commander");
5
5
  const init_js_1 = require("./commands/init.js");
6
6
  const push_js_1 = require("./commands/push.js");
7
7
  const pull_js_1 = require("./commands/pull.js");
8
+ const dedupe_js_1 = require("./commands/dedupe.js");
8
9
  const status_js_1 = require("./commands/status.js");
10
+ const providers_js_1 = require("./clients/providers.js");
11
+ const sparkle_js_1 = require("./utils/sparkle.js");
9
12
  const program = new commander_1.Command();
13
+ (0, sparkle_js_1.printBanner)();
10
14
  program
11
- .name('carry-on')
12
- .description('Your AI setup. Everywhere you work.\nSyncs Claude Code agents, skills, plugins, and MCPs across machines.')
15
+ .name('mcpocket')
16
+ .description('Your AI setup. Every pocket.\nSyncs agents, skills, plugins, and MCPs across all your machines like magic.')
13
17
  .version('0.1.0');
14
18
  program
15
19
  .command('init')
16
- .description('Set up carry-on: connect GitHub, create sync repo')
20
+ .description('Set up mcpocket: connect GitHub, create your sync pocket')
17
21
  .action(() => (0, init_js_1.initCommand)().catch(die));
18
22
  program
19
23
  .command('push')
20
- .description('Upload your current AI setup to the cloud')
21
- .action(() => (0, push_js_1.pushCommand)().catch(die));
24
+ .description('Tuck your AI setup into the cloud pocket');
25
+ for (const provider of providers_js_1.PROVIDER_OPTION_FLAGS) {
26
+ program.commands.find((command) => command.name() === 'push')?.option(provider.flag, provider.description);
27
+ }
28
+ program
29
+ .commands
30
+ .find((command) => command.name() === 'push')
31
+ ?.action((options) => (0, push_js_1.pushCommand)(options).catch(die));
22
32
  program
23
33
  .command('pull')
24
- .description('Restore your AI setup from the cloud')
25
- .action(() => (0, pull_js_1.pullCommand)().catch(die));
34
+ .description('Unpack your AI setup from the cloud pocket');
35
+ for (const provider of providers_js_1.PROVIDER_OPTION_FLAGS) {
36
+ program.commands.find((command) => command.name() === 'pull')?.option(provider.flag, provider.description);
37
+ }
38
+ program
39
+ .commands
40
+ .find((command) => command.name() === 'pull')
41
+ ?.action((options) => (0, pull_js_1.pullCommand)(options).catch(die));
42
+ program
43
+ .command('de-dupe')
44
+ .alias('dedupe')
45
+ .description('Clean stale synced files from your pocket and local folders')
46
+ .action(() => (0, dedupe_js_1.dedupeCommand)().catch(die));
26
47
  program
27
48
  .command('status')
28
- .description('Show what\'s synced vs. local-only vs. remote-only')
49
+ .description('Peek inside: what\'s synced, what\'s local, what\'s remote')
29
50
  .action(() => (0, status_js_1.statusCommand)().catch(die));
30
51
  program.parse();
31
52
  function die(err) {
32
- console.error(`\nError: ${err.message}`);
53
+ (0, sparkle_js_1.oops)(err.message);
33
54
  process.exit(1);
34
55
  }
35
56
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,oDAAqD;AAErD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,2GAA2G,CAAC;KACxH,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,mDAAmD,CAAC;KAChE,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,qBAAW,GAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1C,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,qBAAW,GAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1C,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,qBAAW,GAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1C,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,yBAAa,GAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAE5C,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,SAAS,GAAG,CAAC,GAAU;IACrB,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,gDAAiD;AACjD,gDAAiD;AACjD,gDAAiD;AACjD,oDAAqD;AACrD,oDAAqD;AACrD,yDAA+D;AAC/D,mDAAuD;AAEvD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,IAAA,wBAAW,GAAE,CAAC;AAEd,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,4GAA4G,CAAC;KACzH,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0DAA0D,CAAC;KACvE,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,qBAAW,GAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1C,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0CAA0C,CAAC,CAAA;AAE1D,KAAK,MAAM,QAAQ,IAAI,oCAAqB,EAAE,CAAC;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC7G,CAAC;AAED,OAAO;KACJ,QAAQ;KACR,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC;IAC7C,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAA,qBAAW,EAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAEzD,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,4CAA4C,CAAC,CAAA;AAE5D,KAAK,MAAM,QAAQ,IAAI,oCAAqB,EAAE,CAAC;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC7G,CAAC;AAED,OAAO;KACJ,QAAQ;KACR,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC;IAC7C,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAA,qBAAW,EAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAEzD,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,KAAK,CAAC,QAAQ,CAAC;KACf,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,yBAAa,GAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAE5C,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,4DAA4D,CAAC;KACzE,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,yBAAa,GAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAE5C,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,SAAS,GAAG,CAAC,GAAU;IACrB,IAAA,iBAAI,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { McpServersMap } from './types.js';
2
+ export declare function readAntigravityMcpServers(): McpServersMap;
3
+ export declare function writeAntigravityMcpServers(servers: McpServersMap): void;
4
+ export declare function getConfigPath(): string;
5
+ //# sourceMappingURL=antigravity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antigravity.d.ts","sourceRoot":"","sources":["../../src/clients/antigravity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAmB,aAAa,EAAE,MAAM,YAAY,CAAC;AAOjE,wBAAgB,yBAAyB,IAAI,aAAa,CAgBzD;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAsBvE;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.readAntigravityMcpServers = readAntigravityMcpServers;
37
+ exports.writeAntigravityMcpServers = writeAntigravityMcpServers;
38
+ exports.getConfigPath = getConfigPath;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const paths_js_1 = require("../utils/paths.js");
42
+ function readAntigravityMcpServers() {
43
+ const configPath = (0, paths_js_1.getAntigravityConfigPath)();
44
+ if (!fs.existsSync(configPath)) {
45
+ return {};
46
+ }
47
+ try {
48
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
49
+ const servers = config.mcpServers ?? {};
50
+ return Object.fromEntries(Object.entries(servers).map(([name, server]) => [name, fromAntigravityServer(server)]));
51
+ }
52
+ catch {
53
+ console.warn(`[mcpocket] Could not read Antigravity MCP config at ${configPath}`);
54
+ return {};
55
+ }
56
+ }
57
+ function writeAntigravityMcpServers(servers) {
58
+ const configPath = (0, paths_js_1.getAntigravityConfigPath)();
59
+ const dir = path.dirname(configPath);
60
+ let config = {};
61
+ if (fs.existsSync(configPath)) {
62
+ try {
63
+ config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
64
+ }
65
+ catch {
66
+ console.warn(`[mcpocket] Could not parse existing Antigravity config, will overwrite mcpServers only`);
67
+ }
68
+ }
69
+ else {
70
+ fs.mkdirSync(dir, { recursive: true });
71
+ }
72
+ const existing = config.mcpServers ?? {};
73
+ const mappedServers = Object.fromEntries(Object.entries(servers).map(([name, server]) => [name, toAntigravityServer(server)]));
74
+ config.mcpServers = { ...existing, ...mappedServers };
75
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
76
+ }
77
+ function getConfigPath() {
78
+ return (0, paths_js_1.getAntigravityConfigPath)();
79
+ }
80
+ function fromAntigravityServer(server) {
81
+ if (!server.serverUrl) {
82
+ return server;
83
+ }
84
+ const { serverUrl, ...rest } = server;
85
+ return { ...rest, url: serverUrl };
86
+ }
87
+ function toAntigravityServer(server) {
88
+ if (!server.url) {
89
+ return server;
90
+ }
91
+ const { url, ...rest } = server;
92
+ return { ...rest, serverUrl: url };
93
+ }
94
+ //# sourceMappingURL=antigravity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../../src/clients/antigravity.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,8DAgBC;AAED,gEAsBC;AAED,sCAEC;AAtDD,uCAAyB;AACzB,2CAA6B;AAC7B,gDAA6D;AAQ7D,SAAgB,yBAAyB;IACvC,MAAM,UAAU,GAAG,IAAA,mCAAwB,GAAE,CAAC;IAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAyB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;QACrF,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;QACxC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC,CACvF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,uDAAuD,UAAU,EAAE,CAAC,CAAC;QAClF,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAgB,0BAA0B,CAAC,OAAsB;IAC/D,MAAM,UAAU,GAAG,IAAA,mCAAwB,GAAE,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAErC,IAAI,MAAM,GAAyB,EAAE,CAAC;IACtC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,wFAAwF,CAAC,CAAC;QACzG,CAAC;IACH,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;IACzC,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CACtC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CACrF,CAAC;IAEF,MAAM,CAAC,UAAU,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,aAAa,EAAE,CAAC;IACtD,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACxE,CAAC;AAED,SAAgB,aAAa;IAC3B,OAAO,IAAA,mCAAwB,GAAE,CAAC;AACpC,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAgD;IAC7E,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IACtC,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAuB;IAClD,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IAChC,OAAO,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AACrC,CAAC"}
@@ -49,7 +49,7 @@ function readClaudeCodeSettings() {
49
49
  return JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
50
50
  }
51
51
  catch {
52
- console.warn(`[carry-on] Could not read Claude Code settings at ${settingsPath}`);
52
+ console.warn(`[mcpocket] Could not read Claude Code settings at ${settingsPath}`);
53
53
  return {};
54
54
  }
55
55
  }
@@ -65,7 +65,7 @@ function writeClaudeCodeMcpServers(servers) {
65
65
  settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
66
66
  }
67
67
  catch {
68
- console.warn(`[carry-on] Could not parse existing Claude Code settings, will overwrite mcpServers only`);
68
+ console.warn(`[mcpocket] Could not parse existing Claude Code settings, will overwrite mcpServers only`);
69
69
  }
70
70
  }
71
71
  else {
@@ -50,7 +50,7 @@ function readClaudeDesktopMcpServers() {
50
50
  return config.mcpServers ?? {};
51
51
  }
52
52
  catch {
53
- console.warn(`[carry-on] Could not read Claude Desktop config at ${configPath}`);
53
+ console.warn(`[mcpocket] Could not read Claude Desktop config at ${configPath}`);
54
54
  return {};
55
55
  }
56
56
  }
@@ -63,7 +63,7 @@ function writeClaudeDesktopMcpServers(servers) {
63
63
  config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
64
64
  }
65
65
  catch {
66
- console.warn(`[carry-on] Could not parse existing Claude Desktop config, will overwrite mcpServers only`);
66
+ console.warn(`[mcpocket] Could not parse existing Claude Desktop config, will overwrite mcpServers only`);
67
67
  }
68
68
  }
69
69
  else {
@@ -0,0 +1,5 @@
1
+ import type { McpServersMap } from './types.js';
2
+ export declare function readCodexMcpServers(): McpServersMap;
3
+ export declare function writeCodexMcpServers(servers: McpServersMap): void;
4
+ export declare function getConfigPath(): string;
5
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/clients/codex.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD,wBAAgB,mBAAmB,IAAI,aAAa,CAanD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAiBjE;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}