agentic-factory-bridge 1.0.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.
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # agentic-factory-bridge
2
+
3
+ Local bridge that connects the [Atos Agentic Factory](https://atos-agentic-factory.onrender.com) marketplace to [OpenCode CLI](https://opencode.ai) on your machine.
4
+
5
+ ## What it does
6
+
7
+ - Detects whether OpenCode CLI is installed on your machine
8
+ - Registers the `opencode://` custom protocol so the marketplace can launch OpenCode directly from the browser
9
+ - Runs a lightweight local server (port 3001) that the marketplace web UI communicates with
10
+
11
+ ## Requirements
12
+
13
+ - **Node.js 18+**
14
+ - **Windows** (protocol registration uses PowerShell and Windows Registry)
15
+ - **OpenCode CLI** installed globally: `npm install -g opencode`
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install -g agentic-factory-bridge
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ### 1. Initial setup (once)
26
+
27
+ Register the `opencode://` protocol and verify OpenCode CLI is installed:
28
+
29
+ ```bash
30
+ agentic-factory-bridge setup
31
+ ```
32
+
33
+ ### 2. Start the bridge
34
+
35
+ ```bash
36
+ agentic-factory-bridge start
37
+ ```
38
+
39
+ The bridge starts on `http://localhost:3001`. Keep this terminal open while using the marketplace.
40
+
41
+ ### 3. Use the marketplace
42
+
43
+ Go to [Atos Agentic Factory](https://atos-agentic-factory.onrender.com), navigate to any agent profile, and click **"Open with OpenCode"**.
44
+
45
+ ## Commands
46
+
47
+ | Command | Description |
48
+ | ---------------------------------- | -------------------------------------------------------- |
49
+ | `agentic-factory-bridge start` | Start the local bridge server |
50
+ | `agentic-factory-bridge setup` | Register the opencode:// protocol + install OpenCode CLI |
51
+ | `agentic-factory-bridge uninstall` | Remove the opencode:// protocol from Windows Registry |
52
+ | `agentic-factory-bridge status` | Check bridge, OpenCode CLI, and protocol status |
53
+ | `agentic-factory-bridge --version` | Show version |
54
+ | `agentic-factory-bridge --help` | Show help |
55
+
56
+ ## How it works
57
+
58
+ ```
59
+ Browser (marketplace) --> localhost:3001 (bridge) --> OpenCode CLI
60
+ --> Windows Registry (protocol)
61
+ ```
62
+
63
+ 1. The marketplace web UI calls `http://localhost:3001` to detect if the bridge is running
64
+ 2. The bridge checks if OpenCode CLI is installed and reports status back
65
+ 3. When you click "Open with OpenCode", the browser navigates to `opencode://run?agent=...`
66
+ 4. Windows routes the `opencode://` protocol to the handler, which launches OpenCode CLI
67
+
68
+ ## Uninstall
69
+
70
+ ```bash
71
+ agentic-factory-bridge uninstall # Remove protocol registration
72
+ npm uninstall -g agentic-factory-bridge
73
+ ```
74
+
75
+ ## License
76
+
77
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,275 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Agentic Factory Bridge — CLI entry point.
5
+ *
6
+ * Usage:
7
+ * agentic-factory-bridge start Start the bridge server (port 3001)
8
+ * agentic-factory-bridge setup Install OpenCode CLI + register opencode:// protocol
9
+ * agentic-factory-bridge uninstall Remove the opencode:// protocol registration
10
+ * agentic-factory-bridge status Check bridge health and OpenCode CLI status
11
+ * agentic-factory-bridge --help Show help
12
+ * agentic-factory-bridge --version Show version
13
+ */
14
+
15
+ const { spawn } = require('child_process');
16
+ const path = require('path');
17
+ const fs = require('fs');
18
+ const http = require('http');
19
+
20
+ const PACKAGE_DIR = path.join(__dirname, '..');
21
+ const VERSION = require(path.join(PACKAGE_DIR, 'package.json')).version;
22
+
23
+ const command = process.argv[2];
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Help
27
+ // ---------------------------------------------------------------------------
28
+ function showHelp() {
29
+ console.log('');
30
+ console.log(' Agentic Factory Bridge v' + VERSION);
31
+ console.log(' Local bridge for Atos Agentic Factory marketplace');
32
+ console.log('');
33
+ console.log(' Usage:');
34
+ console.log(' agentic-factory-bridge <command>');
35
+ console.log('');
36
+ console.log(' Commands:');
37
+ console.log(' start Start the bridge server on port 3001');
38
+ console.log(' setup Install OpenCode CLI + register opencode:// protocol (Windows)');
39
+ console.log(' uninstall Remove the opencode:// protocol registration (Windows)');
40
+ console.log(' status Check if the bridge is running and OpenCode is installed');
41
+ console.log('');
42
+ console.log(' Options:');
43
+ console.log(' --help Show this help message');
44
+ console.log(' --version Show version number');
45
+ console.log('');
46
+ console.log(' Environment variables:');
47
+ console.log(' BRIDGE_PORT Port to listen on (default: 3001)');
48
+ console.log(' BRIDGE_SECRET Shared secret for HMAC auth (default: auto-generated)');
49
+ console.log(' BRIDGE_CORS_ORIGIN Allowed CORS origins, comma-separated');
50
+ console.log(' MARKETPLACE_API_URL Backend API URL (default: http://localhost:3000/api)');
51
+ console.log(' OPENCODE_PATH Path to opencode binary (default: "opencode")');
52
+ console.log('');
53
+ console.log(' Quick start:');
54
+ console.log(' npm install -g agentic-factory-bridge');
55
+ console.log(' agentic-factory-bridge setup');
56
+ console.log(' agentic-factory-bridge start');
57
+ console.log('');
58
+ }
59
+
60
+ // ---------------------------------------------------------------------------
61
+ // Start bridge server
62
+ // ---------------------------------------------------------------------------
63
+ function startBridge() {
64
+ const bridgePath = path.join(PACKAGE_DIR, 'bridge.js');
65
+ if (!fs.existsSync(bridgePath)) {
66
+ console.error(' ERROR: bridge.js not found at ' + bridgePath);
67
+ process.exit(1);
68
+ }
69
+ require(bridgePath);
70
+ }
71
+
72
+ // ---------------------------------------------------------------------------
73
+ // Setup: install OpenCode CLI + register protocol
74
+ // ---------------------------------------------------------------------------
75
+ async function setup() {
76
+ console.log('');
77
+ console.log(' ============================================');
78
+ console.log(' Agentic Factory Bridge — Setup');
79
+ console.log(' ============================================');
80
+ console.log('');
81
+
82
+ // Step 1: Check if OpenCode CLI is installed
83
+ console.log(' [1/3] Checking OpenCode CLI...');
84
+ const hasOpencode = await checkCommand('opencode');
85
+
86
+ if (hasOpencode) {
87
+ console.log(' [OK] OpenCode CLI is already installed.');
88
+ } else {
89
+ console.log(' [..] Installing OpenCode CLI (npm install -g opencode)...');
90
+ try {
91
+ await runCommand('npm', ['install', '-g', 'opencode'], 120000);
92
+ console.log(' [OK] OpenCode CLI installed successfully.');
93
+ } catch (err) {
94
+ console.error(' [FAIL] Could not install OpenCode CLI: ' + err.message);
95
+ console.error(' Try running manually: npm install -g opencode');
96
+ }
97
+ }
98
+
99
+ // Step 2: Register protocol (Windows only)
100
+ console.log('');
101
+ console.log(' [2/3] Registering opencode:// protocol...');
102
+
103
+ if (process.platform !== 'win32') {
104
+ console.log(' [SKIP] Protocol registration is only supported on Windows.');
105
+ } else {
106
+ const scriptPath = path.join(PACKAGE_DIR, 'install-protocol.ps1');
107
+ if (!fs.existsSync(scriptPath)) {
108
+ console.error(' [FAIL] install-protocol.ps1 not found at ' + scriptPath);
109
+ } else {
110
+ try {
111
+ await runCommand(
112
+ 'powershell',
113
+ ['-ExecutionPolicy', 'Bypass', '-NonInteractive', '-File', scriptPath],
114
+ 30000,
115
+ );
116
+ console.log(' [OK] Protocol opencode:// registered.');
117
+ } catch (err) {
118
+ console.error(' [FAIL] Protocol registration failed: ' + err.message);
119
+ }
120
+ }
121
+ }
122
+
123
+ // Step 3: Summary
124
+ console.log('');
125
+ console.log(' [3/3] Setup complete!');
126
+ console.log('');
127
+ console.log(' Next steps:');
128
+ console.log(' 1. Run: agentic-factory-bridge start');
129
+ console.log(' 2. Open https://atos-agentic-factory.onrender.com');
130
+ console.log(' 3. Click "Refresh detection" on the OpenCode page');
131
+ console.log('');
132
+ }
133
+
134
+ // ---------------------------------------------------------------------------
135
+ // Uninstall protocol
136
+ // ---------------------------------------------------------------------------
137
+ async function uninstall() {
138
+ if (process.platform !== 'win32') {
139
+ console.log(' Protocol uninstall is only supported on Windows.');
140
+ return;
141
+ }
142
+
143
+ const scriptPath = path.join(PACKAGE_DIR, 'uninstall-protocol.ps1');
144
+ if (!fs.existsSync(scriptPath)) {
145
+ console.error(' uninstall-protocol.ps1 not found at ' + scriptPath);
146
+ process.exit(1);
147
+ }
148
+
149
+ try {
150
+ await runCommand(
151
+ 'powershell',
152
+ ['-ExecutionPolicy', 'Bypass', '-NonInteractive', '-File', scriptPath],
153
+ 30000,
154
+ );
155
+ } catch (err) {
156
+ console.error(' Uninstall failed: ' + err.message);
157
+ }
158
+ }
159
+
160
+ // ---------------------------------------------------------------------------
161
+ // Status check
162
+ // ---------------------------------------------------------------------------
163
+ async function status() {
164
+ console.log('');
165
+ console.log(' Agentic Factory Bridge — Status');
166
+ console.log(' --------------------------------');
167
+
168
+ // Check bridge
169
+ const port = process.env.BRIDGE_PORT || '3001';
170
+ try {
171
+ const health = await httpGet('http://127.0.0.1:' + port + '/health');
172
+ const data = JSON.parse(health);
173
+ console.log(' Bridge: RUNNING (v' + data.version + ', uptime ' + data.uptime + 's)');
174
+ } catch {
175
+ console.log(' Bridge: NOT RUNNING (port ' + port + ')');
176
+ }
177
+
178
+ // Check opencode CLI
179
+ const hasOpencode = await checkCommand('opencode');
180
+ if (hasOpencode) {
181
+ console.log(' OpenCode: INSTALLED');
182
+ } else {
183
+ console.log(' OpenCode: NOT FOUND — run: npm install -g opencode');
184
+ }
185
+
186
+ // Check protocol (Windows)
187
+ if (process.platform === 'win32') {
188
+ try {
189
+ await runCommand('reg', ['query', 'HKCU\\Software\\Classes\\opencode', '/ve'], 5000);
190
+ console.log(' Protocol: REGISTERED (opencode://)');
191
+ } catch {
192
+ console.log(' Protocol: NOT REGISTERED — run: agentic-factory-bridge setup');
193
+ }
194
+ }
195
+
196
+ console.log('');
197
+ }
198
+
199
+ // ---------------------------------------------------------------------------
200
+ // Helpers
201
+ // ---------------------------------------------------------------------------
202
+ function checkCommand(cmd) {
203
+ return new Promise((resolve) => {
204
+ const check = process.platform === 'win32' ? 'where' : 'which';
205
+ const proc = spawn(check, [cmd], { stdio: ['pipe', 'pipe', 'pipe'], shell: false });
206
+ proc.on('close', (code) => resolve(code === 0));
207
+ proc.on('error', () => resolve(false));
208
+ });
209
+ }
210
+
211
+ function runCommand(cmd, args, timeout) {
212
+ return new Promise((resolve, reject) => {
213
+ const proc = spawn(cmd, args, {
214
+ stdio: ['pipe', 'pipe', 'pipe'],
215
+ timeout,
216
+ shell: false,
217
+ });
218
+ let stdout = '';
219
+ let stderr = '';
220
+ proc.stdout.on('data', (d) => {
221
+ stdout += d.toString();
222
+ });
223
+ proc.stderr.on('data', (d) => {
224
+ stderr += d.toString();
225
+ });
226
+ proc.on('close', (code) => {
227
+ if (code === 0) resolve(stdout);
228
+ else reject(new Error(stderr || stdout || 'exit code ' + code));
229
+ });
230
+ proc.on('error', (err) => reject(err));
231
+ });
232
+ }
233
+
234
+ function httpGet(url) {
235
+ return new Promise((resolve, reject) => {
236
+ http
237
+ .get(url, { timeout: 3000 }, (res) => {
238
+ let data = '';
239
+ res.on('data', (c) => (data += c));
240
+ res.on('end', () => resolve(data));
241
+ })
242
+ .on('error', reject);
243
+ });
244
+ }
245
+
246
+ // ---------------------------------------------------------------------------
247
+ // Main
248
+ // ---------------------------------------------------------------------------
249
+ switch (command) {
250
+ case 'start':
251
+ startBridge();
252
+ break;
253
+ case 'setup':
254
+ setup();
255
+ break;
256
+ case 'uninstall':
257
+ uninstall();
258
+ break;
259
+ case 'status':
260
+ status();
261
+ break;
262
+ case '--version':
263
+ case '-v':
264
+ console.log(VERSION);
265
+ break;
266
+ case '--help':
267
+ case '-h':
268
+ case undefined:
269
+ showHelp();
270
+ break;
271
+ default:
272
+ console.error(' Unknown command: ' + command);
273
+ console.error(' Run "agentic-factory-bridge --help" for usage.');
274
+ process.exit(1);
275
+ }