@polderlabs/bizar 4.4.4 → 4.4.6
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/install.mjs +36 -62
- package/cli/update.mjs +20 -107
- package/install.sh +72 -36
- package/package.json +1 -1
package/cli/install.mjs
CHANGED
|
@@ -26,15 +26,12 @@ const AGENT_FILES = [
|
|
|
26
26
|
];
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* Install the Bizar opencode plugin from
|
|
30
|
-
*
|
|
31
|
-
* no longer ships `plugins/bizar/` — the plugin lives in its own scoped package
|
|
32
|
-
* so it can be versioned and published independently.
|
|
29
|
+
* Install the Bizar opencode plugin from this package's own
|
|
30
|
+
* `plugins/bizar/` directory into `~/.config/opencode/plugins/bizar/`.
|
|
33
31
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* `
|
|
37
|
-
* `npm install -g @polderlabs/bizar-plugin`.
|
|
32
|
+
* v4.0.0 consolidated everything into one npm package, so the plugin
|
|
33
|
+
* source ships with `@polderlabs/bizar` itself — no separate
|
|
34
|
+
* `@polderlabs/bizar-plugin` package, no git clone, no fresh checkout.
|
|
38
35
|
*
|
|
39
36
|
* Symlink guard (v3.12.2): if the dest is a symlink (e.g. created by
|
|
40
37
|
* `bizar dev-link`), do NOT overwrite it. The copy below would otherwise
|
|
@@ -43,26 +40,22 @@ const AGENT_FILES = [
|
|
|
43
40
|
* confirming the user really wants the deployed copy back).
|
|
44
41
|
*
|
|
45
42
|
* node_modules copy: the plugin imports `@polderlabs/bizar-sdk`, a
|
|
46
|
-
* workspace-internal package not on the public registry.
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* plugin silently fails to load.
|
|
43
|
+
* workspace-internal package not on the public registry. After copying
|
|
44
|
+
* the plugin files, this function ALSO copies the source's `node_modules/`
|
|
45
|
+
* to the deployed `node_modules/` so Bun can resolve the import when the
|
|
46
|
+
* plugin is loaded from `~/.config/opencode/plugins/bizar/`. Without
|
|
47
|
+
* this, the plugin silently fails to load.
|
|
52
48
|
*
|
|
53
49
|
* Pass `{ silent: true }` to suppress the warning prints; the function
|
|
54
50
|
* still returns `true` if the dest is already in the desired state.
|
|
55
51
|
*
|
|
56
|
-
* Pass `{ sourceDir: '/path/to/fake' }` (test seam) to
|
|
57
|
-
*
|
|
58
|
-
* cli/install.test.mjs to drive the function against a controlled
|
|
59
|
-
* filesystem without touching the real global npm root.
|
|
52
|
+
* Pass `{ sourceDir: '/path/to/fake' }` (test seam) to drive the function
|
|
53
|
+
* against a controlled filesystem without touching the real install.
|
|
60
54
|
*
|
|
61
55
|
* Returns `true` if the plugin was installed (or already in place),
|
|
62
56
|
* `false` otherwise. Never throws.
|
|
63
57
|
*/
|
|
64
58
|
export async function installPluginFromGlobal(opts = {}) {
|
|
65
|
-
const { execSync } = await import('node:child_process');
|
|
66
59
|
const { mkdir, readdir, copyFile } = await import('node:fs/promises');
|
|
67
60
|
const { join } = await import('node:path');
|
|
68
61
|
|
|
@@ -87,7 +80,7 @@ export async function installPluginFromGlobal(opts = {}) {
|
|
|
87
80
|
}
|
|
88
81
|
console.log(
|
|
89
82
|
chalk.yellow(
|
|
90
|
-
' ⚠ ~/.config/opencode/plugins/bizar is a dev symlink — skipping
|
|
83
|
+
' ⚠ ~/.config/opencode/plugins/bizar is a dev symlink — skipping copy.',
|
|
91
84
|
),
|
|
92
85
|
);
|
|
93
86
|
console.log(
|
|
@@ -100,26 +93,19 @@ export async function installPluginFromGlobal(opts = {}) {
|
|
|
100
93
|
}
|
|
101
94
|
|
|
102
95
|
// ── Resolve source path ─────────────────────────────────────────────────────
|
|
103
|
-
//
|
|
104
|
-
//
|
|
96
|
+
// v4.4.5 — the plugin ships inside this package at <pkg>/plugins/bizar/.
|
|
97
|
+
// No separate npm package, no git clone.
|
|
105
98
|
let pluginPath;
|
|
106
99
|
if (opts.sourceDir) {
|
|
107
100
|
pluginPath = opts.sourceDir;
|
|
108
101
|
} else {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
globalRoot = execSync('npm root -g', { stdio: ['ignore', 'pipe', 'ignore'] })
|
|
112
|
-
.toString()
|
|
113
|
-
.trim();
|
|
114
|
-
} catch {
|
|
115
|
-
console.log(chalk.yellow(' ⚠ Could not determine npm global root — skipping plugin install'));
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
pluginPath = join(globalRoot, '@polderlabs', 'bizar-plugin');
|
|
102
|
+
// __dirname is `<pkg>/cli/`, so ../plugins/bizar is the canonical source.
|
|
103
|
+
pluginPath = join(__dirname, '..', 'plugins', 'bizar');
|
|
119
104
|
}
|
|
120
105
|
if (!existsSync(pluginPath)) {
|
|
121
|
-
console.log(chalk.
|
|
122
|
-
console.log(chalk.dim('
|
|
106
|
+
console.log(chalk.red(` ✗ Plugin source not found at ${pluginPath}`));
|
|
107
|
+
console.log(chalk.dim(' This package appears to be missing plugins/bizar/. Reinstall:'));
|
|
108
|
+
console.log(chalk.dim(' npm install -g @polderlabs/bizar --force'));
|
|
123
109
|
return false;
|
|
124
110
|
}
|
|
125
111
|
|
|
@@ -311,42 +297,30 @@ async function isPackageInstalled(name) {
|
|
|
311
297
|
}
|
|
312
298
|
|
|
313
299
|
async function promptAndInstallOptional() {
|
|
314
|
-
// Plugin
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
console.log(' Installing @polderlabs/bizar-plugin...');
|
|
326
|
-
execSync('npm install -g @polderlabs/bizar-plugin', { stdio: 'inherit' });
|
|
327
|
-
console.log(' ✓ @polderlabs/bizar-plugin installed');
|
|
328
|
-
} catch (err) {
|
|
329
|
-
console.log(` ✗ Failed to install @polderlabs/bizar-plugin: ${err.message}`);
|
|
330
|
-
console.log(' You can install it later with: npm install -g @polderlabs/bizar-plugin');
|
|
331
|
-
}
|
|
332
|
-
} else {
|
|
333
|
-
console.log(' Skipped. Install later with: npm install -g @polderlabs/bizar-plugin');
|
|
334
|
-
}
|
|
300
|
+
// v4.4.5 — Plugin and dashboard are both shipped inside this package.
|
|
301
|
+
// No separate npm install step is required for either. The plugin
|
|
302
|
+
// copy happens via installPluginFromGlobal() in runInstaller(); the
|
|
303
|
+
// dashboard is loaded directly from this package's bizar-dash/src/.
|
|
304
|
+
// We just verify they're present here and warn loudly if not.
|
|
305
|
+
const pluginPath = join(__dirname, '..', 'plugins', 'bizar');
|
|
306
|
+
if (!existsSync(pluginPath)) {
|
|
307
|
+
console.error('');
|
|
308
|
+
console.error(' ✗ Plugin source not found at plugins/bizar/.');
|
|
309
|
+
console.error(' This package is missing the plugin source. Reinstall:');
|
|
310
|
+
console.error(' npm install -g @polderlabs/bizar --force');
|
|
335
311
|
} else {
|
|
336
|
-
console.log(' ✓
|
|
312
|
+
console.log(' ✓ Plugin source present (plugins/bizar/)');
|
|
337
313
|
}
|
|
338
314
|
|
|
339
|
-
// Dashboard — v4.0.0: ships inside this package at <repo>/bizar-dash/
|
|
340
|
-
// Verify the directory is present; it's a corrupted install if missing.
|
|
341
315
|
const dashDir = join(__dirname, '..', 'bizar-dash');
|
|
342
316
|
const dashPkgJson = join(dashDir, 'package.json');
|
|
343
317
|
if (!existsSync(dashPkgJson)) {
|
|
344
318
|
console.error('');
|
|
345
|
-
console.error(' ✗ Dashboard
|
|
346
|
-
console.error(' This
|
|
347
|
-
console.error('
|
|
319
|
+
console.error(' ✗ Dashboard source not found at bizar-dash/.');
|
|
320
|
+
console.error(' This package is missing the dashboard source. Reinstall:');
|
|
321
|
+
console.error(' npm install -g @polderlabs/bizar --force');
|
|
348
322
|
} else {
|
|
349
|
-
console.log(' ✓ Dashboard
|
|
323
|
+
console.log(' ✓ Dashboard source present (bizar-dash/)');
|
|
350
324
|
}
|
|
351
325
|
}
|
|
352
326
|
|
package/cli/update.mjs
CHANGED
|
@@ -47,12 +47,13 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
47
47
|
const __dirname = dirname(__filename);
|
|
48
48
|
const REPO_ROOT = join(__dirname, '..');
|
|
49
49
|
|
|
50
|
+
// v4.4.5 — The plugin and dashboard are both shipped inside @polderlabs/bizar.
|
|
51
|
+
// No separate @polderlabs/bizar-plugin or @polderlabs/bizar-dash packages.
|
|
52
|
+
// Updating the main package updates everything.
|
|
50
53
|
const PKG_MAIN = '@polderlabs/bizar';
|
|
51
|
-
const PKG_DASH = '@polderlabs/bizar-dash';
|
|
52
|
-
const PKG_PLUGIN = '@polderlabs/bizar-plugin';
|
|
53
54
|
|
|
54
55
|
// All known components, in the order they should be prompted + updated.
|
|
55
|
-
const COMPONENTS = ['opencode', 'bizar'
|
|
56
|
+
const COMPONENTS = ['opencode', 'bizar'];
|
|
56
57
|
|
|
57
58
|
// ---------------------------------------------------------------------------
|
|
58
59
|
// Config paths (mirror the dashboard + service for consistency)
|
|
@@ -431,11 +432,13 @@ function spawnFreshDashboard({ port } = {}) {
|
|
|
431
432
|
} catch {
|
|
432
433
|
return { ok: false, message: 'could not locate npm global root' };
|
|
433
434
|
}
|
|
434
|
-
|
|
435
|
+
// v4.4.5 — Dashboard ships inside @polderlabs/bizar (no separate
|
|
436
|
+
// @polderlabs/bizar-dash). Resolve the main package's cli.mjs.
|
|
437
|
+
const dashBin = join(globalRoot, '@polderlabs', 'bizar', 'cli', 'bin.mjs');
|
|
435
438
|
if (!existsSync(dashBin)) {
|
|
436
439
|
return {
|
|
437
440
|
ok: false,
|
|
438
|
-
message: `dashboard binary not found at ${dashBin} (was @polderlabs/bizar
|
|
441
|
+
message: `dashboard binary not found at ${dashBin} (was @polderlabs/bizar installed?)`,
|
|
439
442
|
};
|
|
440
443
|
}
|
|
441
444
|
try {
|
|
@@ -536,59 +539,6 @@ async function installSkills({ dryRun = false } = {}) {
|
|
|
536
539
|
return results;
|
|
537
540
|
}
|
|
538
541
|
|
|
539
|
-
/**
|
|
540
|
-
* Rebuild the bizar-dash frontend with Vite.
|
|
541
|
-
*/
|
|
542
|
-
function rebuildDashboard({ dryRun = false } = {}) {
|
|
543
|
-
const dashDir = join(REPO_ROOT, 'bizar-dash');
|
|
544
|
-
const pkgJson = join(dashDir, 'package.json');
|
|
545
|
-
if (!existsSync(pkgJson)) {
|
|
546
|
-
return { ok: false, message: 'bizar-dash/package.json not found — is the dashboard cloned?' };
|
|
547
|
-
}
|
|
548
|
-
if (dryRun) {
|
|
549
|
-
console.log(chalk.dim(' [dry-run] would run: npx vite build (in bizar-dash/)'));
|
|
550
|
-
return { ok: true, message: '[dry-run] dashboard rebuild' };
|
|
551
|
-
}
|
|
552
|
-
console.log(chalk.dim('\n Rebuilding dashboard...'));
|
|
553
|
-
const r = spawnSync('npx', ['vite', 'build'], {
|
|
554
|
-
stdio: 'inherit', cwd: dashDir, timeout: 120000,
|
|
555
|
-
});
|
|
556
|
-
if (r.status === 0) {
|
|
557
|
-
return { ok: true, message: 'dashboard rebuilt' };
|
|
558
|
-
}
|
|
559
|
-
return { ok: false, message: 'dashboard rebuild failed (try: cd bizar-dash && npx vite build)' };
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
/**
|
|
563
|
-
* Detect and run the project's test suite. Checks for common test runners
|
|
564
|
-
* (npm test, pytest, cargo test, go test) and runs the first one found.
|
|
565
|
-
*/
|
|
566
|
-
function runTestGate({ dryRun = false } = {}) {
|
|
567
|
-
if (dryRun) {
|
|
568
|
-
console.log(chalk.dim(' [dry-run] would detect and run local test suite'));
|
|
569
|
-
return { ok: true, message: '[dry-run] test gate' };
|
|
570
|
-
}
|
|
571
|
-
const cwd = process.cwd();
|
|
572
|
-
const suites = [
|
|
573
|
-
{ cmd: 'npm test', check: 'package.json' },
|
|
574
|
-
{ cmd: 'pytest', check: 'pyproject.toml' },
|
|
575
|
-
{ cmd: 'cargo test', check: 'Cargo.toml' },
|
|
576
|
-
{ cmd: 'go test ./...', check: 'go.mod' },
|
|
577
|
-
];
|
|
578
|
-
for (const suite of suites) {
|
|
579
|
-
try {
|
|
580
|
-
if (existsSync(join(cwd, suite.check))) {
|
|
581
|
-
console.log(chalk.dim(`\n Running test suite: ${suite.cmd}...`));
|
|
582
|
-
execSync(suite.cmd, { stdio: 'inherit', timeout: 120000, cwd });
|
|
583
|
-
return { ok: true, message: `test gate passed (${suite.cmd})` };
|
|
584
|
-
}
|
|
585
|
-
} catch {
|
|
586
|
-
return { ok: false, message: `test gate failed (${suite.cmd})` };
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
return { ok: true, message: 'no test suite detected (skipped)' };
|
|
590
|
-
}
|
|
591
|
-
|
|
592
542
|
// ---------------------------------------------------------------------------
|
|
593
543
|
// Prompt helpers
|
|
594
544
|
// ---------------------------------------------------------------------------
|
|
@@ -603,9 +553,7 @@ async function promptForUpdates(forceAll) {
|
|
|
603
553
|
message: 'Which components do you want to update?',
|
|
604
554
|
choices: [
|
|
605
555
|
{ name: 'opencode (the opencode CLI itself)', value: 'opencode', checked: true },
|
|
606
|
-
{ name: `bizar (${PKG_MAIN})`, value: 'bizar', checked: true },
|
|
607
|
-
{ name: `bizar dash (${PKG_DASH}) — web dashboard`, value: 'dash', checked: true },
|
|
608
|
-
{ name: `plugin (${PKG_PLUGIN})`, value: 'plugin', checked: true },
|
|
556
|
+
{ name: `bizar (${PKG_MAIN}) — includes plugin + dashboard`, value: 'bizar', checked: true },
|
|
609
557
|
],
|
|
610
558
|
},
|
|
611
559
|
]);
|
|
@@ -717,24 +665,16 @@ export async function runUpdate(subargs = []) {
|
|
|
717
665
|
const cur = {
|
|
718
666
|
opencode: currentVersion('opencode-ai'),
|
|
719
667
|
bizar: currentVersion(PKG_MAIN),
|
|
720
|
-
dash: currentVersion(PKG_DASH),
|
|
721
|
-
plugin: currentVersion(PKG_PLUGIN),
|
|
722
668
|
};
|
|
723
669
|
const latest = {
|
|
724
670
|
opencode: latestVersion('opencode-ai'),
|
|
725
671
|
bizar: latestVersion(PKG_MAIN),
|
|
726
|
-
dash: latestVersion(PKG_DASH),
|
|
727
|
-
plugin: latestVersion(PKG_PLUGIN),
|
|
728
672
|
};
|
|
729
673
|
|
|
730
674
|
console.log('');
|
|
731
675
|
console.log(' Installed vs. latest:');
|
|
732
676
|
for (const k of COMPONENTS) {
|
|
733
|
-
const label =
|
|
734
|
-
k === 'plugin' ? PKG_PLUGIN :
|
|
735
|
-
k === 'dash' ? PKG_DASH :
|
|
736
|
-
k === 'bizar' ? PKG_MAIN :
|
|
737
|
-
'opencode-ai';
|
|
677
|
+
const label = k === 'bizar' ? PKG_MAIN : 'opencode-ai';
|
|
738
678
|
const c = cur[k] ?? '(not installed)';
|
|
739
679
|
const l = latest[k] ?? '(unknown)';
|
|
740
680
|
const same = c === l;
|
|
@@ -824,23 +764,15 @@ export async function runUpdate(subargs = []) {
|
|
|
824
764
|
console.log(chalk.bold(` → ${PKG_MAIN}`));
|
|
825
765
|
results.push(['bizar', updatePackage(PKG_MAIN, { dryRun })]);
|
|
826
766
|
}
|
|
827
|
-
if (selected.has('dash')) {
|
|
828
|
-
console.log(chalk.bold(` → ${PKG_DASH}`));
|
|
829
|
-
results.push(['dash', updatePackage(PKG_DASH, { dryRun })]);
|
|
830
|
-
}
|
|
831
|
-
if (selected.has('plugin')) {
|
|
832
|
-
console.log(chalk.bold(` → ${PKG_PLUGIN}`));
|
|
833
|
-
results.push(['plugin', updatePackage(PKG_PLUGIN, { dryRun })]);
|
|
834
|
-
}
|
|
835
767
|
|
|
836
768
|
// 4. Re-run the install script if anything relevant changed.
|
|
837
769
|
const anySuccess = results.some(([, r]) => r.ok);
|
|
838
|
-
if (anySuccess &&
|
|
770
|
+
if (anySuccess && selected.has('bizar')) {
|
|
839
771
|
console.log('');
|
|
840
772
|
if (dryRun) {
|
|
841
773
|
console.log(
|
|
842
774
|
chalk.dim(
|
|
843
|
-
' [dry-run] would re-run install
|
|
775
|
+
' [dry-run] would re-run install.sh to refresh agent files + plugin copy',
|
|
844
776
|
),
|
|
845
777
|
);
|
|
846
778
|
} else {
|
|
@@ -849,7 +781,7 @@ export async function runUpdate(subargs = []) {
|
|
|
849
781
|
console.log(chalk.green(`\n ✓ ${rerun.message}`));
|
|
850
782
|
} else {
|
|
851
783
|
console.log(chalk.yellow(`\n ⚠ ${rerun.message}`));
|
|
852
|
-
console.log(chalk.dim(' Run `
|
|
784
|
+
console.log(chalk.dim(' Run `bizar install` to refresh agent files + plugin copy.'));
|
|
853
785
|
}
|
|
854
786
|
}
|
|
855
787
|
}
|
|
@@ -859,27 +791,15 @@ export async function runUpdate(subargs = []) {
|
|
|
859
791
|
const skillResults = await installSkills({ dryRun });
|
|
860
792
|
const skillOk = skillResults.length === 0 || skillResults.every((r) => r.ok);
|
|
861
793
|
|
|
862
|
-
//
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
} else {
|
|
868
|
-
console.log(chalk.yellow(` ⚠ ${dashRebuild.message}`));
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
// ── Test gate ───────────────────────────────────────────────────────
|
|
872
|
-
console.log(chalk.bold('\n → Running test gate...'));
|
|
873
|
-
const testResult = runTestGate({ dryRun });
|
|
874
|
-
if (testResult.ok) {
|
|
875
|
-
console.log(chalk.green(` ✓ ${testResult.message}`));
|
|
876
|
-
} else {
|
|
877
|
-
console.log(chalk.red(` ✗ ${testResult.message}`));
|
|
878
|
-
}
|
|
794
|
+
// v4.4.5 — Dashboard dist ships prebuilt inside the npm package. No
|
|
795
|
+
// rebuild step is needed (and we can't run `vite build` from the
|
|
796
|
+
// installed package anyway — node_modules/vite lives outside the
|
|
797
|
+
// plugin's runtime context). The next launch picks up the new dist
|
|
798
|
+
// when `bizar dash start --bg` runs.
|
|
879
799
|
|
|
880
800
|
// ── Restart dashboard ─────────────────────────────────────────────
|
|
881
|
-
// Restart if it was running before
|
|
882
|
-
if (restartAfter &&
|
|
801
|
+
// Restart if it was running before.
|
|
802
|
+
if (restartAfter && instances.dashboard) {
|
|
883
803
|
if (dryRun) {
|
|
884
804
|
console.log('');
|
|
885
805
|
console.log(chalk.dim(' [dry-run] would restart dashboard with the new code'));
|
|
@@ -908,17 +828,10 @@ export async function runUpdate(subargs = []) {
|
|
|
908
828
|
const marker = sr.ok ? chalk.green('✓') : chalk.red('✗');
|
|
909
829
|
console.log(` ${marker} ${'skill/skills'.padEnd(10)} ${sr.ok ? 'installed' : `failed: ${sr.skill}`}`);
|
|
910
830
|
}
|
|
911
|
-
if (!dashRebuild.ok) {
|
|
912
|
-
console.log(` ${chalk.yellow('⚠')} ${'dash'.padEnd(10)} ${dashRebuild.message}`);
|
|
913
|
-
}
|
|
914
|
-
const testMarker = testResult.ok ? chalk.green('✓') : chalk.red('✗');
|
|
915
|
-
console.log(` ${testMarker} ${'test-gate'.padEnd(10)} ${testResult.message}`);
|
|
916
831
|
|
|
917
832
|
const allResults = [
|
|
918
833
|
...results.map(([, r]) => r),
|
|
919
834
|
...skillResults,
|
|
920
|
-
dashRebuild,
|
|
921
|
-
testResult,
|
|
922
835
|
];
|
|
923
836
|
const anyFail = allResults.some((r) => !r.ok);
|
|
924
837
|
if (anyFail) {
|
package/install.sh
CHANGED
|
@@ -215,61 +215,97 @@ ensure_node() {
|
|
|
215
215
|
note "Node.js installed: $(node --version)"
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
# ──
|
|
218
|
+
# ── Standalone installer (no git clone) ─────────────────────────────────────────
|
|
219
|
+
# v4.4.5 — The plugin, agents, commands, hooks, and dashboard ALL ship inside
|
|
220
|
+
# this package. No separate npm install, no git clone, no separate package
|
|
221
|
+
# lookup. install.sh runs entirely against its own `$REPO_DIR` (which is the
|
|
222
|
+
# installed package directory — `<npm root -g>/@polderlabs/bizar/`).
|
|
219
223
|
|
|
220
224
|
ensure_repo() {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
note "
|
|
226
|
-
|
|
225
|
+
# v4.4.5 — No-op. Everything ships with the package. We still log a note
|
|
226
|
+
# so users upgrading from older versions see that the git-clone step is
|
|
227
|
+
# intentionally gone.
|
|
228
|
+
if [ -d "$REPO_DIR/plugins/bizar" ] && [ -d "$REPO_DIR/bizar-dash" ]; then
|
|
229
|
+
note "using bundled plugin + dashboard from $REPO_DIR"
|
|
230
|
+
else
|
|
231
|
+
err "package missing required files (plugins/bizar or bizar-dash)"
|
|
232
|
+
err "this looks like a corrupted install — try: npm install -g @polderlabs/bizar --force"
|
|
233
|
+
exit 1
|
|
227
234
|
fi
|
|
228
235
|
|
|
229
|
-
#
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if $
|
|
233
|
-
|
|
236
|
+
# Clean up any stale separate-repo clone left over from v3.x installs.
|
|
237
|
+
local stale_clone="$(dirname "$REPO_DIR")/BizarHarness"
|
|
238
|
+
if [ -d "$stale_clone" ] && [ "$stale_clone" != "$REPO_DIR" ]; then
|
|
239
|
+
if $DRY_RUN; then
|
|
240
|
+
dim " would remove stale v3.x clone at $stale_clone"
|
|
241
|
+
else
|
|
242
|
+
action "Removing stale v3.x repo clone at $stale_clone..."
|
|
243
|
+
rm -rf "$stale_clone" 2>/dev/null && note "removed" || dim " (could not remove; harmless)"
|
|
234
244
|
fi
|
|
235
|
-
return
|
|
236
|
-
fi
|
|
237
|
-
|
|
238
|
-
section "Cloning BizarHarness repository"
|
|
239
|
-
local target
|
|
240
|
-
target="$(dirname "$REPO_DIR")/BizarHarness"
|
|
241
|
-
if [ ! -d "$target" ]; then
|
|
242
|
-
action "Cloning into $target..."
|
|
243
|
-
dry git clone https://github.com/DrB0rk/BizarHarness.git "$target"
|
|
244
|
-
note "cloned"
|
|
245
|
-
else
|
|
246
|
-
note "already cloned at $target"
|
|
247
245
|
fi
|
|
248
246
|
}
|
|
249
247
|
|
|
250
|
-
# ──
|
|
248
|
+
# ── Copy agent / config / dashboard files ──────────────────────────────────────
|
|
251
249
|
|
|
252
250
|
install_config() {
|
|
253
251
|
section "Installing BizarHarness config files"
|
|
254
252
|
|
|
255
253
|
if $DRY_RUN; then
|
|
256
|
-
dim " would
|
|
254
|
+
dim " would copy agents/, commands/, hooks/, skills/ to ~/.config/opencode/"
|
|
257
255
|
return
|
|
258
256
|
fi
|
|
259
257
|
|
|
260
|
-
|
|
261
|
-
|
|
258
|
+
local dst="${XDG_CONFIG_HOME:-$HOME/.config}/opencode"
|
|
259
|
+
mkdir -p "$dst/agents" "$dst/agents/_shared" "$dst/command" "$dst/commands" "$dst/skill" "$dst/skills" 2>/dev/null
|
|
260
|
+
|
|
261
|
+
# Agents
|
|
262
|
+
if [ -d "$REPO_DIR/config/agents" ]; then
|
|
263
|
+
action "Copying agent files..."
|
|
264
|
+
cp -R "$REPO_DIR/config/agents/." "$dst/agents/" 2>/dev/null && note "agents synced" || warn "agent copy incomplete"
|
|
265
|
+
fi
|
|
266
|
+
|
|
267
|
+
# Slash commands
|
|
268
|
+
if [ -d "$REPO_DIR/config/command" ]; then
|
|
269
|
+
cp -R "$REPO_DIR/config/command/." "$dst/command/" 2>/dev/null
|
|
270
|
+
fi
|
|
271
|
+
if [ -d "$REPO_DIR/config/commands" ]; then
|
|
272
|
+
cp -R "$REPO_DIR/config/commands/." "$dst/commands/" 2>/dev/null
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
# Skills (bundled)
|
|
276
|
+
for skill in obsidian glyph read-the-damn-docs; do
|
|
277
|
+
if [ -d "$REPO_DIR/config/skills/$skill" ]; then
|
|
278
|
+
cp -R "$REPO_DIR/config/skills/$skill" "$dst/skill/" 2>/dev/null
|
|
279
|
+
cp -R "$REPO_DIR/config/skills/$skill" "$dst/skills/" 2>/dev/null
|
|
280
|
+
fi
|
|
281
|
+
done
|
|
282
|
+
note "skills installed"
|
|
283
|
+
|
|
284
|
+
# AGENTS.md
|
|
285
|
+
if [ -f "$REPO_DIR/AGENTS.md" ]; then
|
|
286
|
+
cp "$REPO_DIR/AGENTS.md" "$dst/AGENTS.md" 2>/dev/null && note "AGENTS.md synced" || true
|
|
287
|
+
fi
|
|
262
288
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
289
|
+
# Plugin (copy from <pkg>/plugins/bizar/ to ~/.config/opencode/plugins/bizar/)
|
|
290
|
+
local dst_plugin="$dst/plugins/bizar"
|
|
291
|
+
if [ -d "$REPO_DIR/plugins/bizar" ]; then
|
|
292
|
+
mkdir -p "$dst_plugin"
|
|
293
|
+
# Skip node_modules + dist to keep the deploy dir small; the plugin's
|
|
294
|
+
# package.json declares its deps and Bun resolves them from the user's
|
|
295
|
+
# global node_modules at load time.
|
|
296
|
+
if command -v rsync >/dev/null 2>&1; then
|
|
297
|
+
rsync -a --exclude='node_modules' --exclude='dist' --exclude='.DS_Store' \
|
|
298
|
+
"$REPO_DIR/plugins/bizar/" "$dst_plugin/" 2>/dev/null && note "plugin copied to $dst_plugin" \
|
|
299
|
+
|| warn "plugin copy incomplete"
|
|
268
300
|
else
|
|
269
|
-
|
|
301
|
+
# Fallback: shell glob + cp — mirrors rsync's exclude behaviour by
|
|
302
|
+
# pruning after copy.
|
|
303
|
+
cp -R "$REPO_DIR/plugins/bizar/." "$dst_plugin/" 2>/dev/null
|
|
304
|
+
rm -rf "$dst_plugin/node_modules" "$dst_plugin/dist" 2>/dev/null
|
|
305
|
+
note "plugin copied to $dst_plugin (cp fallback)"
|
|
270
306
|
fi
|
|
271
307
|
else
|
|
272
|
-
warn "
|
|
308
|
+
warn "plugin source not found at $REPO_DIR/plugins/bizar/"
|
|
273
309
|
fi
|
|
274
310
|
}
|
|
275
311
|
|
|
@@ -370,7 +406,7 @@ install_service() {
|
|
|
370
406
|
|
|
371
407
|
if [ "$ok" = "yes" ]; then
|
|
372
408
|
if [ "$skipped" = "yes" ]; then
|
|
373
|
-
dim " (service
|
|
409
|
+
dim " (service registration deferred — re-run \`bizar service install\` to retry)"
|
|
374
410
|
fi
|
|
375
411
|
note "service registration complete"
|
|
376
412
|
else
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polderlabs/bizar",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.6",
|
|
4
4
|
"description": "Norse-pantheon multi-agent system for opencode — 13 agents across 4 cost tiers with cost-aware routing, plans, and a configurable agent harness. v4 ships as a single npm package bundling the dashboard server, opencode plugin, and typed SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|