unbound-cli 0.1.4 → 0.1.5

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/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "unbound-cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "CLI tool for Unbound - AI Gateway management",
5
5
  "main": "src/index.js",
6
6
  "bin": {
7
- "unbound": "src/index.js"
7
+ "unbound": "src/index.js",
8
+ "unbound-cli": "src/index.js"
8
9
  },
9
10
  "scripts": {
10
11
  "start": "node src/index.js",
@@ -9,9 +9,10 @@ const SETUP_BASE_URL = 'https://raw.githubusercontent.com/websentry-ai/setup/ref
9
9
  /**
10
10
  * Runs a Python setup script from the setup repo, passing the stored API key.
11
11
  */
12
- function runSetupScript(scriptPath, apiKey) {
12
+ function runSetupScript(scriptPath, apiKey, { clear = false } = {}) {
13
13
  const url = `${SETUP_BASE_URL}/${scriptPath}`;
14
- const cmd = `curl -fsSL "${url}" | python3 - --api-key "${apiKey}"`;
14
+ const extraArgs = clear ? ' --clear' : '';
15
+ const cmd = `curl -fsSL "${url}" | python3 - --api-key "${apiKey}"${extraArgs}`;
15
16
 
16
17
  console.log('');
17
18
  execSync(cmd, { stdio: 'inherit' });
@@ -21,13 +22,13 @@ function runSetupScript(scriptPath, apiKey) {
21
22
  * Ensures login, gets the stored API key, and runs the setup script(s).
22
23
  */
23
24
  function makeAction(...scriptPaths) {
24
- return async () => {
25
+ return async (opts) => {
25
26
  try {
26
27
  await ensureLoggedIn();
27
28
  const apiKey = config.getApiKey();
28
29
 
29
30
  for (const scriptPath of scriptPaths) {
30
- runSetupScript(scriptPath, apiKey);
31
+ runSetupScript(scriptPath, apiKey, { clear: opts.clear });
31
32
  }
32
33
  } catch (err) {
33
34
  output.error(err.message);
@@ -66,6 +67,7 @@ open automatically to authenticate before proceeding.
66
67
  'Set up Cursor to use Unbound. Downloads hook scripts, sets the ' +
67
68
  'UNBOUND_CURSOR_API_KEY environment variable, and restarts Cursor.'
68
69
  )
70
+ .option('--clear', 'Remove Unbound configuration for Cursor')
69
71
  .addHelpText('after', `
70
72
  What this does:
71
73
  1. Downloads Cursor hook scripts from the Unbound setup repository
@@ -79,6 +81,7 @@ Prerequisites:
79
81
 
80
82
  Examples:
81
83
  $ unbound setup cursor
84
+ $ unbound setup cursor --clear # Remove Unbound configuration
82
85
  `)
83
86
  .action(makeAction('cursor/setup.py'));
84
87
 
@@ -90,6 +93,7 @@ Examples:
90
93
  )
91
94
  .option('--subscription', 'Use your existing Claude subscription (hooks only)')
92
95
  .option('--gateway', 'Use Unbound as the AI provider (gateway mode)')
96
+ .option('--clear', 'Remove Unbound configuration for Claude Code')
93
97
  .addHelpText('after', `
94
98
  Modes:
95
99
  Subscription (hooks only):
@@ -114,14 +118,16 @@ Examples:
114
118
  $ unbound setup claude-code # Interactive mode selection
115
119
  $ unbound setup claude-code --subscription # Hooks only (keep your subscription)
116
120
  $ unbound setup claude-code --gateway # Use Unbound as AI provider
121
+ $ unbound setup claude-code --clear # Remove Unbound configuration
117
122
  `)
118
123
  .action(async (opts) => {
119
124
  try {
120
125
  await ensureLoggedIn();
121
126
  const apiKey = config.getApiKey();
127
+ const scriptOpts = { clear: opts.clear };
122
128
 
123
129
  let useSubscription = opts.subscription;
124
- if (!opts.subscription && !opts.gateway) {
130
+ if (!opts.clear && !opts.subscription && !opts.gateway) {
125
131
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
126
132
  const answer = await new Promise((resolve) => {
127
133
  console.log('\nHow do you want to use Claude Code with Unbound?\n');
@@ -133,10 +139,13 @@ Examples:
133
139
  useSubscription = answer.trim() === '1';
134
140
  }
135
141
 
136
- if (useSubscription) {
137
- runSetupScript('claude-code/hooks/setup.py', apiKey);
142
+ if (opts.clear) {
143
+ runSetupScript('claude-code/hooks/setup.py', apiKey, scriptOpts);
144
+ runSetupScript('claude-code/gateway/setup.py', apiKey, scriptOpts);
145
+ } else if (useSubscription) {
146
+ runSetupScript('claude-code/hooks/setup.py', apiKey, scriptOpts);
138
147
  } else {
139
- runSetupScript('claude-code/gateway/setup.py', apiKey);
148
+ runSetupScript('claude-code/gateway/setup.py', apiKey, scriptOpts);
140
149
  }
141
150
  } catch (err) {
142
151
  output.error(err.message);
@@ -150,6 +159,7 @@ Examples:
150
159
  'Set up Gemini CLI to use Unbound. Sets GEMINI_API_KEY and ' +
151
160
  'GOOGLE_GEMINI_BASE_URL environment variables.'
152
161
  )
162
+ .option('--clear', 'Remove Unbound configuration for Gemini CLI')
153
163
  .addHelpText('after', `
154
164
  What this does:
155
165
  1. Sets GEMINI_API_KEY to your Unbound API key in your shell profile
@@ -163,6 +173,7 @@ Prerequisites:
163
173
 
164
174
  Examples:
165
175
  $ unbound setup gemini-cli
176
+ $ unbound setup gemini-cli --clear # Remove Unbound configuration
166
177
  `)
167
178
  .action(makeAction('gemini-cli/gateway/setup.py'));
168
179
 
@@ -172,6 +183,7 @@ Examples:
172
183
  'Set up Codex to use Unbound. Sets OPENAI_API_KEY and ' +
173
184
  'OPENAI_BASE_URL environment variables.'
174
185
  )
186
+ .option('--clear', 'Remove Unbound configuration for Codex')
175
187
  .addHelpText('after', `
176
188
  What this does:
177
189
  1. Sets OPENAI_API_KEY to your Unbound API key in your shell profile
@@ -185,6 +197,7 @@ Prerequisites:
185
197
 
186
198
  Examples:
187
199
  $ unbound setup codex
200
+ $ unbound setup codex --clear # Remove Unbound configuration
188
201
  `)
189
202
  .action(makeAction('codex/gateway/setup.py'));
190
203
 
package/src/index.js CHANGED
@@ -3,13 +3,14 @@
3
3
  const { Command } = require('commander');
4
4
  const config = require('./config');
5
5
  const output = require('./output');
6
+ const { version } = require('../package.json');
6
7
 
7
8
  const program = new Command();
8
9
 
9
10
  program
10
11
  .name('unbound')
11
12
  .description('Unbound CLI - Manage your AI Gateway from the command line.\n\nUnbound is an AI gateway that provides centralized policy management,\ncost controls, and security guardrails for AI coding tools like\nClaude Code, Cursor, Gemini CLI, and more.')
12
- .version('0.1.0')
13
+ .version(version)
13
14
  .addHelpText('after', `
14
15
  Examples:
15
16
  $ unbound login Sign in via browser