infinicode 2.8.0 → 2.8.1

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.
@@ -48,7 +48,7 @@ function unreachable(url, err) {
48
48
  return [
49
49
  chalk.red(` ✗ no mesh node reachable at ${url}`),
50
50
  chalk.dim(` ${msg}`),
51
- chalk.dim(' start one with infinicode serve --dashboard or robopark setup --start'),
51
+ chalk.dim(' start one with infinicode serve --peer --token <token> or robopark setup --control --start'),
52
52
  ].join('\n');
53
53
  }
54
54
  // ── loadbar / formatting helpers ───────────────────────────────────────────────
@@ -8,6 +8,12 @@ export interface ServeOptions {
8
8
  open?: boolean;
9
9
  foreground?: boolean;
10
10
  }
11
+ /** Resolve the actual infinicode CLI entry point so `robopark setup --start`
12
+ * works even when global bins are not on PATH. */
13
+ export declare function resolveInfinicodeBin(): Promise<{
14
+ node: string;
15
+ script: string;
16
+ } | null>;
11
17
  export declare function roboparkServe(opts: ServeOptions): Promise<void>;
12
18
  /** Quick health check: is the scheduler responding? */
13
19
  export declare function schedulerHealthy(url: string, timeoutMs?: number): Promise<boolean>;
@@ -46,6 +46,28 @@ function findPython() {
46
46
  }
47
47
  return 'python3';
48
48
  }
49
+ /** Resolve the actual infinicode CLI entry point so `robopark setup --start`
50
+ * works even when global bins are not on PATH. */
51
+ export async function resolveInfinicodeBin() {
52
+ try {
53
+ // When running from the infinicode package itself, the CLI entry is nearby.
54
+ const local = join(pkgDir(), 'bin', 'infinicode.js');
55
+ if (existsSync(local))
56
+ return { node: process.execPath, script: local };
57
+ }
58
+ catch { /* ignore */ }
59
+ try {
60
+ // When running from the robopark wrapper, resolve infinicode from npm.
61
+ const { createRequire } = await import('node:module');
62
+ const require = createRequire(import.meta.url);
63
+ const pkgMain = require.resolve('infinicode/package.json');
64
+ const candidate = join(dirname(pkgMain), 'bin', 'infinicode.js');
65
+ if (existsSync(candidate))
66
+ return { node: process.execPath, script: candidate };
67
+ }
68
+ catch { /* ignore */ }
69
+ return null;
70
+ }
49
71
  export async function roboparkServe(opts) {
50
72
  const schedulerPath = findScheduler();
51
73
  if (!schedulerPath) {
@@ -15,6 +15,7 @@ import { join } from 'node:path';
15
15
  import { spawn } from 'node:child_process';
16
16
  import { discoverContext, generateToken } from './discovery.js';
17
17
  import { registerAutoStart } from './auto-start.js';
18
+ import { resolveInfinicodeBin } from './serve.js';
18
19
  const DEFAULT_MESH_PORT = 47913;
19
20
  const DEFAULT_SCHEDULER_PORT = 8080;
20
21
  function saveToken(token) {
@@ -29,8 +30,23 @@ function runDetached(cmd, args, env) {
29
30
  detached: true,
30
31
  env: { ...process.env, ...env },
31
32
  });
33
+ proc.on('error', (err) => {
34
+ console.log(chalk.red(` ✗ failed to start ${cmd}: ${err.message}`));
35
+ });
32
36
  proc.unref();
33
37
  }
38
+ /** Resolve the infinicode CLI and return the argv to spawn it. */
39
+ async function infinicodeArgv(args) {
40
+ const bin = await resolveInfinicodeBin();
41
+ if (bin)
42
+ return [bin.node, bin.script, ...args];
43
+ // Fallback: assume `infinicode` is on PATH. Will fail clearly if not.
44
+ return ['infinicode', ...args];
45
+ }
46
+ /** Build a Windows-task-friendly command string from an argv array. */
47
+ function commandString(argv) {
48
+ return argv.map(a => /[^a-zA-Z0-9_./:=,-]/.test(a) ? `"${a.replace(/"/g, '""')}"` : a).join(' ');
49
+ }
34
50
  export async function roboparkSetup(config, opts) {
35
51
  const ctx = await discoverContext();
36
52
  const role = opts.role ?? 'control';
@@ -89,24 +105,26 @@ async function setupHub(config, opts, internal) {
89
105
  console.log(' ' + chalk.cyan(`robopark serve --port ${schedulerPort}`));
90
106
  console.log();
91
107
  if (opts.start) {
108
+ const hubArgv = await infinicodeArgv(infinicodeArgs);
92
109
  console.log(chalk.dim(' starting infinicode hub…'));
93
- runDetached('infinicode', infinicodeArgs);
110
+ runDetached(hubArgv[0], hubArgv.slice(1));
94
111
  console.log(chalk.dim(' starting robopark scheduler…'));
95
- runDetached('robopark', ['serve', '--port', String(schedulerPort)]);
112
+ runDetached(process.execPath, [process.argv[1], 'serve', '--port', String(schedulerPort)]);
96
113
  }
97
114
  if (opts.autoStart) {
115
+ const hubArgv = await infinicodeArgv(infinicodeArgs);
98
116
  const reg = await registerAutoStart({
99
117
  role: 'hub',
100
118
  name: internal.name,
101
- command: 'infinicode',
102
- args: infinicodeArgs,
119
+ command: hubArgv[0],
120
+ args: hubArgv.slice(1),
103
121
  });
104
122
  console.log(reg.ok ? chalk.green(` ✓ ${reg.message}`) : chalk.yellow(` ⚠ ${reg.message}`));
105
123
  const reg2 = await registerAutoStart({
106
124
  role: 'hub-scheduler',
107
125
  name: internal.name,
108
- command: 'robopark',
109
- args: ['serve', '--port', String(schedulerPort), '--foreground'],
126
+ command: process.execPath,
127
+ args: [process.argv[1], 'serve', '--port', String(schedulerPort), '--foreground'],
110
128
  });
111
129
  console.log(reg2.ok ? chalk.green(` ✓ ${reg2.message}`) : chalk.yellow(` ⚠ ${reg2.message}`));
112
130
  }
@@ -142,15 +160,17 @@ async function setupRobot(config, opts, ctx, internal) {
142
160
  console.log(' ' + chalk.cyan(`infinicode ${args.join(' ')}`));
143
161
  console.log();
144
162
  if (opts.start) {
163
+ const robotArgv = await infinicodeArgv(args);
145
164
  console.log(chalk.dim(' starting robot satellite node…'));
146
- runDetached('infinicode', args);
165
+ runDetached(robotArgv[0], robotArgv.slice(1));
147
166
  }
148
167
  if (opts.autoStart) {
168
+ const robotArgv = await infinicodeArgv(args);
149
169
  const reg = await registerAutoStart({
150
170
  role: 'robot',
151
171
  name: internal.name,
152
- command: 'infinicode',
153
- args,
172
+ command: robotArgv[0],
173
+ args: robotArgv.slice(1),
154
174
  });
155
175
  console.log(reg.ok ? chalk.green(` ✓ ${reg.message}`) : chalk.yellow(` ⚠ ${reg.message}`));
156
176
  }
@@ -167,8 +187,12 @@ async function setupControl(config, opts, ctx, internal) {
167
187
  console.log(' ' + chalk.cyan(`infinicode ${args.join(' ')}`));
168
188
  console.log();
169
189
  if (opts.start) {
190
+ const controlArgv = await infinicodeArgv(args);
170
191
  console.log(chalk.dim(' registering infinicode MCP host…'));
171
- const proc = spawn('infinicode', args, { stdio: 'inherit' });
192
+ const proc = spawn(controlArgv[0], controlArgv.slice(1), { stdio: 'inherit' });
193
+ proc.on('error', (err) => {
194
+ console.log(chalk.red(` ✗ failed to start infinicode: ${err.message}`));
195
+ });
172
196
  await new Promise(resolve => proc.on('close', () => resolve()));
173
197
  }
174
198
  }
@@ -17,7 +17,7 @@ const config = new Conf({
17
17
  });
18
18
  const program = new Command('robopark')
19
19
  .description('RoboPark fleet control CLI — set up, watch, and drive talking robots')
20
- .version('2.8.0');
20
+ .version('2.8.1');
21
21
  program
22
22
  .command('scan')
23
23
  .description('Auto-discover the fleet and print ready-to-run setup commands')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "infinicode",
3
- "version": "2.8.0",
3
+ "version": "2.8.1",
4
4
  "description": "OpenKernel — provider-agnostic AI execution kernel. Native coding agent + mission-driven execution runtime.",
5
5
  "type": "module",
6
6
  "main": "./dist/kernel/index.js",