pro-app 0.1.0 → 0.1.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 +3 -2
- package/bin/proapp.js +54 -37
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
Connect Claude Code or Codex to your PROApp workspace.
|
|
4
4
|
|
|
5
5
|
```
|
|
6
|
-
npx pro-app
|
|
6
|
+
npx pro-app claude
|
|
7
|
+
npx pro-app codex
|
|
7
8
|
```
|
|
8
9
|
|
|
9
|
-
Adds PROApp to
|
|
10
|
+
Adds PROApp to that assistant and opens PROApp sign-in in your browser. Sign in, click **Allow access**, done. `npx pro-app` alone connects whichever one is installed (and asks if both are).
|
|
10
11
|
|
|
11
12
|
- `npx pro-app login` — sign in again
|
|
12
13
|
- `npx pro-app logout` — sign out
|
package/bin/proapp.js
CHANGED
|
@@ -2,63 +2,80 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
// PROApp connector for local AI coding assistants. No credentials live here:
|
|
4
4
|
// sign-in happens in your browser on PROApp's own page, and each assistant
|
|
5
|
-
// stores its own token. Usage: npx pro-app [
|
|
5
|
+
// stores its own token. Usage: npx pro-app [claude|codex] | login|logout|status [claude|codex]
|
|
6
6
|
const { spawnSync } = require('node:child_process');
|
|
7
|
+
const readline = require('node:readline');
|
|
7
8
|
|
|
8
|
-
const
|
|
9
|
+
const SERVER = 'https://www.proapphub.com/api/mcp';
|
|
9
10
|
const NAME = 'proapp';
|
|
10
11
|
const APPS = [
|
|
11
|
-
{ label: 'Claude Code', bin: 'claude',
|
|
12
|
-
add: ['mcp', 'add', '--transport', 'http', '--scope', 'user', '--client-id', 'proapp-claude-code', '--callback-port', '8766', NAME,
|
|
12
|
+
{ key: 'claude', label: 'Claude Code', bin: 'claude',
|
|
13
|
+
add: ['mcp', 'add', '--transport', 'http', '--scope', 'user', '--client-id', 'proapp-claude-code', '--callback-port', '8766', NAME, SERVER],
|
|
13
14
|
remove: ['mcp', 'remove', NAME, '--scope', 'user'] },
|
|
14
|
-
{ label: 'Codex', bin: 'codex',
|
|
15
|
-
add: ['mcp', 'add', NAME, '--url',
|
|
15
|
+
{ key: 'codex', label: 'Codex', bin: 'codex',
|
|
16
|
+
add: ['mcp', 'add', NAME, '--url', SERVER, '--oauth-client-id', 'proapp-codex'],
|
|
16
17
|
remove: ['mcp', 'remove', NAME] },
|
|
17
18
|
];
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
// On Windows, npm installs CLIs as .cmd/.ps1 shims that can only be started through a
|
|
21
|
+
// shell. Every argument here is a fixed string (no user input), so this is safe.
|
|
22
|
+
const SHELL = process.platform === 'win32';
|
|
23
|
+
const run = (bin, args, quiet = false) => spawnSync(bin, args, { stdio: quiet ? 'ignore' : 'inherit', shell: SHELL });
|
|
20
24
|
const installed = (bin) => {
|
|
21
|
-
const probe = spawnSync(bin, ['--version'], { stdio: 'ignore', shell:
|
|
25
|
+
const probe = spawnSync(bin, ['--version'], { stdio: 'ignore', shell: SHELL });
|
|
22
26
|
return !probe.error && probe.status === 0;
|
|
23
27
|
};
|
|
28
|
+
const fail = (message) => { console.error(message); process.exit(1); };
|
|
24
29
|
|
|
25
|
-
function
|
|
30
|
+
function ask(question) {
|
|
31
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
32
|
+
return new Promise(resolve => rl.question(question, answer => { rl.close(); resolve(answer.trim().toLowerCase()); }));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** One assistant: the one named, the only one installed, or the one the user picks. */
|
|
36
|
+
async function choose(which) {
|
|
26
37
|
const apps = APPS.filter(app => installed(app.bin));
|
|
27
|
-
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
console.error(`"${which}" is not installed. Found: ${apps.map(a => a.bin).join(', ')}`);
|
|
34
|
-
process.exit(1);
|
|
38
|
+
if (!apps.length) fail('Neither Claude Code nor Codex was found. Install one, then run: npx pro-app');
|
|
39
|
+
if (which) {
|
|
40
|
+
const app = APPS.find(a => a.key === which);
|
|
41
|
+
if (!app) fail(`Unknown assistant "${which}". Use: npx pro-app claude or npx pro-app codex`);
|
|
42
|
+
if (!apps.includes(app)) fail(`${app.label} is not installed on this computer.`);
|
|
43
|
+
return app;
|
|
35
44
|
}
|
|
36
|
-
return
|
|
45
|
+
if (apps.length === 1) return apps[0];
|
|
46
|
+
if (!process.stdin.isTTY) fail('Both Claude Code and Codex are installed. Run: npx pro-app claude or npx pro-app codex');
|
|
47
|
+
const answer = await ask('Connect PROApp to which assistant? [1] Claude Code [2] Codex: ');
|
|
48
|
+
const app = answer === '1' || answer.startsWith('cl') ? apps.find(a => a.key === 'claude')
|
|
49
|
+
: answer === '2' || answer.startsWith('co') ? apps.find(a => a.key === 'codex') : undefined;
|
|
50
|
+
if (!app) fail('No assistant chosen. Run: npx pro-app claude or npx pro-app codex');
|
|
51
|
+
return app;
|
|
37
52
|
}
|
|
38
53
|
|
|
39
|
-
function connect(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
else console.log(`${app.label} is connected to PROApp.`);
|
|
46
|
-
}
|
|
54
|
+
function connect(app) {
|
|
55
|
+
run(app.bin, app.remove, true);
|
|
56
|
+
if (run(app.bin, app.add, true).status !== 0) fail(`Could not add PROApp to ${app.label}.`);
|
|
57
|
+
console.log(`\nPROApp added to ${app.label}. Opening sign-in in your browser...`);
|
|
58
|
+
if (run(app.bin, ['mcp', 'login', NAME]).status !== 0) console.log(`Finish later with: npx pro-app login ${app.key}`);
|
|
59
|
+
else console.log(`${app.label} is connected to PROApp.`);
|
|
47
60
|
}
|
|
48
61
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
async function main() {
|
|
63
|
+
const [command, which] = process.argv.slice(2);
|
|
64
|
+
const assistants = APPS.map(a => a.key);
|
|
65
|
+
if (!command || assistants.includes(command)) return connect(await choose(command));
|
|
66
|
+
if (command === 'login') { const app = await choose(which); return void run(app.bin, ['mcp', 'login', NAME]); }
|
|
67
|
+
if (command === 'logout') { const app = await choose(which); return void run(app.bin, ['mcp', 'logout', NAME]); }
|
|
68
|
+
if (command === 'status') { const app = await choose(which); console.log(`\n${app.label}:`); return void run(app.bin, ['mcp', 'get', NAME]); }
|
|
69
|
+
console.log(`PROApp for Claude Code and Codex
|
|
57
70
|
|
|
58
|
-
npx pro-app
|
|
59
|
-
npx pro-app
|
|
71
|
+
npx pro-app claude connect Claude Code (adds PROApp and opens sign-in)
|
|
72
|
+
npx pro-app codex connect Codex
|
|
73
|
+
npx pro-app connect whichever is installed (asks if both are)
|
|
74
|
+
npx pro-app login sign in again (add claude/codex if both installed)
|
|
60
75
|
npx pro-app logout sign out
|
|
61
76
|
npx pro-app status show the connection
|
|
62
77
|
|
|
63
|
-
|
|
78
|
+
Your company needs the PROApp AI Assistant add-on.`);
|
|
64
79
|
}
|
|
80
|
+
|
|
81
|
+
main();
|