inscope 0.8.4 โ 0.8.6
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 +111 -93
- package/dist/bin/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,77 +7,73 @@
|
|
|
7
7
|
[](https://www.npmjs.com/package/inscope)
|
|
8
8
|
[](https://github.com/nrjdalal/inscope)
|
|
9
9
|
|
|
10
|
-
๐ **The why behind the design:** [Race-Free Identity in Claude Code](https://zerostarter.dev/blog/mcp-per-workspace) aka multiple gh, linear, notion, slack and other accounts.
|
|
10
|
+
๐ **The why behind the design:** [Race-Free Identity in Claude Code](https://zerostarter.dev/blog/mcp-per-workspace), aka multiple gh, linear, notion, slack and other accounts.
|
|
11
11
|
|
|
12
12
|
> #### `cd` into a project and you are the right person: the right GitHub token, the right MCP servers, the right git commit email, all resolved live from `$PWD`. No toggles, no profile switching, and it holds up with several Claude Code sessions open at once.
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
|
-
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/demo.gif" alt="inscope
|
|
15
|
+
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/demo.gif" alt="inscope flips git identity and the GitHub token per directory on cd" width="900" />
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
You describe each workspace once; `inscope` owns the moving parts and keeps them in sync from a single source of truth:
|
|
19
19
|
|
|
20
20
|
- a `.mcp.json` at each workspace root, with uniquely named servers
|
|
21
|
-
-
|
|
22
|
-
- git `includeIf` rules so commits
|
|
21
|
+
- one zsh `chpwd` hook that resolves the right tokens from `$PWD`
|
|
22
|
+
- git `includeIf` rules so commits land with the right author email per path
|
|
23
23
|
|
|
24
|
-
Nothing sensitive is written to disk
|
|
24
|
+
Nothing sensitive is written to disk: GitHub tokens come from the `gh` keyring and Slack tokens from the macOS Keychain, resolved live by the hook. It is race-free across concurrent shells and Claude Code sessions, with no global toggles, and idempotent: only the blocks it owns inside `.zshrc`, `.gitconfig`, and `.mcp.json` are ever touched.
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
28
28
|
### Table of Contents
|
|
29
29
|
|
|
30
|
-
- [Some Examples](#-some-examples)
|
|
31
|
-
- [Features](#-features)
|
|
32
|
-
- [Requirements](#-requirements)
|
|
33
30
|
- [Quick Usage](#-quick-usage)
|
|
31
|
+
- [Requirements](#-requirements)
|
|
34
32
|
- [Commands](#-commands)
|
|
33
|
+
- [`inscope init`](#inscope-init)
|
|
34
|
+
- [`inscope add`](#inscope-add)
|
|
35
|
+
- [`inscope edit`](#inscope-edit)
|
|
36
|
+
- [`inscope rm`](#inscope-rm)
|
|
37
|
+
- [`inscope list`](#inscope-list)
|
|
38
|
+
- [`inscope diff`](#inscope-diff)
|
|
39
|
+
- [`inscope apply`](#inscope-apply)
|
|
40
|
+
- [`inscope doctor`](#inscope-doctor)
|
|
35
41
|
- [What It Manages](#-what-it-manages)
|
|
36
42
|
- [MCP Servers](#-mcp-servers)
|
|
37
43
|
- [Config File](#-config-file)
|
|
44
|
+
- [Install Globally (Optional)](#-install-globally-optional)
|
|
38
45
|
- [Contributing](#-contributing)
|
|
39
46
|
|
|
40
47
|
---
|
|
41
48
|
|
|
42
|
-
##
|
|
49
|
+
## ๐ Quick Usage
|
|
50
|
+
|
|
51
|
+
No install required, just prefix any command with `npx`:
|
|
43
52
|
|
|
44
53
|
```sh
|
|
45
54
|
# set up the config + hook, and source it from ~/.zshrc
|
|
46
|
-
inscope init
|
|
47
|
-
|
|
48
|
-
# map a workspace โ inscope prompts for the gh account, git identity, and servers
|
|
49
|
-
inscope add ~/acme
|
|
50
|
-
inscope add ~/personal
|
|
55
|
+
npx inscope init
|
|
51
56
|
|
|
52
|
-
#
|
|
53
|
-
inscope
|
|
57
|
+
# map a workspace - inscope walks you through gh account, git identity, and servers
|
|
58
|
+
npx inscope add ~/acme
|
|
59
|
+
npx inscope add ~/personal
|
|
54
60
|
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
inscope doctor
|
|
58
|
-
|
|
59
|
-
# remove a workspace (asks you to type the label to confirm)
|
|
60
|
-
inscope rm acme
|
|
61
|
+
# reload your shell, then verify
|
|
62
|
+
source ~/.zshrc
|
|
63
|
+
npx inscope doctor
|
|
61
64
|
```
|
|
62
65
|
|
|
63
|
-
|
|
66
|
+
Scoping GitHub accounts? Sign each one into `gh` once with `gh auth login` (that is gh's own command, not inscope); inscope reads tokens from the accounts you have signed in.
|
|
64
67
|
|
|
65
|
-
|
|
66
|
-
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/demo-switch.gif" alt="inscope switching git identity and tokens on cd" width="900" />
|
|
67
|
-
</p>
|
|
68
|
+
`cd ~/acme/api` and you are the work account, with work MCP servers and your work commit email. `cd ~/personal/blog` and you are you. Launch `claude` from inside a mapped directory (or relaunch) to pick up the identity.
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
Prefer flags or CI? Every prompt has a flag, and `-y` takes the defaults non-interactively:
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
```sh
|
|
73
|
+
npx inscope add ~/acme --gh <account> --email you@work.com --servers github,linear -y
|
|
74
|
+
```
|
|
72
75
|
|
|
73
|
-
|
|
74
|
-
- ๐งต Race-free across concurrent shells and Claude Code sessions, with no global toggles
|
|
75
|
-
- ๐ No secrets on disk: GitHub tokens from the `gh` keyring, Slack tokens from the macOS Keychain
|
|
76
|
-
- ๐ค One `.mcp.json` per workspace with uniquely named servers โ GitHub plus OAuth connectors for Atlassian, Canva, ClickUp, HubSpot, Intercom, Linear, monday, Notion, Plane, Sentry, Slack, Stripe, Vercel and Webflow
|
|
77
|
-
- โ๏ธ Git `includeIf` rules so every commit lands with the right author email per path
|
|
78
|
-
- ๐ช A single zsh `chpwd` hook does all the resolution; nothing else touches your shell
|
|
79
|
-
- ๐ฉบ `inscope doctor` verifies tokens, identities, and the hook before you trust them
|
|
80
|
-
- โป๏ธ Idempotent and surgical: only the managed blocks in `.zshrc`, `.gitconfig` and `.mcp.json` are touched
|
|
76
|
+
Running these a lot? Drop the `npx` with a [global install](#-install-globally-optional).
|
|
81
77
|
|
|
82
78
|
---
|
|
83
79
|
|
|
@@ -89,64 +85,39 @@ macOS, zsh, and [Claude Code](https://claude.com/claude-code).
|
|
|
89
85
|
|
|
90
86
|
---
|
|
91
87
|
|
|
92
|
-
##
|
|
93
|
-
|
|
94
|
-
Install globally (the CLI manages your shell hook, so a global install is expected):
|
|
95
|
-
|
|
96
|
-
```sh
|
|
97
|
-
npm i -g inscope
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Scoping GitHub accounts? Sign each one into `gh` once with `gh auth login` (that's gh's own command, not inscope). inscope reads tokens from the accounts you've signed in.
|
|
101
|
-
|
|
102
|
-
```sh
|
|
103
|
-
# set up the config + hook, and source it from ~/.zshrc
|
|
104
|
-
inscope init
|
|
105
|
-
|
|
106
|
-
# map a workspace โ inscope walks you through the gh account, git identity, and servers
|
|
107
|
-
inscope add ~/acme
|
|
108
|
-
inscope add ~/personal
|
|
88
|
+
## ๐ง Commands
|
|
109
89
|
|
|
110
|
-
# reload your shell, then verify
|
|
111
|
-
source ~/.zshrc
|
|
112
|
-
inscope doctor
|
|
113
90
|
```
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
inscope
|
|
91
|
+
inscope init Create the config, generate the hook, source it from ~/.zshrc
|
|
92
|
+
inscope add [path] Map a directory to a GitHub account, git email, and MCP servers
|
|
93
|
+
inscope edit [path] Edit a workspace interactively, then re-apply
|
|
94
|
+
inscope rm [path] Remove a workspace mapping (alias: remove)
|
|
95
|
+
inscope list List configured workspaces (alias: ls)
|
|
96
|
+
inscope diff Preview what apply would change; --adopt pulls on-disk extras back
|
|
97
|
+
inscope apply Regenerate the hook, git includes, and .mcp.json (alias: sync)
|
|
98
|
+
inscope doctor Verify tokens, identities, and the hook resolve correctly
|
|
99
|
+
|
|
100
|
+
-v, --version Display version
|
|
101
|
+
-h, --help Display help
|
|
121
102
|
```
|
|
122
103
|
|
|
123
|
-
|
|
104
|
+
Run any command with `-h` for its full options.
|
|
124
105
|
|
|
125
|
-
|
|
106
|
+
### `inscope init`
|
|
126
107
|
|
|
127
|
-
|
|
128
|
-
inscope init Create the config, generate the hook, source it from ~/.zshrc
|
|
129
|
-
inscope add [path] Map a directory to a GitHub account, git email, and MCP servers
|
|
130
|
-
inscope edit [path] Edit a workspace interactively, then re-apply
|
|
131
|
-
inscope rm [path] Remove a workspace mapping (alias: remove)
|
|
132
|
-
inscope list List configured workspaces (alias: ls)
|
|
133
|
-
inscope diff Preview what apply would change; --adopt pulls on-disk extras back
|
|
134
|
-
inscope apply Regenerate the hook, git includes, and .mcp.json (alias: sync)
|
|
135
|
-
inscope doctor Verify tokens, identities, and the hook resolve correctly
|
|
136
|
-
|
|
137
|
-
-v, --version Display version
|
|
138
|
-
-h, --help Display help
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Run any command with `-h` for its options.
|
|
108
|
+
Create the config, generate the chpwd hook, and add a source line to `~/.zshrc`. Safe to run again; it never overwrites your config.
|
|
142
109
|
|
|
143
110
|
<p align="center">
|
|
144
|
-
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/
|
|
111
|
+
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/init.gif" alt="inscope init creating the config and hook" width="900" />
|
|
145
112
|
</p>
|
|
146
113
|
|
|
147
114
|
### `inscope add`
|
|
148
115
|
|
|
149
|
-
Run it bare and it walks you through everything: pick the GitHub account from your signed-in `gh` accounts, accept your global git identity or set a per-workspace one, and toggle which MCP servers to enable. Pass any flag to skip its prompt, or `-y` to take the defaults non-interactively (for scripts and CI).
|
|
116
|
+
Map a directory. Run it bare and it walks you through everything: pick the GitHub account from your signed-in `gh` accounts, accept your global git identity or set a per-workspace one, and toggle which MCP servers to enable. Enabling Slack adds a keychain prompt and a Yes/No for posting messages. Pass any flag to skip its prompt, or `-y` to take the defaults non-interactively (for scripts and CI).
|
|
117
|
+
|
|
118
|
+
<p align="center">
|
|
119
|
+
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/add.gif" alt="inscope add: gh picker, git identity, server multiselect, and the Slack prompts" width="900" />
|
|
120
|
+
</p>
|
|
150
121
|
|
|
151
122
|
```
|
|
152
123
|
--gh <account> gh account whose token this workspace uses
|
|
@@ -164,12 +135,52 @@ Run it bare and it walks you through everything: pick the GitHub account from yo
|
|
|
164
135
|
-y, --yes accept defaults, skip all prompts (non-interactive)
|
|
165
136
|
```
|
|
166
137
|
|
|
138
|
+
### `inscope edit`
|
|
139
|
+
|
|
140
|
+
Step through a workspace's prompts pre-filled with its current values (pick it, or pass its path/label), then inscope re-applies on save.
|
|
141
|
+
|
|
142
|
+
<p align="center">
|
|
143
|
+
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/edit.gif" alt="inscope edit: prompts pre-filled with the workspace's current values" width="900" />
|
|
144
|
+
</p>
|
|
145
|
+
|
|
146
|
+
### `inscope rm`
|
|
147
|
+
|
|
148
|
+
Remove a workspace mapping (alias `remove`). Drops its git include and the MCP servers inscope manages; your keychain entries and gh accounts are left untouched. Asks you to type the label to confirm, or pass `-y` to skip the prompt.
|
|
149
|
+
|
|
150
|
+
<p align="center">
|
|
151
|
+
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/rm.gif" alt="inscope rm with a type-the-label confirm" width="900" />
|
|
152
|
+
</p>
|
|
153
|
+
|
|
154
|
+
### `inscope list`
|
|
155
|
+
|
|
156
|
+
List the configured workspaces with their path, gh account, git email, and enabled servers (alias `ls`). Run `inscope doctor` to verify they actually resolve.
|
|
157
|
+
|
|
158
|
+
<p align="center">
|
|
159
|
+
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/list.gif" alt="inscope list showing the configured workspaces" width="900" />
|
|
160
|
+
</p>
|
|
161
|
+
|
|
167
162
|
### `inscope diff`
|
|
168
163
|
|
|
169
|
-
Preview exactly what `apply` would write: a colored diff of the hook, git includes, and each `.mcp.json` against your config. `--adopt` pulls config-expressible on-disk settings (a Slack add-message tool, a custom server URL) back into the config, so the next apply keeps them instead of dropping them.
|
|
164
|
+
Preview exactly what `apply` would write: a colored diff of the hook, git includes, and each `.mcp.json` against your config. `--adopt` pulls config-expressible on-disk settings (a Slack add-message tool, a custom server URL) back into the config, so the next apply keeps them instead of dropping them. `--exit-code` exits non-zero when anything is out of sync, so it works as a CI or pre-commit gate.
|
|
170
165
|
|
|
171
166
|
<p align="center">
|
|
172
|
-
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/
|
|
167
|
+
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/diff.gif" alt="inscope diff: colored drift, then --adopt back-syncs an on-disk setting into the config" width="900" />
|
|
168
|
+
</p>
|
|
169
|
+
|
|
170
|
+
### `inscope apply`
|
|
171
|
+
|
|
172
|
+
Regenerate the hook, git includes, and every `.mcp.json` from the config (alias `sync`). Idempotent and surgical: only the managed blocks are touched, and writes are atomic. Run it any time you edit `inscope.json` by hand.
|
|
173
|
+
|
|
174
|
+
<p align="center">
|
|
175
|
+
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/apply.gif" alt="inscope apply regenerating the hook, git includes, and each .mcp.json" width="900" />
|
|
176
|
+
</p>
|
|
177
|
+
|
|
178
|
+
### `inscope doctor`
|
|
179
|
+
|
|
180
|
+
Verify that tokens, identities, the hook, and each `.mcp.json` resolve correctly. Exits non-zero if anything fails, so it doubles as a health gate.
|
|
181
|
+
|
|
182
|
+
<p align="center">
|
|
183
|
+
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/doctor.gif" alt="inscope doctor verifying tokens, identities, and the hook" width="900" />
|
|
173
184
|
</p>
|
|
174
185
|
|
|
175
186
|
---
|
|
@@ -183,7 +194,7 @@ Preview exactly what `apply` would write: a colored diff of the hook, git includ
|
|
|
183
194
|
| MCP servers | `<workspace>/.mcp.json` |
|
|
184
195
|
| Git identity | `~/.gitconfig` includeIf + `~/.config/inscope/git/<name>.gitconfig` |
|
|
185
196
|
|
|
186
|
-
`inscope` only touches the blocks it owns; your other `.zshrc`, `.gitconfig
|
|
197
|
+
`inscope` only touches the blocks it owns; your other `.zshrc`, `.gitconfig`, and `.mcp.json` content is left alone. Edit `inscope.json` by hand if you like, then run `inscope apply`.
|
|
187
198
|
|
|
188
199
|
---
|
|
189
200
|
|
|
@@ -209,20 +220,16 @@ Each enabled server is written into the workspace `.mcp.json` with a name suffix
|
|
|
209
220
|
| `vercel` | http | OAuth |
|
|
210
221
|
| `webflow` | http | OAuth |
|
|
211
222
|
|
|
212
|
-
Slack is opt-in. Enable it with
|
|
223
|
+
Slack is opt-in. Enable it during `add` (shown above), or with flags, then store the token once:
|
|
213
224
|
|
|
214
225
|
```sh
|
|
215
|
-
inscope add ~/acme --gh neeraj-acme-org --servers github,slack --seed-slack
|
|
226
|
+
npx inscope add ~/acme --gh neeraj-acme-org --servers github,slack --seed-slack
|
|
216
227
|
```
|
|
217
228
|
|
|
218
229
|
`--seed-slack` prompts for the `xoxp` token and writes it to the Keychain. Pass `--slack-message` to allow the Slack MCP server to post messages.
|
|
219
230
|
|
|
220
231
|
You need a Slack app with a user OAuth (`xoxp`) token first. If you don't have one, follow the [slack-mcp-server authentication guide](https://github.com/korotovsky/slack-mcp-server/blob/HEAD/docs/01-authentication-setup.md#option-2-using-slack_mcp_xoxp_token-user-oauth). inscope points you there during `add` when Slack is enabled.
|
|
221
232
|
|
|
222
|
-
<p align="center">
|
|
223
|
-
<img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/demo-slack.gif" alt="inscope adding Slack: keychain prompt and Yes/No selector confirms" width="900" />
|
|
224
|
-
</p>
|
|
225
|
-
|
|
226
233
|
---
|
|
227
234
|
|
|
228
235
|
## ๐ Config File
|
|
@@ -256,9 +263,20 @@ Edit it directly, then run `inscope apply` to regenerate the hook, git includes,
|
|
|
256
263
|
|
|
257
264
|
---
|
|
258
265
|
|
|
266
|
+
## ๐ฆ Install Globally (Optional)
|
|
267
|
+
|
|
268
|
+
Reaching for inscope often? Install it once and drop the `npx`:
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
npm i -g inscope
|
|
272
|
+
inscope <command> [options]
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
259
277
|
## ๐ค Contributing
|
|
260
278
|
|
|
261
|
-
Issues and pull requests are welcome. Run the tests with `bun test` and the type checks with `bun run typecheck` before opening a PR.
|
|
279
|
+
Issues and pull requests are welcome. Run the tests with `bun test` and the type checks with `bun run typecheck` before opening a PR. See [CONTRIBUTING.md](./CONTRIBUTING.md) for the toolchain and architecture.
|
|
262
280
|
|
|
263
281
|
---
|
|
264
282
|
|
package/dist/bin/index.mjs
CHANGED
|
@@ -61,7 +61,7 @@ add-zsh-hook chpwd __inscope_resolve_identity
|
|
|
61
61
|
__inscope_ws="__init__" # force the first resolve, clearing any inherited token
|
|
62
62
|
__inscope_resolve_identity
|
|
63
63
|
`},Je=e=>{let t=o();return e===t?`$HOME`:e.startsWith(t+n.sep)?`$HOME/${e.slice(t.length+1)}`:e},Ye=()=>{let e=Je(p());return`[ -r "${e}" ] && source "${e}"`},Xe=e=>{let t=Ye();if(e.includes(t))return e;let n=e.replace(/\n*$/,``),r=`# inscope: load each workspace's tokens (GitHub, Slack) from \$PWD on every cd\n${t}`;return n.length?`${n}\n\n${r}\n`:`${r}\n`},Ze=()=>{let e=g(),t=v(e),n=Xe(t);n!==t&&y(e,n)},Qe=()=>v(g()).includes(Ye()),Q=e=>{ge(e.workspaces);let t=p();y(t,qe(e)),Ue(e),Ze();let n=[];for(let t of e.workspaces)_e(t),n.push(A(t));return{hook:t,gitconfig:e.workspaces.some(e=>e.git?.email||e.git?.name),mcp:n}},$e=O,et=e=>`SLACK_MCP_XOXP_TOKEN_${e.toUpperCase().replace(/[^A-Z0-9]+/g,`_`)}`,tt=e=>O.filter(t=>!!e[t]),nt=(e,t)=>{let n={};for(let r of O)n[r]=r===`slack`?t?{keychain:t.keychain,addMessageTool:t.addMessageTool}:!1:e.includes(r);return n},rt=e=>e?`global: ${e}`:`no global set`,it=e=>{let t=x()?S():b(),n=t.workspaces.find(t=>t.name===e.name),r=le(t,e);C(r),Q(r),n&&u(n.path)!==u(e.path)&&ve(n)},at=async(e,t)=>{if(!e.servers.slack)return;let n=e.servers.slack.keychain;if(t){let e=await je(`Paste the Slack xoxp token for ${n}: `);e?(we(n,e),console.log(`\nโ stored ${n} in the macOS keychain`)):console.error(`
|
|
64
|
-
No token entered; skipped keychain write.`)}else F(n)||console.log(`\nSlack token not in the keychain yet. Store it once with:\n${R(Te(n))}\n\nSetup guide: ${R(De(`https://github.com/korotovsky/slack-mcp-server/blob/HEAD/docs/01-authentication-setup.md#option-2-using-slack_mcp_xoxp_token-user-oauth`))}`)};var $=`inscope`,ot=`0.8.
|
|
64
|
+
No token entered; skipped keychain write.`)}else F(n)||console.log(`\nSlack token not in the keychain yet. Store it once with:\n${R(Te(n))}\n\nSetup guide: ${R(De(`https://github.com/korotovsky/slack-mcp-server/blob/HEAD/docs/01-authentication-setup.md#option-2-using-slack_mcp_xoxp_token-user-oauth`))}`)};var $=`inscope`,ot=`0.8.6`,st={name:`Neeraj Dalal`,email:`admin@nrjdalal.com`,url:`https://nrjdalal.com`};const ct=`Map a directory to a GitHub account, git email, and MCP servers.
|
|
65
65
|
Runs interactively in a terminal; pass flags or -y to skip the prompts. Re-running
|
|
66
66
|
with the same label updates that workspace; each directory maps to one workspace.
|
|
67
67
|
|