@polderlabs/bizar 2.6.1 → 3.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/cli/bin.mjs +158 -130
- package/cli/plan.test.mjs +2331 -0
- package/cli/service.mjs +309 -0
- package/package.json +19 -27
- package/cli/dashboard/api.mjs +0 -473
- package/cli/dashboard/browser.mjs +0 -40
- package/cli/dashboard/server.mjs +0 -366
- package/cli/dashboard/state.mjs +0 -438
- package/cli/dashboard/tasks-store.mjs +0 -203
- package/cli/dashboard/watcher.mjs +0 -81
- package/cli/dashboard.mjs +0 -97
- package/dist/assets/index-BVvY22Gt.css +0 -1
- package/dist/assets/index-CO3c8O32.js +0 -285
- package/dist/assets/index-CO3c8O32.js.map +0 -1
- package/dist/index.html +0 -18
- package/src/App.tsx +0 -233
- package/src/components/Button.tsx +0 -55
- package/src/components/Card.tsx +0 -40
- package/src/components/EmptyState.tsx +0 -30
- package/src/components/Modal.tsx +0 -137
- package/src/components/Spinner.tsx +0 -19
- package/src/components/StatusBadge.tsx +0 -25
- package/src/components/Tag.tsx +0 -28
- package/src/components/Toast.tsx +0 -142
- package/src/components/Topbar.tsx +0 -88
- package/src/index.html +0 -17
- package/src/lib/api.ts +0 -71
- package/src/lib/markdown.tsx +0 -59
- package/src/lib/types.ts +0 -200
- package/src/lib/utils.ts +0 -79
- package/src/lib/ws.ts +0 -132
- package/src/main.tsx +0 -12
- package/src/styles/main.css +0 -2324
- package/src/views/Agents.tsx +0 -199
- package/src/views/Chat.tsx +0 -255
- package/src/views/Config.tsx +0 -250
- package/src/views/Overview.tsx +0 -267
- package/src/views/Plans.tsx +0 -667
- package/src/views/Projects.tsx +0 -155
- package/src/views/Settings.tsx +0 -253
- package/src/views/Tasks.tsx +0 -567
- package/tsconfig.json +0 -23
- package/vite.config.ts +0 -24
package/cli/bin.mjs
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* cli/bin.mjs
|
|
4
|
+
*
|
|
5
|
+
* v3.0.0 — `bizar` runtime CLI.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - `bizar` is the core runtime + installer + audit/init/export/update/plan
|
|
9
|
+
* + service commands.
|
|
10
|
+
* - The dashboard lives in a separate package, `@polderlabs/bizar-dash`.
|
|
11
|
+
* If it's installed, `bizar dashboard` / `bizar --web*` will defer to it.
|
|
12
|
+
* If not, the user is told to install it.
|
|
13
|
+
*
|
|
14
|
+
* Subcommands (unchanged from v2.7.0):
|
|
15
|
+
* install, audit, init, export, plan, update, test-gate, service
|
|
16
|
+
*
|
|
17
|
+
* Flags (unchanged):
|
|
18
|
+
* --web / --no-web / --web-only / --bg / --detach
|
|
19
|
+
*/
|
|
4
20
|
import { existsSync } from 'node:fs';
|
|
5
21
|
import { join } from 'node:path';
|
|
22
|
+
import chalk from 'chalk';
|
|
6
23
|
import { runInstaller, runPostInstall } from './install.mjs';
|
|
7
24
|
import { runAudit } from './audit.mjs';
|
|
8
25
|
import { runInit } from './init.mjs';
|
|
@@ -17,20 +34,33 @@ function showHelp() {
|
|
|
17
34
|
Bizar — Norse Pantheon Agent System for opencode
|
|
18
35
|
|
|
19
36
|
Usage:
|
|
20
|
-
bizar
|
|
37
|
+
bizar Launch the TUI dashboard (default)
|
|
38
|
+
bizar --web Launch TUI + auto-open web dashboard
|
|
39
|
+
bizar --no-web Launch TUI only (no browser)
|
|
40
|
+
bizar --web-only Web dashboard only (no TUI, in browser)
|
|
41
|
+
bizar --bg, --detach Launch web dashboard in background, return to shell
|
|
42
|
+
install Run the interactive installer
|
|
43
|
+
bizar install Same as \`install\`
|
|
21
44
|
bizar audit Run security audit on agent configuration
|
|
22
45
|
bizar init Initialize .bizar/ in current project
|
|
23
|
-
bizar export [target] Export agents/rules to another harness
|
|
24
|
-
bizar plan <subcommand> Manage visual plans
|
|
46
|
+
bizar export [target] Export agents/rules to another harness
|
|
47
|
+
bizar plan <subcommand> Manage visual plans
|
|
25
48
|
bizar test-gate Detect & run the project's test suite
|
|
26
49
|
bizar update Update opencode, bizar, and/or bizar-plugin
|
|
27
|
-
bizar
|
|
50
|
+
bizar service Manage the background service daemon
|
|
51
|
+
bizar dashboard Launch the web dashboard (uses bizar-dash)
|
|
28
52
|
bizar --help Show this help
|
|
29
53
|
|
|
30
54
|
Install:
|
|
31
|
-
npm install -g @polderlabs/bizar Install globally
|
|
32
|
-
npm install -g @polderlabs/bizar-
|
|
33
|
-
|
|
55
|
+
npm install -g @polderlabs/bizar Install globally
|
|
56
|
+
npm install -g @polderlabs/bizar-dash Optional companion dashboard
|
|
57
|
+
npm install -g @polderlabs/bizar-plugin Bizar opencode plugin
|
|
58
|
+
|
|
59
|
+
Notes:
|
|
60
|
+
The TUI is the default command — press 1-8 for tabs, q to quit.
|
|
61
|
+
\`bizar --bg\` launches the dashboard detached; \`bizar dashboard stop\`
|
|
62
|
+
terminates it. The web dashboard lives in the \`@polderlabs/bizar-dash\`
|
|
63
|
+
package — if it's not installed, you'll be prompted to install it.
|
|
34
64
|
`);
|
|
35
65
|
}
|
|
36
66
|
|
|
@@ -40,157 +70,131 @@ function showAuditHelp() {
|
|
|
40
70
|
|
|
41
71
|
Usage:
|
|
42
72
|
bizar audit
|
|
43
|
-
|
|
44
|
-
Description:
|
|
45
|
-
Scans opencode agent definitions for security issues:
|
|
46
|
-
- Agents with read/edit/bash permission conflicts
|
|
47
|
-
- Agents lacking mode or model definitions
|
|
48
|
-
- Suspicious tool access patterns
|
|
49
73
|
`);
|
|
50
74
|
}
|
|
51
75
|
|
|
52
76
|
function showInitHelp() {
|
|
53
77
|
console.log(`
|
|
54
78
|
bizar init — Initialize .bizar/ in current project
|
|
55
|
-
|
|
56
|
-
Usage:
|
|
57
|
-
bizar init
|
|
58
|
-
|
|
59
|
-
Description:
|
|
60
|
-
Creates a .bizar/ directory in the current project with:
|
|
61
|
-
- PROJECT.md (living project description)
|
|
62
|
-
- AGENTS_SELF_IMPROVEMENT.md (lesson log)
|
|
63
79
|
`);
|
|
64
80
|
}
|
|
65
81
|
|
|
66
82
|
function showExportHelp() {
|
|
67
83
|
console.log(`
|
|
68
84
|
bizar export — Export agents/rules to another harness
|
|
69
|
-
|
|
70
|
-
Usage:
|
|
71
|
-
bizar export --target <harness>
|
|
72
|
-
|
|
73
|
-
Targets:
|
|
74
|
-
claude Export to Claude Code format
|
|
75
|
-
cursor Export to Cursor format
|
|
76
|
-
opencode Export to OpenCode format (default)
|
|
77
|
-
|
|
78
|
-
Description:
|
|
79
|
-
Converts Bizar agent definitions and rules
|
|
80
|
-
to the target harness's native format.
|
|
81
85
|
`);
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
function showTestGateHelp() {
|
|
85
89
|
console.log(`
|
|
86
90
|
bizar test-gate — Detect & run the project's test suite
|
|
91
|
+
`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function showServiceHelp() {
|
|
95
|
+
console.log(`
|
|
96
|
+
bizar service — Manage the background service daemon
|
|
87
97
|
|
|
88
98
|
Usage:
|
|
89
|
-
bizar
|
|
99
|
+
bizar service start Start the service in background
|
|
100
|
+
bizar service stop Stop the running service
|
|
101
|
+
bizar service status Show whether the service is running
|
|
102
|
+
bizar service logs Tail the service log
|
|
90
103
|
|
|
91
104
|
Description:
|
|
92
|
-
|
|
93
|
-
|
|
105
|
+
The service watches per-project schedules (cron / interval / once)
|
|
106
|
+
and runs them at the right time. It logs to
|
|
107
|
+
~/.config/bizar/service.log and writes its PID to
|
|
108
|
+
~/.config/bizar/service.pid.
|
|
94
109
|
`);
|
|
95
110
|
}
|
|
96
111
|
|
|
97
112
|
function showDashboardHelp() {
|
|
98
113
|
console.log(`
|
|
99
|
-
bizar dashboard — Launch
|
|
114
|
+
bizar dashboard — Launch the web dashboard (uses @polderlabs/bizar-dash)
|
|
100
115
|
|
|
101
116
|
Usage:
|
|
102
|
-
bizar dashboard Start the dashboard
|
|
103
|
-
bizar dashboard start
|
|
104
|
-
bizar dashboard stop Kill the running dashboard
|
|
105
|
-
bizar dashboard status
|
|
117
|
+
bizar dashboard Start the dashboard
|
|
118
|
+
bizar dashboard start Same
|
|
119
|
+
bizar dashboard stop Kill the running dashboard
|
|
120
|
+
bizar dashboard status Show port + URL
|
|
106
121
|
|
|
107
122
|
Description:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
file-change events from config/, agents/, commands-bizar/, .bizar/,
|
|
111
|
-
and plans/. The server binds loopback only — never expose it.
|
|
123
|
+
The dashboard lives in a separate package. If it's not installed,
|
|
124
|
+
you'll see an install hint pointing at @polderlabs/bizar-dash.
|
|
112
125
|
`);
|
|
113
126
|
}
|
|
114
127
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
console.log('No Bizar dashboard is running. Use: bizar dashboard start');
|
|
129
|
-
}
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (sub === 'stop') {
|
|
134
|
-
if (!existsSync(PID_FILE)) {
|
|
135
|
-
console.log('No Bizar dashboard is running.');
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const pid = parseInt(readFileSync(PID_FILE, 'utf8').trim(), 10);
|
|
139
|
-
if (!Number.isFinite(pid)) {
|
|
140
|
-
console.log(`Bad PID file: ${PID_FILE}`);
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
try {
|
|
144
|
-
process.kill(pid, 'SIGTERM');
|
|
145
|
-
console.log(`Stopped Bizar dashboard (pid ${pid}).`);
|
|
146
|
-
} catch (err) {
|
|
147
|
-
console.log(`Could not stop dashboard (pid ${pid}): ${err.message}`);
|
|
148
|
-
}
|
|
149
|
-
try { unlinkSync(PORT_FILE); } catch { /* ignore */ }
|
|
150
|
-
try { unlinkSync(PID_FILE); } catch { /* ignore */ }
|
|
151
|
-
return;
|
|
128
|
+
/**
|
|
129
|
+
* Detect whether @polderlabs/bizar-dash is installed locally.
|
|
130
|
+
* We probe the global npm root, but also look in the local node_modules
|
|
131
|
+
* of the bizar package itself.
|
|
132
|
+
*/
|
|
133
|
+
async function findBizarDash() {
|
|
134
|
+
const { execSync } = await import('node:child_process');
|
|
135
|
+
try {
|
|
136
|
+
const root = execSync('npm root -g', { encoding: 'utf8', timeout: 5000 }).trim();
|
|
137
|
+
const dashPath = join(root, '@polderlabs', 'bizar-dash', 'src', 'cli.mjs');
|
|
138
|
+
if (existsSync(dashPath)) return dashPath;
|
|
139
|
+
} catch {
|
|
140
|
+
/* fall through */
|
|
152
141
|
}
|
|
142
|
+
// Local fallback — node_modules of this package
|
|
143
|
+
const here = new URL('..', import.meta.url);
|
|
144
|
+
const localPath = join(here.pathname, '..', 'node_modules', '@polderlabs', 'bizar-dash', 'src', 'cli.mjs');
|
|
145
|
+
if (existsSync(localPath)) return localPath;
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
153
148
|
|
|
154
|
-
|
|
155
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Delegate a subcommand to the bizar-dash CLI, if installed.
|
|
151
|
+
*/
|
|
152
|
+
async function delegateToDash(argsForDash) {
|
|
153
|
+
const dashPath = await findBizarDash();
|
|
154
|
+
if (!dashPath) {
|
|
155
|
+
console.log('The Bizar dashboard lives in a separate package.');
|
|
156
|
+
console.log('Install it with:');
|
|
157
|
+
console.log(chalk.cyan(' npm install -g @polderlabs/bizar-dash'));
|
|
156
158
|
return;
|
|
157
159
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
160
|
+
const { spawn } = await import('node:child_process');
|
|
161
|
+
const child = spawn(process.execPath, [dashPath, ...argsForDash], {
|
|
162
|
+
stdio: 'inherit',
|
|
163
|
+
cwd: process.cwd(),
|
|
164
|
+
env: process.env,
|
|
165
|
+
});
|
|
166
|
+
await new Promise((resolve, reject) => {
|
|
167
|
+
child.on('exit', (code) => (code === 0 ? resolve() : reject(new Error(`exit ${code}`))));
|
|
168
|
+
child.on('error', reject);
|
|
169
|
+
});
|
|
164
170
|
}
|
|
165
171
|
|
|
166
|
-
function
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
bizar update Interactive: ask which components to update
|
|
172
|
-
bizar update --all Update everything non-interactively
|
|
173
|
-
bizar update opencode Update only opencode
|
|
174
|
-
bizar update bizar Update only the bizar CLI package
|
|
175
|
-
bizar update plugin Update only the @polderlabs/bizar-plugin package
|
|
176
|
-
|
|
177
|
-
Description:
|
|
178
|
-
By default, prompts for each component (opencode, @polderlabs/bizar,
|
|
179
|
-
@polderlabs/bizar-plugin) before running its update. With --all, runs
|
|
180
|
-
every update without prompting. With explicit subcommands, runs only
|
|
181
|
-
the named update.
|
|
172
|
+
function parseFlag(name) {
|
|
173
|
+
const idx = args.indexOf(name);
|
|
174
|
+
if (idx === -1) return null;
|
|
175
|
+
return args[idx + 1] || null;
|
|
176
|
+
}
|
|
182
177
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
178
|
+
async function readAutoLaunchWeb() {
|
|
179
|
+
try {
|
|
180
|
+
const fs = await import('node:fs');
|
|
181
|
+
const os = await import('node:os');
|
|
182
|
+
const path = await import('node:path');
|
|
183
|
+
const file = path.join(os.homedir(), '.config', 'bizar', 'settings.json');
|
|
184
|
+
if (!fs.existsSync(file)) return true;
|
|
185
|
+
const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
186
|
+
if (parsed && parsed.dashboard && typeof parsed.dashboard.autoLaunchWeb === 'boolean') {
|
|
187
|
+
return parsed.dashboard.autoLaunchWeb;
|
|
188
|
+
}
|
|
189
|
+
} catch {
|
|
190
|
+
/* fall through */
|
|
191
|
+
}
|
|
192
|
+
return true;
|
|
188
193
|
}
|
|
189
194
|
|
|
190
195
|
async function runTestGate() {
|
|
191
196
|
console.log(chalk.bold.hex('#a855f7')('\n ᚦ TEST GATE ᚦ\n'));
|
|
192
197
|
const { execSync } = await import('node:child_process');
|
|
193
|
-
|
|
194
198
|
const cwd = process.cwd();
|
|
195
199
|
const possible = [
|
|
196
200
|
{ cmd: 'npm test', check: 'package.json' },
|
|
@@ -198,7 +202,6 @@ async function runTestGate() {
|
|
|
198
202
|
{ cmd: 'cargo test', check: 'Cargo.toml' },
|
|
199
203
|
{ cmd: 'go test ./...', check: 'go.mod' },
|
|
200
204
|
];
|
|
201
|
-
|
|
202
205
|
for (const suite of possible) {
|
|
203
206
|
try {
|
|
204
207
|
if (existsSync(join(cwd, suite.check))) {
|
|
@@ -212,18 +215,21 @@ async function runTestGate() {
|
|
|
212
215
|
process.exit(1);
|
|
213
216
|
}
|
|
214
217
|
}
|
|
215
|
-
|
|
216
218
|
console.log(' No test suite detected. Install one to use the test gate.\n');
|
|
217
219
|
return false;
|
|
218
220
|
}
|
|
219
221
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
222
|
+
/**
|
|
223
|
+
* Service commands — start / stop / status / logs.
|
|
224
|
+
*
|
|
225
|
+
* Implementation lives in cli/service.mjs (created below).
|
|
226
|
+
*/
|
|
227
|
+
async function runServiceCommand(sub) {
|
|
228
|
+
const { runService } = await import('./service.mjs');
|
|
229
|
+
await runService(sub || 'status', args.slice(2));
|
|
224
230
|
}
|
|
225
231
|
|
|
226
|
-
if (args
|
|
232
|
+
if (args[0] === '--postinstall') {
|
|
227
233
|
await runPostInstall();
|
|
228
234
|
} else if (args[0] === 'audit') {
|
|
229
235
|
if (args.includes('--help') || args.includes('-h')) showAuditHelp();
|
|
@@ -233,27 +239,49 @@ if (args.includes('--postinstall')) {
|
|
|
233
239
|
else await runInit(process.cwd());
|
|
234
240
|
} else if (args[0] === 'export') {
|
|
235
241
|
if (args.includes('--help') || args.includes('-h')) showExportHelp();
|
|
236
|
-
else
|
|
237
|
-
const target = parseFlag('--target');
|
|
238
|
-
await runExport(target);
|
|
239
|
-
}
|
|
242
|
+
else await runExport(parseFlag('--target'));
|
|
240
243
|
} else if (args[0] === 'test-gate') {
|
|
241
244
|
if (args.includes('--help') || args.includes('-h')) showTestGateHelp();
|
|
242
245
|
else await runTestGate();
|
|
243
246
|
} else if (args[0] === 'update') {
|
|
244
247
|
if (args.includes('--help') || args.includes('-h')) {
|
|
245
|
-
|
|
248
|
+
console.log('Run bizar update [opencode|bizar|plugin]');
|
|
246
249
|
} else {
|
|
247
250
|
await runUpdate(args.slice(1));
|
|
248
251
|
}
|
|
249
252
|
} else if (args[0] === 'plan') {
|
|
250
|
-
|
|
251
|
-
|
|
253
|
+
await runPlan(args.slice(1), {});
|
|
254
|
+
} else if (args[0] === 'install') {
|
|
255
|
+
await runInstaller();
|
|
256
|
+
} else if (args[0] === 'service') {
|
|
257
|
+
if (args.includes('--help') || args.includes('-h')) showServiceHelp();
|
|
258
|
+
else await runServiceCommand(args[1]);
|
|
252
259
|
} else if (args[0] === 'dashboard') {
|
|
253
260
|
if (args.includes('--help') || args.includes('-h')) showDashboardHelp();
|
|
254
|
-
else await
|
|
261
|
+
else await delegateToDash(args.slice(1));
|
|
262
|
+
} else if (args.includes('--bg') || args.includes('--detach')) {
|
|
263
|
+
// Delegate to bizarre-dash
|
|
264
|
+
await delegateToDash(['--bg']);
|
|
265
|
+
} else if (args.includes('--web-only')) {
|
|
266
|
+
await delegateToDash(['--web-only']);
|
|
255
267
|
} else if (args.includes('--help') || args.includes('-h')) {
|
|
256
268
|
showHelp();
|
|
257
269
|
} else {
|
|
258
|
-
|
|
270
|
+
// Default: launch the TUI dashboard. The TUI lives in bizar-dash.
|
|
271
|
+
// We try to use the bizar-dash package's TUI, but we also support a
|
|
272
|
+
// bundled fallback that imports from this package's local copy.
|
|
273
|
+
const dashPath = await findBizarDash();
|
|
274
|
+
if (dashPath) {
|
|
275
|
+
const skipWeb = args.includes('--no-web');
|
|
276
|
+
const forceWeb = args.includes('--web');
|
|
277
|
+
const settingAuto = await readAutoLaunchWeb();
|
|
278
|
+
const launchWeb = !skipWeb && (forceWeb || settingAuto);
|
|
279
|
+
await delegateToDash(['tui', ...(launchWeb ? [] : ['--no-web'])]);
|
|
280
|
+
} else {
|
|
281
|
+
console.log('The Bizar dashboard is in a separate package:');
|
|
282
|
+
console.log(chalk.cyan(' npm install -g @polderlabs/bizar-dash'));
|
|
283
|
+
console.log('');
|
|
284
|
+
console.log('Or run the installer to set up everything:');
|
|
285
|
+
console.log(chalk.cyan(' npx -y @polderlabs/bizar install'));
|
|
286
|
+
}
|
|
259
287
|
}
|