@polderlabs/bizar 3.7.2 → 3.8.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/cli/init.mjs CHANGED
@@ -150,6 +150,41 @@ ${stack.runner ? `- Dev: \`${stack.runner}\`` : ''}
150
150
  console.log(chalk.green(` ✓ Created ${siPath}`));
151
151
  }
152
152
 
153
+ // Build per-project knowledge graph (graphify -> .bizar/graph/)
154
+ // Soft step: never fails init. If graphify is missing or build errors,
155
+ // the user can retry manually with `bizar graph build`.
156
+ console.log(chalk.bold('\n--- Graph ---\n'));
157
+ const detectGraphify = spawnSync('python3', ['-c', 'import graphify; print(graphify.__version__)'], {
158
+ cwd,
159
+ encoding: 'utf8',
160
+ timeout: 5000,
161
+ });
162
+ const graphifyAvailable = detectGraphify.status === 0 && (detectGraphify.stdout || '').trim().length > 0;
163
+
164
+ if (!graphifyAvailable) {
165
+ console.log(chalk.yellow(' graphify not detected — skipping project graph build.'));
166
+ console.log(chalk.dim(' Install with: pip install graphifyy (or pipx install graphifyy)'));
167
+ console.log(chalk.dim(' Then re-run: bizar graph build'));
168
+ console.log(chalk.dim(' The graph will land in .bizar/graph/ inside this project.'));
169
+ } else {
170
+ console.log(chalk.dim(' Building project knowledge graph (.bizar/graph/)...'));
171
+ // npx resolves "bizar" via local package.json bin field (or global install).
172
+ // Fallback for environments without global bizar: node <repo>/cli/bin.mjs graph build
173
+ const buildResult = spawnSync('npx', ['bizar', 'graph', 'build'], {
174
+ cwd,
175
+ stdio: 'inherit',
176
+ timeout: 5 * 60 * 1000,
177
+ });
178
+ if (buildResult.status === 0) {
179
+ console.log(chalk.green(' ✓ Graph built at .bizar/graph/ — query with: bizar graph query "<concept>"'));
180
+ } else {
181
+ const code = buildResult.status !== null ? buildResult.status : (buildResult.signal || '?');
182
+ console.log(chalk.yellow(` Graph build failed (exit ${code}). You can retry manually:`));
183
+ console.log(chalk.dim(' bizar graph build'));
184
+ console.log(chalk.dim(' The graph will land in .bizar/graph/ inside this project.'));
185
+ }
186
+ }
187
+
153
188
  console.log(chalk.dim('\n Project initialized. Run `@frigg` to ask questions about the codebase.\n'));
154
189
  return true;
155
190
  }
package/cli/install.mjs CHANGED
@@ -292,6 +292,9 @@ export async function runInstaller() {
292
292
  }
293
293
  }
294
294
 
295
+ // ── Post-install: graphify ──
296
+ await promptGraphifyInstall();
297
+
295
298
  // ── Post-install ──
296
299
  console.log(chalk.dim('\n Odin watches. The Pantheon awaits. ᛟ\n'));
297
300
  }
@@ -386,6 +389,61 @@ async function promptAndInstallOptional() {
386
389
  }
387
390
  }
388
391
 
392
+ async function promptGraphifyInstall() {
393
+ const { spawnSync } = await import('node:child_process');
394
+
395
+ console.log();
396
+ sectionHeading('Knowledge Graph (graphify)');
397
+
398
+ const detect = spawnSync('python3', ['-c', 'import graphify; print(graphify.__version__)'], {
399
+ cwd: process.cwd(),
400
+ encoding: 'utf8',
401
+ timeout: 5000,
402
+ });
403
+ const graphifyInstalled = detect.status === 0 && (detect.stdout || '').trim().length > 0;
404
+
405
+ if (graphifyInstalled) {
406
+ console.log(chalk.green(' graphify already installed — skipping.'));
407
+ return;
408
+ }
409
+
410
+ // Non-interactive: no TTY means we can't ask, so just print the hint
411
+ if (!stdin.isTTY || !stdout.isTTY) {
412
+ console.log(chalk.dim(' graphify not detected. Install later with:'));
413
+ console.log(chalk.dim(' pip install graphifyy'));
414
+ console.log(chalk.dim(' pipx install graphifyy'));
415
+ console.log(chalk.dim(' uv tool install graphifyy'));
416
+ console.log(chalk.dim(' Then run `bizar graph build` to populate .bizar/graph/.'));
417
+ return;
418
+ }
419
+
420
+ console.log(chalk.dim(' graphify not detected. graphify powers per-project knowledge graphs (bizar graph build).'));
421
+ console.log(chalk.dim(' Install with one of:'));
422
+ console.log(chalk.dim(' pip install graphifyy # user-site or venv'));
423
+ console.log(chalk.dim(' pipx install graphifyy # isolated CLI tool (recommended on macOS)'));
424
+ console.log(chalk.dim(' uv tool install graphifyy # via uv'));
425
+
426
+ const rl = createInterface({ input: stdin, output: stdout });
427
+ try {
428
+ const answer = (await rl.question(' Install graphify now via pip? [Y/n]: ')).trim().toLowerCase();
429
+ rl.close();
430
+
431
+ if (answer === '' || answer.startsWith('y')) {
432
+ const result = spawnSync('pip', ['install', 'graphifyy'], { stdio: 'inherit', timeout: 120000 });
433
+ if (result.status === 0) {
434
+ console.log(chalk.green(' graphify installed. Try: bizar graph build'));
435
+ } else {
436
+ console.log(chalk.yellow(` pip install failed (exit ${result.status}). You can install manually later — see options above.`));
437
+ }
438
+ } else {
439
+ console.log(chalk.dim(' Skipped. Install manually with one of the commands above when ready.'));
440
+ }
441
+ } catch {
442
+ rl.close();
443
+ console.log(chalk.dim(' Skipped.'));
444
+ }
445
+ }
446
+
389
447
  export async function runPostInstall() {
390
448
  // Skip interactive prompts in CI / non-TTY environments
391
449
  if (!process.env.BIZAR_SKIP_OPTIONAL_INSTALLS) {