inscope 0.3.1 → 0.3.2

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 CHANGED
@@ -10,7 +10,7 @@
10
10
  > #### `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.
11
11
 
12
12
  <p align="center">
13
- <img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/docs/demo.gif" alt="inscope demo: interactive add, list, and doctor" width="800" />
13
+ <img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/demo.gif" alt="inscope demo: interactive add, list, and doctor" width="800" />
14
14
  </p>
15
15
 
16
16
  Concurrent sessions in different projects should never bleed work and personal accounts into each other. You describe each workspace once; `inscope` owns the moving parts and keeps them in sync:
@@ -73,7 +73,7 @@ inscope rm ~/acme
73
73
  `cd ~/acme/api` and you are the work account, with work MCP servers and your work commit email. `cd ~/nrjdalal/blog` and you are you.
74
74
 
75
75
  <p align="center">
76
- <img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/docs/demo-switch.gif" alt="inscope switching git identity and tokens on cd" width="800" />
76
+ <img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/demo-switch.gif" alt="inscope switching git identity and tokens on cd" width="800" />
77
77
  </p>
78
78
 
79
79
  ---
@@ -145,7 +145,7 @@ inscope doctor Verify tokens, identities, and the hook resolve correctly
145
145
  Run any command with `-h` for its options.
146
146
 
147
147
  <p align="center">
148
- <img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/docs/demo-manage.gif" alt="inscope edit and rm with type-to-confirm" width="800" />
148
+ <img src="https://raw.githubusercontent.com/nrjdalal/inscope/main/.github/assets/demo-manage.gif" alt="inscope edit and rm with type-to-confirm" width="800" />
149
149
  </p>
150
150
 
151
151
  ### `inscope add`
@@ -61,7 +61,7 @@ __inscope_ws="__init__" # force the first resolve, clearing any inherit
61
61
  __inscope_resolve_identity
62
62
  `},we=[`github`,`linear`,`notion`,`slack`],W=e=>we.map(t=>`${t}-${e}`),G=e=>n.join(u(e.path),`.mcp.json`),K=(e,t)=>e&&typeof e==`object`&&e.url?e.url:t,Te=e=>{let t=e.servers,n={};if(t.github&&(n[`github-${e.name}`]={type:`http`,url:`https://api.githubcopilot.com/mcp/`,headers:{Authorization:"Bearer ${GITHUB_TOKEN}"}}),t.linear&&(n[`linear-${e.name}`]={type:`http`,url:K(t.linear,`https://mcp.linear.app/mcp`)}),t.notion&&(n[`notion-${e.name}`]={type:`http`,url:K(t.notion,`https://mcp.notion.com/mcp`)}),t.slack){let r={SLACK_MCP_XOXP_TOKEN:"${SLACK_MCP_XOXP_TOKEN}"};t.slack.addMessageTool&&(r.SLACK_MCP_ADD_MESSAGE_TOOL=`true`),n[`slack-${e.name}`]={type:`stdio`,command:`npx`,args:[`-y`,`slack-mcp-server@1.3.0`,`--transport`,`stdio`],env:r}}return n},Ee=e=>{if(!t.existsSync(e))return{};try{return JSON.parse(t.readFileSync(e,`utf8`))}catch{return{}}},q=e=>{if(!t.existsSync(e))return{};try{return JSON.parse(t.readFileSync(e,`utf8`))}catch{throw Error(`${e} is not valid JSON; fix or remove it, then re-run inscope (left it untouched)`)}},De=e=>{let n=G(e);return t.existsSync(n)?Ee(n):null},Oe=e=>{let r=G(e);t.mkdirSync(n.dirname(r),{recursive:!0});let i=q(r),a=i.mcpServers&&typeof i.mcpServers==`object`?{...i.mcpServers}:{};for(let t of W(e.name))delete a[t];Object.assign(a,Te(e)),i.mcpServers=a,t.writeFileSync(r,JSON.stringify(i,null,2)+`
63
63
  `)},ke=e=>{let n=G(e);if(!t.existsSync(n))return;let r=q(n);if(r.mcpServers&&typeof r.mcpServers==`object`)for(let t of W(e.name))delete r.mcpServers[t];t.writeFileSync(n,JSON.stringify(r,null,2)+`
64
- `)},Ae=e=>{let t=o();return e===t?`$HOME`:e.startsWith(t+n.sep)?`$HOME/${e.slice(t.length+1)}`:e},J=()=>{let e=Ae(p());return`[ -r "${e}" ] && source "${e}"`},je=e=>{let t=J();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`},Me=()=>{let e=g(),n=``;try{n=t.readFileSync(e,`utf8`)}catch{}let r=je(n);r!==n&&t.writeFileSync(e,r)},Ne=()=>{try{return t.readFileSync(g(),`utf8`).includes(J())}catch{return!1}},Y=e=>{let r=p();t.mkdirSync(n.dirname(r),{recursive:!0}),t.writeFileSync(r,U(e)),be(e),Me();let i=[];for(let t of e.workspaces)Oe(t),i.push(G(t));return{hook:r,gitconfig:e.workspaces.some(e=>e.git?.email||e.git?.name),mcp:i}},X=`https://github.com/korotovsky/slack-mcp-server/blob/HEAD/docs/01-authentication-setup.md#option-2-using-slack_mcp_xoxp_token-user-oauth`,Pe=[`github`,`linear`,`notion`,`slack`],Fe=e=>`SLACK_MCP_XOXP_TOKEN_${e.toUpperCase().replace(/[^A-Z0-9]+/g,`_`)}`,Ie=e=>[e.github&&`github`,e.linear&&`linear`,e.notion&&`notion`,e.slack&&`slack`].filter(Boolean),Le=(e,t)=>({github:e.includes(`github`),linear:e.includes(`linear`),notion:e.includes(`notion`),slack:t?{keychain:t.keychain,addMessageTool:t.addMessageTool}:!1}),Re=e=>{let t=w(v()?y():_(),e);b(t),Y(t)},ze=async(e,t)=>{if(!e.servers.slack)return;let n=e.servers.slack.keychain;if(t){let e=await ce(`Paste the Slack xoxp token for ${n}: `);e?(ae(n,e),console.log(`✓ stored ${n} in the macOS keychain`)):console.error(`No token entered; skipped keychain write.`)}else O(n)||console.log(`\nSlack token not in the keychain yet. Create a Slack app (xoxp user OAuth):\n ${X}\nthen store the token once with:\n ${oe(n)}`)};var Z=`inscope`,Be=`0.3.1`,Q={name:`Neeraj Dalal`,email:`admin@nrjdalal.com`,url:`https://nrjdalal.com`};const $=`Map a directory to a GitHub account, git email, and MCP servers.
64
+ `)},Ae=e=>{let t=o();return e===t?`$HOME`:e.startsWith(t+n.sep)?`$HOME/${e.slice(t.length+1)}`:e},J=()=>{let e=Ae(p());return`[ -r "${e}" ] && source "${e}"`},je=e=>{let t=J();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`},Me=()=>{let e=g(),n=``;try{n=t.readFileSync(e,`utf8`)}catch{}let r=je(n);r!==n&&t.writeFileSync(e,r)},Ne=()=>{try{return t.readFileSync(g(),`utf8`).includes(J())}catch{return!1}},Y=e=>{let r=p();t.mkdirSync(n.dirname(r),{recursive:!0}),t.writeFileSync(r,U(e)),be(e),Me();let i=[];for(let t of e.workspaces)Oe(t),i.push(G(t));return{hook:r,gitconfig:e.workspaces.some(e=>e.git?.email||e.git?.name),mcp:i}},X=`https://github.com/korotovsky/slack-mcp-server/blob/HEAD/docs/01-authentication-setup.md#option-2-using-slack_mcp_xoxp_token-user-oauth`,Pe=[`github`,`linear`,`notion`,`slack`],Fe=e=>`SLACK_MCP_XOXP_TOKEN_${e.toUpperCase().replace(/[^A-Z0-9]+/g,`_`)}`,Ie=e=>[e.github&&`github`,e.linear&&`linear`,e.notion&&`notion`,e.slack&&`slack`].filter(Boolean),Le=(e,t)=>({github:e.includes(`github`),linear:e.includes(`linear`),notion:e.includes(`notion`),slack:t?{keychain:t.keychain,addMessageTool:t.addMessageTool}:!1}),Re=e=>{let t=w(v()?y():_(),e);b(t),Y(t)},ze=async(e,t)=>{if(!e.servers.slack)return;let n=e.servers.slack.keychain;if(t){let e=await ce(`Paste the Slack xoxp token for ${n}: `);e?(ae(n,e),console.log(`✓ stored ${n} in the macOS keychain`)):console.error(`No token entered; skipped keychain write.`)}else O(n)||console.log(`\nSlack token not in the keychain yet. Create a Slack app (xoxp user OAuth):\n ${X}\nthen store the token once with:\n ${oe(n)}`)};var Z=`inscope`,Be=`0.3.2`,Q={name:`Neeraj Dalal`,email:`admin@nrjdalal.com`,url:`https://nrjdalal.com`};const $=`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 path or label updates that workspace.
67
67
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inscope",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Per-workspace identity for Claude Code: scope MCP servers, GitHub auth, and git commit identity to the directory you are in.",
5
5
  "keywords": [
6
6
  "claude-code",