@polderlabs/bizar 10.6.0 → 10.7.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.
Files changed (109) hide show
  1. package/bizar-dash/tests/memory-protocol-drift.test.mjs +18 -11
  2. package/cli/__tests__/feature-list-bridge.test.mjs +42 -42
  3. package/cli/agent-browser-up.sh +35 -35
  4. package/cli/agent-browser-update.mjs +42 -42
  5. package/cli/agent-browser-update.test.mjs +7 -7
  6. package/cli/audit.mjs +3 -3
  7. package/cli/bin.mjs +10 -10
  8. package/cli/bootstrap.mjs +1 -1
  9. package/cli/cli-commands-validation.test.mjs +2 -2
  10. package/cli/commands/claim.mjs +3 -3
  11. package/cli/commands/claude-cmd.mjs +3 -3
  12. package/cli/commands/eval.mjs +6 -6
  13. package/cli/commands/util.mjs +18 -18
  14. package/cli/commands/validate.mjs +10 -10
  15. package/cli/init.mjs +1 -1
  16. package/cli/install/postinstall.mjs +4 -4
  17. package/cli/plow-through.test.mjs +7 -6
  18. package/cli/prompts.mjs +11 -11
  19. package/cli/provision.mjs +4 -16
  20. package/config/skills/bizar/SKILL.md +1 -1
  21. package/config/skills/skillopt/SKILL.md +129 -0
  22. package/config/skills/thinking-archetypes/SKILL.md +90 -0
  23. package/config/skills/thinking-bayesian/SKILL.md +267 -0
  24. package/config/skills/thinking-bounded-rationality/SKILL.md +406 -0
  25. package/config/skills/thinking-circle-of-competence/SKILL.md +216 -0
  26. package/config/skills/thinking-cynefin/SKILL.md +70 -0
  27. package/config/skills/thinking-debiasing/SKILL.md +192 -0
  28. package/config/skills/thinking-dual-process/SKILL.md +282 -0
  29. package/config/skills/thinking-effectuation/SKILL.md +366 -0
  30. package/config/skills/thinking-feedback-loops/SKILL.md +464 -0
  31. package/config/skills/thinking-fermi-estimation/SKILL.md +263 -0
  32. package/config/skills/thinking-first-principles/SKILL.md +167 -0
  33. package/config/skills/thinking-five-whys-plus/SKILL.md +139 -0
  34. package/config/skills/thinking-inversion/SKILL.md +195 -0
  35. package/config/skills/thinking-jobs-to-be-done/SKILL.md +363 -0
  36. package/config/skills/thinking-kepner-tregoe/SKILL.md +154 -0
  37. package/config/skills/thinking-leverage-points/SKILL.md +390 -0
  38. package/config/skills/thinking-lindy-effect/SKILL.md +331 -0
  39. package/config/skills/thinking-map-territory/SKILL.md +111 -0
  40. package/config/skills/thinking-margin-of-safety/SKILL.md +330 -0
  41. package/config/skills/thinking-model-combination/SKILL.md +406 -0
  42. package/config/skills/thinking-model-router/SKILL.md +360 -0
  43. package/config/skills/thinking-model-selection/SKILL.md +341 -0
  44. package/config/skills/thinking-occams-razor/SKILL.md +129 -0
  45. package/config/skills/thinking-ooda/SKILL.md +127 -0
  46. package/config/skills/thinking-opportunity-cost/SKILL.md +360 -0
  47. package/config/skills/thinking-pre-mortem/SKILL.md +170 -0
  48. package/config/skills/thinking-probabilistic/SKILL.md +324 -0
  49. package/config/skills/thinking-red-team/SKILL.md +142 -0
  50. package/config/skills/thinking-regret-minimization/SKILL.md +335 -0
  51. package/config/skills/thinking-reversibility/SKILL.md +326 -0
  52. package/config/skills/thinking-scientific-method/SKILL.md +162 -0
  53. package/config/skills/thinking-second-order/SKILL.md +184 -0
  54. package/config/skills/thinking-socratic/SKILL.md +198 -0
  55. package/config/skills/thinking-steel-manning/SKILL.md +332 -0
  56. package/config/skills/thinking-systems/SKILL.md +238 -0
  57. package/config/skills/thinking-theory-of-constraints/SKILL.md +338 -0
  58. package/config/skills/thinking-thought-experiment/SKILL.md +354 -0
  59. package/config/skills/thinking-triz/SKILL.md +171 -0
  60. package/config/skills/thinking-via-negativa/SKILL.md +358 -0
  61. package/package.json +2 -3
  62. package/packages/sdk/dist/consensus/index.js +4 -4
  63. package/packages/sdk/dist/router/agent-model-registry.js +2 -2
  64. package/packages/sdk/dist/router/index.d.ts +3 -3
  65. package/packages/sdk/dist/router/index.js +4 -4
  66. package/packages/sdk/dist/router/q-learning-router.d.ts +2 -2
  67. package/packages/sdk/dist/router/q-learning-router.js +18 -18
  68. package/scripts/bh-full-e2e.mjs +10 -8
  69. package/scripts/check-agents.mjs +27 -24
  70. package/scripts/mirror-claude-md.sh +0 -0
  71. package/scripts/sync-skills-mirror.mjs +113 -0
  72. package/scripts/verify-thinking-skills.mjs +135 -0
  73. package/config/agents/_shared/AGENT_BASELINE.md +0 -155
  74. package/config/agents/_shared/CLINE_TOOLS.md +0 -398
  75. package/config/agents/_shared/SKILLS.md +0 -109
  76. package/config/agents/agent-browser.md +0 -90
  77. package/config/agents/baldr.md +0 -60
  78. package/config/agents/forseti.md +0 -60
  79. package/config/agents/frigg.md +0 -52
  80. package/config/agents/heimdall.md +0 -44
  81. package/config/agents/hermod.md +0 -64
  82. package/config/agents/mimir.md +0 -60
  83. package/config/agents/odin.md +0 -310
  84. package/config/agents/quick.md +0 -47
  85. package/config/agents/semble-search.md +0 -59
  86. package/config/agents/thor.md +0 -64
  87. package/config/agents/tyr.md +0 -67
  88. package/config/agents/vidarr.md +0 -65
  89. package/config/agents/vor.md +0 -62
  90. package/config/commands/audit.md +0 -5
  91. package/config/commands/bizar.md +0 -22
  92. package/config/commands/explain.md +0 -5
  93. package/config/commands/init.md +0 -26
  94. package/config/commands/learn.md +0 -5
  95. package/config/commands/plan.md +0 -30
  96. package/config/commands/plow-through.md +0 -47
  97. package/config/commands/pr-review.md +0 -5
  98. package/config/commands/setup-provider.md +0 -95
  99. package/config/commands/tailscale-serve.md +0 -97
  100. package/config/commands/team.md +0 -124
  101. package/config/commands/test.md +0 -60
  102. package/config/commands/validate.md +0 -66
  103. package/config/commands/visual-plan.md +0 -19
  104. package/config/hooks/PostToolUse +0 -66
  105. package/config/hooks/PreToolUse +0 -82
  106. package/config/hooks/README.md +0 -68
  107. package/config/hooks/TaskResume +0 -48
  108. package/config/hooks/TaskStart +0 -47
  109. package/config/hooks/UserPromptSubmit +0 -55
@@ -1,22 +1,22 @@
1
1
  /**
2
- * cli/agent-browser-update.mjs
2
+ * cli/kevin-update.mjs
3
3
  *
4
- * v6.0.0 — Install / update / verify the `agent-browser` CLI.
4
+ * v6.0.0 — Install / update / verify the `kevin` CLI.
5
5
  *
6
- * `agent-browser` is a native Rust CLI from vercel-labs (~38K★) that
6
+ * `kevin` is a native Rust CLI from vercel-labs (~38K★) that
7
7
  * gives Bizar agents a complete browser-automation surface:
8
8
  * - 100+ typed CLI commands (open, snapshot, click, fill, screenshot, ...)
9
- * - Native MCP stdio server (`agent-browser mcp`)
9
+ * - Native MCP stdio server (`kevin mcp`)
10
10
  * - Self-healing snapshot-based element refs (`@e2`)
11
11
  * - Plugin system (vault, recorder, ...)
12
12
  * - Vercel AI SDK + AI Gateway integration
13
13
  *
14
14
  * This module is the single source of truth for installing and
15
- * updating `agent-browser`. It is used by:
15
+ * updating `kevin`. It is used by:
16
16
  * - cli/install.mjs (during `bizar install`)
17
17
  * - cli/provision.mjs (during `bizar update`)
18
- * - cli/agent-browser-up.sh (the bash idempotent starter; on first
19
- * run it shells to `npm install -g agent-browser` if the binary
18
+ * - cli/kevin-up.sh (the bash idempotent starter; on first
19
+ * run it shells to `npm install -g kevin` if the binary
20
20
  * is missing — this module is the rich equivalent)
21
21
  *
22
22
  * Public API:
@@ -36,12 +36,12 @@ import { homedir } from 'node:os';
36
36
  import chalk from 'chalk';
37
37
 
38
38
  const DEFAULT_DAEMON_PORT = 9223;
39
- const DEFAULT_PROFILE_DIR = join(homedir(), '.agent-browser', 'profile');
39
+ const DEFAULT_PROFILE_DIR = join(homedir(), '.kevin', 'profile');
40
40
 
41
41
  // ── detection ──────────────────────────────────────────────────────────
42
42
 
43
43
  /**
44
- * Probe the current agent-browser install without modifying anything.
44
+ * Probe the current kevin install without modifying anything.
45
45
  *
46
46
  * Returns a structured state object:
47
47
  * {
@@ -79,7 +79,7 @@ export function detectState() {
79
79
  }
80
80
 
81
81
  // 3. Check Chrome for Testing
82
- const chromeDir = join(homedir(), '.cache', 'agent-browser', 'chrome');
82
+ const chromeDir = join(homedir(), '.cache', 'kevin', 'chrome');
83
83
  if (existsSync(chromeDir)) state.chromeReady = true;
84
84
 
85
85
  // 4. Check daemon (read env on every call so tests can override)
@@ -97,17 +97,17 @@ function findAgentBrowserBin() {
97
97
  }
98
98
  // 2. Well-known npm-global locations
99
99
  const candidates = [
100
- '/usr/local/bin/agent-browser',
101
- '/opt/homebrew/bin/agent-browser',
102
- join(homedir(), '.local', 'bin', 'agent-browser'),
103
- join(homedir(), '.npm', 'bin', 'agent-browser'),
100
+ '/usr/local/bin/kevin',
101
+ '/opt/homebrew/bin/kevin',
102
+ join(homedir(), '.local', 'bin', 'kevin'),
103
+ join(homedir(), '.npm', 'bin', 'kevin'),
104
104
  ];
105
105
  for (const c of candidates) {
106
106
  if (existsSync(c)) return c;
107
107
  }
108
108
  // 3. PATH lookup
109
109
  try {
110
- const r = execSync('command -v agent-browser', { encoding: 'utf8', timeout: 2_000 }).trim();
110
+ const r = execSync('command -v kevin', { encoding: 'utf8', timeout: 2_000 }).trim();
111
111
  if (r && existsSync(r)) return r;
112
112
  } catch {
113
113
  // fall through
@@ -130,7 +130,7 @@ function isDaemonUp(port) {
130
130
  // ── install / update ───────────────────────────────────────────────────
131
131
 
132
132
  /**
133
- * Install agent-browser. Idempotent: skips steps that are already
133
+ * Install kevin. Idempotent: skips steps that are already
134
134
  * complete. Returns the updated state.
135
135
  *
136
136
  * @param {object} opts
@@ -145,7 +145,7 @@ export function install(opts = {}) {
145
145
 
146
146
  const before = detectState();
147
147
  if (before.installed) {
148
- log(`agent-browser ${before.version} already installed at ${before.bin}`);
148
+ log(`kevin ${before.version} already installed at ${before.bin}`);
149
149
  if (startDaemon && !before.daemonRunning) {
150
150
  log('daemon is down — bringing it up');
151
151
  ensureRunning({ silent, dryRun });
@@ -153,28 +153,28 @@ export function install(opts = {}) {
153
153
  return detectState();
154
154
  }
155
155
 
156
- log(`Installing agent-browser from npm (channel: ${channel})...`);
156
+ log(`Installing kevin from npm (channel: ${channel})...`);
157
157
  if (dryRun) {
158
- log(`[DRY RUN] would run: npm install -g agent-browser@${channel}`);
158
+ log(`[DRY RUN] would run: npm install -g kevin@${channel}`);
159
159
  // In dry-run, the binary may not be on PATH. Just return the
160
160
  // current state (which includes installed=false) without checking
161
161
  // for the after-install state.
162
162
  return detectState();
163
163
  } else {
164
- const r = spawnSync('npm', ['install', '-g', `agent-browser@${channel}`], {
164
+ const r = spawnSync('npm', ['install', '-g', `kevin@${channel}`], {
165
165
  stdio: silent ? 'ignore' : 'inherit',
166
166
  timeout: 180_000,
167
167
  });
168
168
  if (r.status !== 0) {
169
- throw new Error(`npm install -g agent-browser@${channel} failed (exit ${r.status})`);
169
+ throw new Error(`npm install -g kevin@${channel} failed (exit ${r.status})`);
170
170
  }
171
171
  }
172
172
 
173
173
  const after = detectState();
174
174
  if (!after.installed) {
175
- throw new Error('agent-browser still not on PATH after install');
175
+ throw new Error('kevin still not on PATH after install');
176
176
  }
177
- log(`agent-browser ${after.version} installed`);
177
+ log(`kevin ${after.version} installed`);
178
178
 
179
179
  log('Downloading Chrome for Testing...');
180
180
  if (!dryRun) {
@@ -183,7 +183,7 @@ export function install(opts = {}) {
183
183
  timeout: 300_000,
184
184
  });
185
185
  if (r.status !== 0) {
186
- log(chalk.yellow('Chrome download failed — you can retry with `agent-browser install`'));
186
+ log(chalk.yellow('Chrome download failed — you can retry with `kevin install`'));
187
187
  }
188
188
  }
189
189
 
@@ -194,9 +194,9 @@ export function install(opts = {}) {
194
194
  }
195
195
 
196
196
  /**
197
- * Update agent-browser to the latest version. Idempotent.
197
+ * Update kevin to the latest version. Idempotent.
198
198
  *
199
- * Same shape as install() but uses `agent-browser upgrade` after the
199
+ * Same shape as install() but uses `kevin upgrade` after the
200
200
  * first install (which knows how to detect the install method and run
201
201
  * the right update command).
202
202
  */
@@ -206,38 +206,38 @@ export function update(opts = {}) {
206
206
 
207
207
  const before = detectState();
208
208
  if (!before.installed) {
209
- log('agent-browser not installed — calling install()');
209
+ log('kevin not installed — calling install()');
210
210
  return install(opts);
211
211
  }
212
212
 
213
- log(`agent-browser ${before.version} is installed. Upgrading to ${channel}...`);
213
+ log(`kevin ${before.version} is installed. Upgrading to ${channel}...`);
214
214
  if (dryRun) {
215
- log(`[DRY RUN] would run: agent-browser upgrade`);
215
+ log(`[DRY RUN] would run: kevin upgrade`);
216
216
  return detectState();
217
217
  } else {
218
- // First, try `agent-browser upgrade` (the self-updater). If it
218
+ // First, try `kevin upgrade` (the self-updater). If it
219
219
  // doesn't exist (older version), fall back to `npm update -g`.
220
220
  const r = spawnSync(before.bin, ['upgrade'], {
221
221
  stdio: silent ? 'ignore' : 'inherit',
222
222
  timeout: 180_000,
223
223
  });
224
224
  if (r.status !== 0) {
225
- log('`agent-browser upgrade` failed — falling back to `npm update -g`');
226
- const r2 = spawnSync('npm', ['update', '-g', `agent-browser@${channel}`], {
225
+ log('`kevin upgrade` failed — falling back to `npm update -g`');
226
+ const r2 = spawnSync('npm', ['update', '-g', `kevin@${channel}`], {
227
227
  stdio: silent ? 'ignore' : 'inherit',
228
228
  timeout: 180_000,
229
229
  });
230
230
  if (r2.status !== 0) {
231
- throw new Error(`npm update -g agent-browser@${channel} failed (exit ${r2.status})`);
231
+ throw new Error(`npm update -g kevin@${channel} failed (exit ${r2.status})`);
232
232
  }
233
233
  }
234
234
  }
235
235
 
236
236
  const after = detectState();
237
237
  if (after.version === before.version) {
238
- log(`agent-browser already at latest (${after.version})`);
238
+ log(`kevin already at latest (${after.version})`);
239
239
  } else {
240
- log(`agent-browser updated: ${before.version} → ${after.version}`);
240
+ log(`kevin updated: ${before.version} → ${after.version}`);
241
241
  }
242
242
 
243
243
  if (startDaemon && !after.daemonRunning) {
@@ -249,10 +249,10 @@ export function update(opts = {}) {
249
249
  // ── daemon management ──────────────────────────────────────────────────
250
250
 
251
251
  /**
252
- * Bring the agent-browser daemon up if it's down. Idempotent.
252
+ * Bring the kevin daemon up if it's down. Idempotent.
253
253
  *
254
254
  * On macOS, Linux, and Windows, the daemon is started as a background
255
- * process using `agent-browser serve`. On success, the daemon listens
255
+ * process using `kevin serve`. On success, the daemon listens
256
256
  * on `http://127.0.0.1:<port>` and is reachable via the typed CLI
257
257
  * and the MCP stdio server.
258
258
  */
@@ -262,7 +262,7 @@ export function ensureRunning(opts = {}) {
262
262
 
263
263
  const state = detectState();
264
264
  if (!state.installed) {
265
- log('agent-browser is not installed — call install() first');
265
+ log('kevin is not installed — call install() first');
266
266
  return state;
267
267
  }
268
268
  if (state.daemonRunning) {
@@ -297,7 +297,7 @@ export function ensureRunning(opts = {}) {
297
297
  }
298
298
  spawnSync('sleep', ['0.1']);
299
299
  }
300
- log(chalk.yellow('daemon did not bind within 5s — check `agent-browser doctor`'));
300
+ log(chalk.yellow('daemon did not bind within 5s — check `kevin doctor`'));
301
301
  return detectState();
302
302
  }
303
303
 
@@ -309,14 +309,14 @@ export function ensureRunning(opts = {}) {
309
309
  export function printStatus() {
310
310
  const s = detectState();
311
311
  if (!s.installed) {
312
- console.log(chalk.yellow(' agent-browser: NOT INSTALLED'));
313
- console.log(chalk.dim(' Install with: npm install -g agent-browser && agent-browser install'));
312
+ console.log(chalk.yellow(' kevin: NOT INSTALLED'));
313
+ console.log(chalk.dim(' Install with: npm install -g kevin && kevin install'));
314
314
  } else {
315
315
  const daemonTxt = s.daemonRunning
316
316
  ? chalk.green('running')
317
317
  : chalk.yellow('stopped');
318
318
  const chromeTxt = s.chromeReady ? chalk.green('ready') : chalk.yellow('not installed');
319
- console.log(` agent-browser ${chalk.cyan(s.version)} · daemon: ${daemonTxt} (port ${s.daemonPort}) · chrome: ${chromeTxt}`);
319
+ console.log(` kevin ${chalk.cyan(s.version)} · daemon: ${daemonTxt} (port ${s.daemonPort}) · chrome: ${chromeTxt}`);
320
320
  }
321
321
  return s;
322
322
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
- * cli/agent-browser-update.test.mjs
2
+ * cli/kevin-update.test.mjs
3
3
  *
4
- * Unit tests for the v6.0.0 agent-browser install/update module.
4
+ * Unit tests for the v6.0.0 kevin install/update module.
5
5
  * Uses node:test (no `expect` — uses `assert` instead).
6
6
  */
7
7
 
@@ -14,9 +14,9 @@ const {
14
14
  install,
15
15
  update,
16
16
  ensureRunning,
17
- } = await import("./agent-browser-update.mjs");
17
+ } = await import("./kevin-update.mjs");
18
18
 
19
- describe("agent-browser-update", () => {
19
+ describe("kevin-update", () => {
20
20
  it("exports the public API", () => {
21
21
  assert.equal(typeof detectState, "function");
22
22
  assert.equal(typeof printStatus, "function");
@@ -42,9 +42,9 @@ describe("agent-browser-update", () => {
42
42
  }
43
43
  });
44
44
 
45
- it("detectState profileDir points to ~/.agent-browser/profile by default", () => {
45
+ it("detectState profileDir points to ~/.kevin/profile by default", () => {
46
46
  const s = detectState();
47
- assert.match(s.profileDir, /\.agent-browser\/profile$/);
47
+ assert.match(s.profileDir, /\.kevin\/profile$/);
48
48
  });
49
49
 
50
50
  it("detectState default daemon port is 9223", () => {
@@ -63,7 +63,7 @@ describe("agent-browser-update", () => {
63
63
  console.log = origLog;
64
64
  }
65
65
  assert.ok(captured.length > 0);
66
- assert.match(captured[0], /agent-browser/);
66
+ assert.match(captured[0], /kevin/);
67
67
  });
68
68
 
69
69
  it("install with dryRun=true returns a state object", () => {
package/cli/audit.mjs CHANGED
@@ -28,7 +28,7 @@ export async function runAudit() {
28
28
  const lines = content.split('\n');
29
29
 
30
30
  // Check 1: Dangerous bash permissions on review-only agents
31
- if (file.includes('forseti') || file.includes('semble-search')) {
31
+ if (file.includes('linda') || file.includes('oscar')) {
32
32
  if (content.includes('bash: allow')) {
33
33
  issues.push({ path, severity: 'HIGH', msg: 'Review-only agent has bash permission' });
34
34
  }
@@ -38,7 +38,7 @@ export async function runAudit() {
38
38
  }
39
39
 
40
40
  // Check 2: Frigg should never have edit/write
41
- if (file.includes('frigg')) {
41
+ if (file.includes('susan')) {
42
42
  if (content.includes('edit: allow')) {
43
43
  issues.push({ path, severity: 'HIGH', msg: 'Read-only Q&A agent (Frigg) has edit permission' });
44
44
  }
@@ -48,7 +48,7 @@ export async function runAudit() {
48
48
  }
49
49
 
50
50
  // Check 3: Odin should have minimal permissions
51
- if (file.includes('odin')) {
51
+ if (file.includes('mike')) {
52
52
  const dangerousForOdin = ['bash', 'edit', 'write', 'glob', 'grep', 'question'];
53
53
  for (const tool of dangerousForOdin) {
54
54
  if (content.includes(`${tool}: allow`)) {
package/cli/bin.mjs CHANGED
@@ -13,7 +13,7 @@
13
13
  * Commands:
14
14
  * install, audit, init, export, artifact, update, test-gate, service, dash,
15
15
  * memory, minimax, usage, mod, doctor, repair, dev-link, dev-unlink,
16
- * heads-up, bg, agent-browser, agent-browser-up, providers, deploy, plugin,
16
+ * heads-up, bg, kevin, kevin-up, providers, deploy, plugin,
17
17
  * marketplace, plan, digest, backup, restore, clip, ocr, voice, workspace, eval
18
18
  */
19
19
  import chalk from 'chalk';
@@ -148,8 +148,8 @@ function showHelp() {
148
148
  deploy One-click deploy to Vercel, Cloudflare, Fly.io, or Docker
149
149
  plugin <subcommand> Manage marketplace plugins (search/install/config/invoke)
150
150
  marketplace <subcommand> Browse and install plugins from the public marketplace
151
- agent-browser Install / update / verify the agent-browser CLI
152
- agent-browser-up Start Chromium for agent-browser (start/stop/status)
151
+ kevin Install / update / verify the kevin CLI
152
+ kevin-up Start Chromium for kevin (start/stop/status)
153
153
  providers detect Auto-detect provider API keys from env + ~/.claude/settings.json
154
154
  clip <subcommand> Manage web clipper saved clips (list/delete/configure)
155
155
  ocr <subcommand> OCR operations on images (list/process/configure)
@@ -245,21 +245,21 @@ async function main() {
245
245
  const UTIL_COMMANDS = new Set([
246
246
  'audit', 'init', 'export', 'test-gate', 'dev-link', 'dev-unlink',
247
247
  'doctor', 'repair', 'heads-up', 'bg', 'digest', 'backup', 'restore',
248
- 'agent-browser', 'update', 'providers', 'plan', 'validate',
248
+ 'kevin', 'update', 'providers', 'plan', 'validate',
249
249
  'setup-provider', 'config', 'history', 'hub', 'hook',
250
250
  'team', 'subagent', 'rca',
251
251
  ]);
252
- const UTIL_ALIASES = new Set(['dashboard', 'agent-browser-up']);
252
+ const UTIL_ALIASES = new Set(['dashboard', 'kevin-up']);
253
253
  let mod;
254
254
  if (UTIL_COMMANDS.has(cmd)) {
255
255
  // util-based commands: audit, init, etc.
256
256
  mod = await importCommand('util');
257
257
  } else if (UTIL_ALIASES.has(cmd)) {
258
- // util aliases: dashboard → dash, agent-browser-up → bash script
258
+ // util aliases: dashboard → dash, kevin-up → bash script
259
259
  if (cmd === 'dashboard') {
260
260
  mod = await importCommand('dash');
261
- } else if (cmd === 'agent-browser-up') {
262
- // Run via util.mjs's `agent-browser-up` case
261
+ } else if (cmd === 'kevin-up') {
262
+ // Run via util.mjs's `kevin-up` case
263
263
  mod = await importCommand('util');
264
264
  }
265
265
  } else {
@@ -499,8 +499,8 @@ async function main() {
499
499
  case 'digest':
500
500
  case 'backup':
501
501
  case 'restore':
502
- case 'agent-browser':
503
- case 'agent-browser-up':
502
+ case 'kevin':
503
+ case 'kevin-up':
504
504
  case 'providers':
505
505
  case 'plan': {
506
506
  const mod = await importCommand('util');
package/cli/bootstrap.mjs CHANGED
@@ -26,7 +26,7 @@ import { runPostInstall } from './install.mjs';
26
26
  * If ANY are missing → setup is needed.
27
27
  */
28
28
  const SETUP_MARKERS = [
29
- join(clineAgentsDir(), 'odin.md'), // core agent installed
29
+ join(clineAgentsDir(), 'mike.md'), // core agent installed
30
30
  join(clineConfigDir(), 'plugins', 'bizar'), // plugin installed
31
31
  ];
32
32
 
@@ -20,7 +20,7 @@ const ALL_COMMANDS = [
20
20
  // Util-based (live in cli/commands/util.mjs)
21
21
  'audit', 'init', 'export', 'test-gate', 'dev-link', 'dev-unlink',
22
22
  'doctor', 'repair', 'heads-up', 'bg', 'digest', 'backup', 'restore',
23
- 'agent-browser', 'agent-browser-up', 'providers',
23
+ 'kevin', 'kevin-up', 'providers',
24
24
  // Own module
25
25
  'install', 'update',
26
26
  'service',
@@ -38,7 +38,7 @@ const ALL_COMMANDS = [
38
38
  const NON_OWN_MODULE = new Set([
39
39
  'audit', 'init', 'export', 'test-gate', 'dev-link', 'dev-unlink',
40
40
  'doctor', 'repair', 'heads-up', 'bg', 'digest', 'backup', 'restore',
41
- 'agent-browser', 'agent-browser-up', 'providers', 'install', 'update',
41
+ 'kevin', 'kevin-up', 'providers', 'install', 'update',
42
42
  ]);
43
43
 
44
44
  const seen = new Set();
@@ -111,9 +111,9 @@ function showHelp() {
111
111
  --help, -h Show this help
112
112
 
113
113
  Examples:
114
- bizar claim F-035 --who odin --reason "porting MetaHarness from ruflo"
115
- bizar claim steal F-014 --by hermod --reason stale
116
- bizar claim handoff F-035 --to tyr --from odin
114
+ bizar claim F-035 --who mike --reason "porting MetaHarness from ruflo"
115
+ bizar claim steal F-014 --by steve --reason stale
116
+ bizar claim handoff F-035 --to karen --from mike
117
117
  bizar claim list --status claimed --agent-only
118
118
  `);
119
119
  }
@@ -121,7 +121,7 @@ export function showClaudeCmdHelp() {
121
121
  bizar config --json
122
122
  bizar plugin list
123
123
  bizar team auth-sprint "Plan and implement user auth with tests"
124
- bizar subagent mimir "Find all places where the auth token is verified"
124
+ bizar subagent greg "Find all places where the auth token is verified"
125
125
  bizar run "fix the failing test in src/auth.test.ts"
126
126
 
127
127
  Related:
@@ -262,7 +262,7 @@ export async function runClaudeTeam(args = []) {
262
262
  }
263
263
 
264
264
  /**
265
- * `bizar subagent <agent> "task"` — spawn a quick read-only research
265
+ * `bizar subagent <agent> "task"` — spawn a pam read-only research
266
266
  * subagent via `claude --agent <name> "..."`.
267
267
  *
268
268
  * Note: Claude Code's in-session subagent dispatch uses the `Agent`
@@ -272,7 +272,7 @@ export async function runClaudeTeam(args = []) {
272
272
  */
273
273
  export async function runClaudeSubagent(args = []) {
274
274
  if (args.length === 0) {
275
- console.log(chalk.cyan(' bizar subagent — Spawn a quick read-only research subagent\n'));
275
+ console.log(chalk.cyan(' bizar subagent — Spawn a pam read-only research subagent\n'));
276
276
  console.log(chalk.dim(' Subagents are research agents. They run in parallel, '));
277
277
  console.log(chalk.dim(' keep their own context window, and return a focused report.'));
278
278
  console.log(chalk.dim(' Use them for broad codebase exploration without burning context.\n'));
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Subcommands:
7
7
  * bizar eval list [--limit N] List recent runs
8
- * bizar eval run <suite-path> [--concurrency N] [--agent thor] Run a suite
8
+ * bizar eval run <suite-path> [--concurrency N] [--agent todd] Run a suite
9
9
  * bizar eval show <run-id> Show run details
10
10
  * bizar eval diff <run-id-1> <run-id-2> Compare two runs
11
11
  * bizar eval init <path> Scaffold a new fixture template
@@ -76,7 +76,7 @@ export function showEvalHelp() {
76
76
 
77
77
  Usage:
78
78
  bizar eval list [--limit N] List recent runs (default limit 20)
79
- bizar eval run <suite-path> [--concurrency N] [--agent thor]
79
+ bizar eval run <suite-path> [--concurrency N] [--agent todd]
80
80
  Run a fixture suite
81
81
  bizar eval show <run-id> Show run details + results
82
82
  bizar eval diff <run-id-1> <run-id-2> Diff two runs
@@ -118,12 +118,12 @@ async function runSuite(args) {
118
118
  const suitePath = positional[0];
119
119
  if (!suitePath) {
120
120
  console.error(chalk.red(' Error: suite-path is required'));
121
- console.error(' Usage: bizar eval run <suite-path> [--concurrency N] [--agent thor]');
121
+ console.error(' Usage: bizar eval run <suite-path> [--concurrency N] [--agent todd]');
122
122
  process.exit(1);
123
123
  }
124
124
 
125
125
  const concurrency = parseInt(args.find((a) => a.startsWith('--concurrency='))?.split('=')[1] || '5', 10);
126
- const agent = args.find((a) => a.startsWith('--agent='))?.split('=')[1] || 'thor';
126
+ const agent = args.find((a) => a.startsWith('--agent='))?.split('=')[1] || 'todd';
127
127
 
128
128
  console.log(chalk.bold(` Running eval suite: ${suitePath}`));
129
129
  console.log(` Concurrency: ${concurrency} Agent: ${agent}`);
@@ -260,7 +260,7 @@ function initFixture(path) {
260
260
  id: 'my-fixture-id',
261
261
  name: 'My Fixture',
262
262
  description: 'Describe what this fixture verifies',
263
- agent: 'thor',
263
+ agent: 'todd',
264
264
  prompt: 'What should the agent do?',
265
265
  expected: {
266
266
  contains: ['expected output fragment'],
@@ -286,7 +286,7 @@ function initFixture(path) {
286
286
  - \`id\` — unique identifier
287
287
  - \`name\` — human-readable name
288
288
  - \`description\` — what the fixture verifies
289
- - \`agent\` — agent to use (thor, tyr, etc.)
289
+ - \`agent\` — agent to use (todd, karen, etc.)
290
290
  - \`prompt\` — the prompt to send
291
291
  - \`expected\` — validation rules (contains, notContains, regex, jsonSchema, maxTokens, maxLatencyMs)
292
292
  - \`tags\` — optional tags for filtering
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Miscellaneous utility commands:
5
5
  * audit, init, export, test-gate, dev-link, dev-unlink,
6
- * doctor, repair, heads-up, bg, agent-browser, agent-browser-up, providers detect,
6
+ * doctor, repair, heads-up, bg, kevin, kevin-up, providers detect,
7
7
  * backup, restore
8
8
  */
9
9
  import chalk from 'chalk';
@@ -119,7 +119,7 @@ export function showDoctorHelp() {
119
119
  • the Bizar plugin is registered
120
120
  • plugin path resolves
121
121
  • @polderlabs/bizar-plugin is installed globally
122
- • core agent files are installed (odin, quick, thor, tyr)
122
+ • core agent files are installed (mike, pam, todd, karen)
123
123
  • semble / skills on PATH (lenient — at least one)
124
124
  • dashboard reachable (skipped if no port file)
125
125
  • provider.minimax block + MiniMax model flags are sane
@@ -466,11 +466,11 @@ export async function run(name, args, isHelpRequest) {
466
466
  }
467
467
  break;
468
468
 
469
- case 'agent-browser-up': {
469
+ case 'kevin-up': {
470
470
  const { execFileSync } = await import('node:child_process');
471
471
  const sub = args[0] || 'start';
472
472
  const __dirname = fileURLToPath(new URL('.', import.meta.url));
473
- const scriptPath = join(__dirname, '..', 'agent-browser-up.sh');
473
+ const scriptPath = join(__dirname, '..', 'kevin-up.sh');
474
474
  try {
475
475
  const out = execFileSync('bash', [scriptPath, sub], {
476
476
  encoding: 'utf8',
@@ -478,18 +478,18 @@ export async function run(name, args, isHelpRequest) {
478
478
  });
479
479
  if (out) process.stdout.write(out);
480
480
  } catch (err) {
481
- console.error(chalk.red(` ✗ agent-browser-up ${sub} failed (exit ${err.status ?? 1})`));
481
+ console.error(chalk.red(` ✗ kevin-up ${sub} failed (exit ${err.status ?? 1})`));
482
482
  process.exit(err.status || 1);
483
483
  }
484
484
  break;
485
485
  }
486
486
 
487
- case 'agent-browser': {
488
- // v6.0.0 — install / update / verify the agent-browser CLI.
489
- // (The 'agent-browser-up' sibling is the bash wrapper that just
487
+ case 'kevin': {
488
+ // v6.0.0 — install / update / verify the kevin CLI.
489
+ // (The 'kevin-up' sibling is the bash wrapper that just
490
490
  // manages the daemon process; this is the rich installer + updater.)
491
491
  const { install, update, detectState, ensureRunning, printStatus } =
492
- await import('../agent-browser-update.mjs');
492
+ await import('../kevin-update.mjs');
493
493
  const sub = args[0] || 'status';
494
494
  switch (sub) {
495
495
  case 'status':
@@ -497,7 +497,7 @@ export async function run(name, args, isHelpRequest) {
497
497
  break;
498
498
  case 'install': {
499
499
  const s = install({ silent: false });
500
- console.log(chalk.green('\n agent-browser ready.'));
500
+ console.log(chalk.green('\n kevin ready.'));
501
501
  console.log(` version: ${s.version}`);
502
502
  console.log(` daemon: ${s.daemonRunning ? 'running' : 'stopped'}`);
503
503
  console.log(` profile: ${s.profileDir}`);
@@ -505,7 +505,7 @@ export async function run(name, args, isHelpRequest) {
505
505
  }
506
506
  case 'update': {
507
507
  const s = update({ silent: false });
508
- console.log(chalk.green('\n agent-browser up-to-date.'));
508
+ console.log(chalk.green('\n kevin up-to-date.'));
509
509
  console.log(` version: ${s.version}`);
510
510
  console.log(` daemon: ${s.daemonRunning ? 'running' : 'stopped'}`);
511
511
  break;
@@ -520,7 +520,7 @@ export async function run(name, args, isHelpRequest) {
520
520
  break;
521
521
  case 'stop': {
522
522
  const { spawnSync } = await import('node:child_process');
523
- const killed = spawnSync('pkill', ['-f', 'agent-browser serve'], { stdio: 'ignore' });
523
+ const killed = spawnSync('pkill', ['-f', 'kevin serve'], { stdio: 'ignore' });
524
524
  if (killed.status === 0) {
525
525
  console.log(chalk.green(' ✓ daemon stopped'));
526
526
  } else {
@@ -529,21 +529,21 @@ export async function run(name, args, isHelpRequest) {
529
529
  break;
530
530
  }
531
531
  default:
532
- console.log(`bizar agent-browser <sub>
532
+ console.log(`bizar kevin <sub>
533
533
 
534
534
  Subcommands:
535
535
  status one-line status (default)
536
- install install agent-browser + download Chrome
536
+ install install kevin + download Chrome
537
537
  update upgrade to the latest version
538
538
  detect JSON state (for scripts)
539
539
  start start the daemon
540
540
  stop stop the daemon
541
541
 
542
542
  Examples:
543
- bizar agent-browser status
544
- bizar agent-browser install
545
- bizar agent-browser update
546
- bizar agent-browser start`);
543
+ bizar kevin status
544
+ bizar kevin install
545
+ bizar kevin update
546
+ bizar kevin start`);
547
547
  }
548
548
  break;
549
549
  }
@@ -61,10 +61,10 @@ function bizarHome() {
61
61
  const REPO_ROOT = process.env.BIZAR_REPO_ROOT || process.cwd();
62
62
 
63
63
  const REQUIRED_AGENTS = [
64
- 'odin.md', 'vor.md', 'frigg.md', 'quick.md',
65
- 'mimir.md', 'heimdall.md', 'hermod.md', 'thor.md', 'baldr.md',
66
- 'tyr.md', 'vidarr.md', 'forseti.md',
67
- 'semble-search.md', 'agent-browser.md',
64
+ 'mike.md', 'janet.md', 'susan.md', 'pam.md',
65
+ 'greg.md', 'brenda.md', 'steve.md', 'todd.md', 'brad.md',
66
+ 'karen.md', 'carl.md', 'linda.md',
67
+ 'oscar.md', 'kevin.md',
68
68
  ];
69
69
 
70
70
  const REQUIRED_COMMANDS = [
@@ -244,16 +244,16 @@ const CHECKS = {
244
244
 
245
245
  'agent-frontmatter-format': async () => {
246
246
  // Claude Code reads agents via `.md` files with YAML frontmatter.
247
- // Spot-check that at least the odin.md agent has frontmatter.
247
+ // Spot-check that at least the mike.md agent has frontmatter.
248
248
  const dir = join(claudeDir(), 'agents');
249
249
  if (!existsSync(dir)) throw new Error('agents dir missing');
250
- const odin = join(dir, 'odin.md');
251
- if (!existsSync(odin)) throw new Error('odin.md missing');
252
- const text = readFileSync(odin, 'utf8');
250
+ const mike = join(dir, 'mike.md');
251
+ if (!existsSync(mike)) throw new Error('mike.md missing');
252
+ const text = readFileSync(mike, 'utf8');
253
253
  if (!text.startsWith('---')) {
254
- throw new Error('odin.md has no YAML frontmatter — Claude Code may not load it');
254
+ throw new Error('mike.md has no YAML frontmatter — Claude Code may not load it');
255
255
  }
256
- return 'odin.md has YAML frontmatter';
256
+ return 'mike.md has YAML frontmatter';
257
257
  },
258
258
 
259
259
  'slash-commands-installed': async () => {
package/cli/init.mjs CHANGED
@@ -363,6 +363,6 @@ ${stack.runner ? `- Dev: \`${stack.runner}\`` : ''}
363
363
  }
364
364
  }
365
365
 
366
- console.log(chalk.dim('\n Project initialized. Run `@frigg` to ask questions about the codebase.\n'));
366
+ console.log(chalk.dim('\n Project initialized. Run `@susan` to ask questions about the codebase.\n'));
367
367
  return true;
368
368
  }