@polderlabs/bizar 3.1.1 → 3.2.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.
Files changed (2) hide show
  1. package/cli/install.mjs +95 -0
  2. package/package.json +1 -1
package/cli/install.mjs CHANGED
@@ -294,7 +294,102 @@ export async function runInstaller() {
294
294
  console.log(chalk.dim('\n Odin watches. The Pantheon awaits. ᛟ\n'));
295
295
  }
296
296
 
297
+ // ── Interactive prompts for optional packages ─────────────────────────────────
298
+
299
+ import { execSync } from 'node:child_process';
300
+ import { createInterface } from 'node:readline/promises';
301
+ import { stdin, stdout } from 'node:process';
302
+
303
+ async function promptYesNo(question, defaultYes = true) {
304
+ // If not a TTY (CI, automated install), skip the prompt
305
+ if (!stdin.isTTY || !stdout.isTTY) {
306
+ return false;
307
+ }
308
+
309
+ const rl = createInterface({ input: stdin, output: stdout });
310
+ try {
311
+ const hint = defaultYes ? '[Y/n]' : '[y/N]';
312
+ const answer = (await rl.question(` ${question} ${hint}: `)).trim().toLowerCase();
313
+ rl.close();
314
+
315
+ if (answer === '') return defaultYes;
316
+ if (['y', 'yes'].includes(answer)) return true;
317
+ if (['n', 'no'].includes(answer)) return false;
318
+ return defaultYes;
319
+ } catch {
320
+ rl.close();
321
+ return false;
322
+ }
323
+ }
324
+
325
+ async function isPackageInstalled(name) {
326
+ try {
327
+ const globalRoot = execSync('npm root -g', { encoding: 'utf8' }).trim();
328
+ require.resolve(name, { paths: [globalRoot] });
329
+ return true;
330
+ } catch {
331
+ return false;
332
+ }
333
+ }
334
+
335
+ async function promptAndInstallOptional() {
336
+ // Plugin
337
+ const pluginInstalled = await isPackageInstalled('@polderlabs/bizar-plugin');
338
+ if (!pluginInstalled) {
339
+ console.log('');
340
+ console.log(' The Bizar opencode plugin is required for the /bizar command and agent integration.');
341
+ const install = await promptYesNo(
342
+ 'Install @polderlabs/bizar-plugin?',
343
+ true,
344
+ );
345
+ if (install) {
346
+ try {
347
+ console.log(' Installing @polderlabs/bizar-plugin...');
348
+ execSync('npm install -g @polderlabs/bizar-plugin', { stdio: 'inherit' });
349
+ console.log(' ✓ @polderlabs/bizar-plugin installed');
350
+ } catch (err) {
351
+ console.log(` ✗ Failed to install @polderlabs/bizar-plugin: ${err.message}`);
352
+ console.log(' You can install it later with: npm install -g @polderlabs/bizar-plugin');
353
+ }
354
+ } else {
355
+ console.log(' Skipped. Install later with: npm install -g @polderlabs/bizar-plugin');
356
+ }
357
+ } else {
358
+ console.log(' ✓ @polderlabs/bizar-plugin already installed');
359
+ }
360
+
361
+ // Dashboard
362
+ const dashInstalled = await isPackageInstalled('@polderlabs/bizar-dash');
363
+ if (!dashInstalled) {
364
+ console.log('');
365
+ console.log(' The Bizar dashboard provides the web UI (React + Vite) and TUI (blessed).');
366
+ console.log(' It\'s optional — install it for the full experience, or use the CLI alone.');
367
+ const install = await promptYesNo(
368
+ 'Install @polderlabs/bizar-dash?',
369
+ true,
370
+ );
371
+ if (install) {
372
+ try {
373
+ console.log(' Installing @polderlabs/bizar-dash...');
374
+ execSync('npm install -g @polderlabs/bizar-dash', { stdio: 'inherit' });
375
+ console.log(' ✓ @polderlabs/bizar-dash installed');
376
+ } catch (err) {
377
+ console.log(` ✗ Failed to install @polderlabs/bizar-dash: ${err.message}`);
378
+ console.log(' You can install it later with: npm install -g @polderlabs/bizar-dash');
379
+ }
380
+ } else {
381
+ console.log(' Skipped. Install later with: npm install -g @polderlabs/bizar-dash');
382
+ }
383
+ } else {
384
+ console.log(' ✓ @polderlabs/bizar-dash already installed');
385
+ }
386
+ }
387
+
297
388
  export async function runPostInstall() {
389
+ // Skip interactive prompts in CI / non-TTY environments
390
+ if (!process.env.BIZAR_SKIP_OPTIONAL_INSTALLS) {
391
+ await promptAndInstallOptional();
392
+ }
298
393
  const { mkdirSync, copyFileSync, existsSync } = await import('node:fs');
299
394
  const { execSync } = await import('node:child_process');
300
395
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polderlabs/bizar",
3
- "version": "3.1.1",
3
+ "version": "3.2.1",
4
4
  "description": "Norse-pantheon multi-agent system for opencode — 13 agents across 4 cost tiers with cost-aware routing, per-project Hindsight memory, mods, schedules, and a background service daemon",
5
5
  "type": "module",
6
6
  "bin": {