@polderlabs/bizar 10.25.1 → 10.26.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 (95) hide show
  1. package/AGENTS.md +4 -4
  2. package/README.md +44 -37
  3. package/cli/bin.mjs +3 -46
  4. package/cli/commands/claim.mjs +6 -6
  5. package/cli/commands/goal-bootstrap.mjs +1 -1
  6. package/cli/commands/hook.mjs +0 -7
  7. package/cli/commands/install.mjs +15 -10
  8. package/cli/commands/openkan.mjs +19 -13
  9. package/cli/commands/planning.mjs +1 -1
  10. package/cli/commands/setup-provider.mjs +4 -2
  11. package/cli/commands/task.mjs +10 -10
  12. package/cli/commands/tools.mjs +19 -6
  13. package/cli/commands/upgrade-defaults.mjs +6 -33
  14. package/cli/commands/util.mjs +1 -1
  15. package/cli/commands/validate.mjs +26 -20
  16. package/cli/commands/worker.mjs +30 -21
  17. package/cli/commands/workflow.mjs +14 -100
  18. package/cli/config-paths.mjs +0 -12
  19. package/cli/core/workflow-state.mjs +2 -5
  20. package/cli/doctor.mjs +41 -23
  21. package/cli/install/index.mjs +9 -2
  22. package/cli/install/interactive-setup.mjs +105 -10
  23. package/cli/install/paths.mjs +4 -0
  24. package/cli/openkan.mjs +212 -10
  25. package/cli/provision.mjs +160 -208
  26. package/config/agents/model-assignment.mjs +45 -97
  27. package/config/claude/agents/_shared/AGENT_BASELINE.md +1 -1
  28. package/config/claude/agents/_shared/SKILLS.md +4 -2
  29. package/config/claude/agents/office-manager.md +33 -31
  30. package/config/claude/agents/planner.md +18 -15
  31. package/config/claude/commands/bizar.md +2 -2
  32. package/config/claude/commands/plow-through.md +1 -1
  33. package/config/claude/commands/setup-provider.md +8 -2
  34. package/config/claude/commands/team.md +5 -4
  35. package/config/claude/hooks/README.md +14 -2
  36. package/config/claude/hooks/goal-bootstrap.mjs +3 -3
  37. package/config/claude/hooks/sessionend-recall.mjs +1 -1
  38. package/config/claude/hooks/sessionstart-prime.mjs +3 -3
  39. package/config/claude/hooks/verify-deliverables.mjs +1 -1
  40. package/config/claude/hooks/worker-suggest.mjs +1 -1
  41. package/config/claude/hooks/workflow-route-guard.mjs +4 -3
  42. package/config/claude/hooks/worktree-bootstrap.mjs +1 -1
  43. package/config/claude/settings.json +12 -1
  44. package/config/skills/autopilot/SKILL.md +1 -1
  45. package/config/skills/goal-bootstrap/SKILL.md +5 -5
  46. package/config/skills/harness-engineering/SKILL.md +1 -1
  47. package/config/skills/openkan/SKILL.md +9 -9
  48. package/config/skills/ultragoal/SKILL.md +3 -3
  49. package/config/skills/ultrawork/SKILL.md +1 -1
  50. package/config/workflows/bizar-debug.js +17 -25
  51. package/config/workflows/bizar-implement.js +15 -24
  52. package/config/workflows/bizar-research.js +14 -24
  53. package/config/workflows/lib/dispatch.js +219 -998
  54. package/config/workflows/ultracode-research.js +14 -23
  55. package/config/workflows/ultracode-review.js +14 -23
  56. package/config/workflows/ultracode.js +15 -24
  57. package/install.sh +14 -4
  58. package/package.json +2 -2
  59. package/packages/sdk/dist/autonomy/outcome-record.d.ts +1 -1
  60. package/packages/sdk/dist/autonomy/outcome-record.js +1 -1
  61. package/packages/sdk/dist/bench/auto-reduction.d.ts +3 -3
  62. package/packages/sdk/dist/bench/auto-reduction.js +3 -3
  63. package/packages/sdk/dist/mcp/server.js +62 -24
  64. package/packages/sdk/dist/release/known-good-releases.d.ts +7 -0
  65. package/packages/sdk/dist/release/known-good-releases.js +43 -1
  66. package/packages/sdk/dist/version.d.ts +1 -1
  67. package/packages/sdk/dist/version.js +1 -1
  68. package/packages/sdk/package.json +1 -1
  69. package/cli/commands/model.mjs +0 -189
  70. package/cli/commands/models.mjs +0 -2808
  71. package/cli/commands/tier.mjs +0 -159
  72. package/config/claude/hooks/agent-model-guard.mjs +0 -304
  73. package/config/claude/hooks/sessionstart-model-sync.mjs +0 -312
  74. package/config/claude/hooks/thinking-route.mjs +0 -311
  75. package/packages/sdk/dist/router/agent-model-registry.d.ts +0 -323
  76. package/packages/sdk/dist/router/agent-model-registry.js +0 -492
  77. package/packages/sdk/dist/router/codemod-intent.d.ts +0 -68
  78. package/packages/sdk/dist/router/codemod-intent.js +0 -112
  79. package/packages/sdk/dist/router/dispatch-evidence.d.ts +0 -176
  80. package/packages/sdk/dist/router/dispatch-evidence.js +0 -505
  81. package/packages/sdk/dist/router/failover-mirror.mjs +0 -315
  82. package/packages/sdk/dist/router/failover.d.ts +0 -188
  83. package/packages/sdk/dist/router/failover.js +0 -255
  84. package/packages/sdk/dist/router/index.d.ts +0 -176
  85. package/packages/sdk/dist/router/index.js +0 -238
  86. package/packages/sdk/dist/router/model-profile.d.ts +0 -229
  87. package/packages/sdk/dist/router/model-profile.js +0 -199
  88. package/packages/sdk/dist/router/model-router.d.ts +0 -113
  89. package/packages/sdk/dist/router/model-router.js +0 -268
  90. package/packages/sdk/dist/router/outcome-learner.d.ts +0 -180
  91. package/packages/sdk/dist/router/outcome-learner.js +0 -506
  92. package/packages/sdk/dist/router/q-learning-router.d.ts +0 -83
  93. package/packages/sdk/dist/router/q-learning-router.js +0 -277
  94. package/packages/sdk/dist/router/select-dispatch-model.d.ts +0 -227
  95. package/packages/sdk/dist/router/select-dispatch-model.js +0 -532
package/AGENTS.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Bizar Harness is a Claude Code-native, guarded-autonomy harness. It ships project and user-level agents, skills, slash commands, hooks, an MCP server, CLI utilities, and verification scripts. OpenKan is bundled as Bizar’s default durable planning, progression, task, and PRD-goal system; Bizar integrates with it only through the `.ok/` workspace and its supported CLI boundary.
4
4
 
5
- If you are an agent: read this file, inspect `.ok/` with `bizar task list` and `bizar goals list`, then run `make check` before changing code.
5
+ If you are an agent: read this file, inspect `.ok/` with `ok task list` and `ok prd list`, then run `make check` before changing code.
6
6
 
7
7
  ## Commands
8
8
 
@@ -15,9 +15,9 @@ make check-arch # architectural and removed-surface checks
15
15
  make verify-removed-surfaces # prove deleted subsystems are absent
16
16
  make verify-repo-structure # prove tracked/package paths are clean
17
17
  make clean-check # debug-artifact/static hygiene gate
18
- bizar task list # OpenKan task progression
19
- bizar plan list # OpenKan plans
20
- bizar goals list # OpenKan PRD goals
18
+ ok task list # OpenKan task progression
19
+ ok plan list # OpenKan plans
20
+ ok prd list # OpenKan PRD goals
21
21
  make session-start # lifecycle compatibility target
22
22
  make session-end # lifecycle compatibility target
23
23
  ```
package/README.md CHANGED
@@ -35,34 +35,43 @@ the project you happen to be working on.
35
35
 
36
36
  | You want | Bizar provides |
37
37
  | --- | --- |
38
- | A clean way to begin | A guided installer and `bizar models` picker |
39
- | Your own gateway models | Global selection, full-ID subagent definitions, and native alias mapping |
38
+ | A clean way to begin | A guided installer and a static four-alias dispatch surface |
39
+ | Your own gateway models | Four native aliases (`haiku`/`sonnet`/`opus`/`fable`) with OmniRoute handling ordered failover between configured full IDs |
40
40
  | Useful parallel work | Isolated worktrees, scoped tasks, and specialist roles |
41
41
  | Fewer surprises | Explicit safety checks for releases, publication, deployment, pushes, and destructive operations |
42
42
  | Confidence at the end | Tests, architecture checks, E2E checks, and evidence-aware handoff |
43
43
 
44
44
  ## Start here
45
45
 
46
- Install Bizar globally, install its Claude Code integration, then choose the
47
- models you want Bizar to use.
46
+ Install Bizar globally and its Claude Code integration. Bizar dispatches
47
+ through four static native aliases — `haiku`, `sonnet`, `opus`, `fable` —
48
+ and OmniRoute handles ordered failover between configured full IDs for the
49
+ chosen alias, so there is no model picker step.
48
50
 
49
51
  ```sh
50
52
  npm install -g @polderlabs/bizar
51
53
  bizar install
52
- bizar models
53
54
  ```
54
55
 
55
56
  Restart Claude Code after installation. The installer adds Bizar's agents, skills, commands, hooks, settings, and the
56
57
  default OpenKan planning runtime to your user-level Claude configuration.
58
+ Claude Code itself is installed with Anthropic's native installer; npm is used
59
+ for Bizar and OpenKan, not for the Claude Code CLI.
57
60
  It preserves your configured gateway endpoint and credential values during a
58
61
  clean reinstall.
59
62
 
63
+ On a new interactive install, Bizar also asks whether Claude Code agent teams
64
+ should be enabled, the OpenKan install directory, and whether the current
65
+ project should receive a `.ok/` workspace. OpenKan is installed from npm as
66
+ `@polderlabs/openkan@latest`; its package-owned agent and skill are
67
+ installed into the same Claude configuration. Use `bizar install --yes` for
68
+ CI or a prompt-free refresh.
69
+
60
70
  For a completely fresh Bizar-managed Claude setup while retaining endpoint and
61
71
  authentication settings:
62
72
 
63
73
  ```sh
64
74
  bizar install --force
65
- bizar models
66
75
  ```
67
76
 
68
77
  Then open any repository in Claude Code and describe the outcome you want.
@@ -98,40 +107,36 @@ foregrounded.
98
107
 
99
108
  ## Your models, everywhere Bizar dispatches
100
109
 
101
- `bizar models` is the single operator-facing place to select models. It
102
- discovers candidates from your configured gateway and writes your selections to
103
- the global model router:
110
+ Bizar dispatches through four static native aliases `haiku`, `sonnet`,
111
+ `opus`, `fable`. Claude Code's native per-call `model` field accepts one of
112
+ these aliases. OmniRoute handles ordered failover between the configured full
113
+ gateway IDs for the chosen alias, so the operator never picks a picker-style
114
+ gateway ID per agent at this layer. There is no `bizar models` picker, no
115
+ `model-router.json`, no `userSelected` block, and no Agent-model-guard hook.
104
116
 
105
- ```text
106
- ~/.claude/model-router.json
107
- ```
117
+ The four aliases are the entire dispatch surface:
108
118
 
109
- The router is never stored in a project directory. Bizar uses the selected
110
- models for direct subagents, workflows, and agent-team teammates.
119
+ - `haiku` trivial / cheap micro-edits
120
+ - `sonnet` ordinary implementation, research, planning lanes
121
+ - `opus` — hard / architectural / adversarial / debug / high-risk review lanes
122
+ - `fable` — explicit Anthropic OpenAI-compat surfaces
123
+
124
+ Workflow scripts (`config/workflows/*.js`) inline a tiny `dispatchAgent`
125
+ wrapper that picks the alias from a static policy; agent definitions stay
126
+ model-agnostic so the harness, not the agent, owns alias selection.
111
127
 
112
128
  ```mermaid
113
129
  flowchart TD
114
- Picker["bizar models"] --> Router["Global model router\n~/.claude/model-router.json"]
115
- Router --> Definitions["Global Bizar agent definitions\nfull model ID in frontmatter"]
116
- Router --> Aliases["sonnet · opus · haiku · fable\ncompatibility aliases"]
117
- Definitions --> Agent["Subagents"]
118
- Definitions --> Workflow["Workflow workers"]
119
- Definitions --> Team["Agent-team teammates"]
130
+ Policy["Static alias policy\n(office-manager.md + workflow routeModel)"] --> Aliases["haiku · sonnet · opus · fable"]
131
+ Aliases --> OmniRoute["OmniRoute ordered failover\nper configured full ID"]
132
+ OmniRoute --> Agent["Subagents"]
133
+ OmniRoute --> Workflow["Workflow workers"]
134
+ OmniRoute --> Team["Agent-team teammates"]
120
135
  ```
121
136
 
122
- Claude Code's native per-call model field has a small alias vocabulary. Bizar
123
- avoids making that vocabulary a limitation: it projects each selected gateway
124
- model into a global subagent definition whose frontmatter contains the full
125
- model ID. The agent, workflow, and team routes use that definition. The four
126
- native aliases are compatibility shortcuts only; they do not enable an
127
- unselected provider or reduce your selected-model pool to four choices.
128
-
129
137
  Useful inspection commands:
130
138
 
131
139
  ```sh
132
- bizar models --list
133
- bizar models --agent-types --json
134
- bizar models explain todd
135
140
  bizar doctor
136
141
  ```
137
142
 
@@ -144,9 +149,7 @@ also ships 80 skills for planning, debugging, verification, review,
144
149
  worktrees, and implementation practice.
145
150
 
146
151
  The coordinator selects specialists when their expertise reduces a concrete
147
- risk. It does not create parallel workers merely to look busy. You can inspect
148
- the installed specialist definition names through `bizar models --agent-types
149
- --json` and use a relevant Bizar specialist directly when needed.
152
+ risk. It does not create parallel workers merely to look busy.
150
153
 
151
154
  ```text
152
155
  Core coordination Specialist coverage
@@ -186,10 +189,12 @@ point where an external or difficult-to-reverse decision belongs to you.
186
189
  ├── rules/ focused guidance for common development work
187
190
  ├── workflows/ native workflow definitions
188
191
  ├── settings.json Bizar-managed Claude Code integration
189
- └── model-router.json operator-selected model state
192
+ └── agents/ Bizar agent definitions (alias-agnostic)
190
193
 
191
194
  ~/.config/bizar/
192
195
  ├── installed.json install record
196
+ ├── openkan/ managed @polderlabs/openkan npm runtime
197
+ ├── openkan-install.json selected OpenKan home/package settings
193
198
  ├── evidence/ local dispatch and verification evidence
194
199
  ├── telemetry/ local routing and rejected-action feedback
195
200
  └── worktree-queue.json completed worktree integration queue
@@ -203,11 +208,13 @@ plane, background daemon, or general-purpose note vault.
203
208
 
204
209
  | Command | When to use it |
205
210
  | --- | --- |
206
- | `bizar install` | Install or refresh Bizar in your global Claude configuration |
207
- | `bizar models` | Discover and select the models Bizar may dispatch |
211
+ | `bizar install` | Install or refresh Bizar, OpenKan, and the global Claude configuration |
212
+ | `bizar openkan install` | Refresh the managed `@polderlabs/openkan` npm runtime and its agent/skill |
213
+ | `bizar openkan init` | Initialise `.ok/` planning state in the current project |
208
214
  | `bizar doctor` | Diagnose the global installation and provider connectivity |
209
215
  | `bizar validate` | Run an install-focused health check |
210
- | `bizar task` | Inspect or coordinate scoped worktree tasks |
216
+ | `ok task` | Inspect or coordinate scoped worktree tasks (OpenKan-native) |
217
+ | `ok plan` / `ok prd` | Manage OpenKan plans and PRD goals |
211
218
  | `bizar worktree-merge --all` | Review and merge completed isolated work, surfacing conflicts |
212
219
  | `bizar control snapshot --json` | Read the machine-friendly current harness state |
213
220
  | `bizar evidence` | Inspect local dispatch and verification evidence |
package/cli/bin.mjs CHANGED
@@ -108,7 +108,6 @@ function showHelp() {
108
108
  artifact Toggle global browser completion artifacts
109
109
  learn Manage bounded global preferences and project lessons
110
110
  tools Inventory installed agents, skills, hooks, commands, and MCP tools
111
- tier Explain the explicit configured model tier for a task
112
111
  upgrade-defaults Reapply safe Bizar-owned Claude defaults
113
112
  backup Create / list / verify / delete backups of BizarHarness state
114
113
  restore Restore BizarHarness from a backup
@@ -136,12 +135,10 @@ function showHelp() {
136
135
  hook <name> Run a portable Claude Code hook
137
136
  worktree-merge <branch> Merge a feature branch with archive tag (no work lost)
138
137
  worker <subcommand> Run an exact-model Claude process worker in a worktree
139
- models Configure the global model picker and Models.dev metadata
140
138
  evidence <subcommand> Inspect model-routing evidence
141
139
  improve <subcommand> Propose and verify bounded self-edits
142
140
  sandbox <subcommand> Manage local execution sandboxes
143
141
  explain-run <id> Explain a recorded run
144
- model Deprecated alias for models
145
142
 
146
143
  Examples:
147
144
  bizar install
@@ -154,7 +151,7 @@ function showHelp() {
154
151
 
155
152
  Install:
156
153
  npm install -g @polderlabs/bizar
157
- npm install -g @anthropic-ai/claude-code
154
+ curl -fsSL https://claude.ai/install.sh | bash
158
155
  `);
159
156
  }
160
157
 
@@ -399,7 +396,7 @@ async function main() {
399
396
  dbg('loaded command module:', 'claim');
400
397
  const found = await mod.run(cmd, cmdArgs, isHelpRequest);
401
398
  if (found === false) {
402
- console.error(chalk.red(` ✗ Usage: bizar claim <subcommand> — run 'bizar claim --help'`));
399
+ console.error(chalk.red(` ✗ Usage: ok task claim <task-id> — run 'ok task --help'`));
403
400
  process.exit(EXIT_USAGE);
404
401
  }
405
402
  break;
@@ -415,7 +412,7 @@ async function main() {
415
412
  dbg('loaded command module:', 'task');
416
413
  const found = await mod.run(cmd, cmdArgs, isHelpRequest);
417
414
  if (found === false) {
418
- console.error(chalk.red(` ✗ Usage: bizar task <subcommand> — run 'bizar task --help'`));
415
+ console.error(chalk.red(` ✗ Usage: ok task <subcommand> — run 'ok task --help'`));
419
416
  process.exit(EXIT_USAGE);
420
417
  }
421
418
  break;
@@ -452,22 +449,6 @@ async function main() {
452
449
  break;
453
450
  }
454
451
 
455
- case 'models': {
456
- const mod = await importCommand('models');
457
- if (!mod) {
458
- console.error(chalk.red(` ✗ Could not load models command module`));
459
- process.exit(EXIT_ERROR);
460
- return;
461
- }
462
- dbg('loaded command module:', 'models');
463
- const found = await mod.run(cmd, cmdArgs, isHelpRequest);
464
- if (found === false) {
465
- console.error(chalk.red(` ✗ Usage: bizar models [--list|--set|--clear|--json] — run 'bizar models --help'`));
466
- process.exit(EXIT_USAGE);
467
- }
468
- break;
469
- }
470
-
471
452
  case 'artifact': {
472
453
  const mod = await importCommand('artifact');
473
454
  if (!mod) { process.exit(EXIT_ERROR); return; }
@@ -483,7 +464,6 @@ async function main() {
483
464
  }
484
465
 
485
466
  case 'tools':
486
- case 'tier':
487
467
  case 'upgrade-defaults': {
488
468
  const mod = await importCommand(cmd);
489
469
  if (!mod) { process.exit(EXIT_ERROR); return; }
@@ -615,29 +595,6 @@ async function main() {
615
595
  break;
616
596
  }
617
597
 
618
- case 'model': {
619
- // Deprecated alias. Routes to the original `model.mjs` so the
620
- // legacy JSON shape (`{ providers: { ... }, total: N }`) and table
621
- // output keep working for existing scripts and tests. New code
622
- // should use `bizar models` (see `case 'models'`).
623
- const mod = await importCommand('model');
624
- if (!mod) {
625
- console.error(chalk.red(` ✗ Could not load model command module`));
626
- process.exit(EXIT_ERROR);
627
- return;
628
- }
629
- dbg('loaded command module (deprecated alias):', 'model');
630
- if (!isHelpRequest) {
631
- console.error(chalk.yellow(' ! `bizar model` is deprecated; use `bizar models` for the new picker surface.'));
632
- }
633
- const found = await mod.run(cmd, cmdArgs, isHelpRequest);
634
- if (found === false) {
635
- console.error(chalk.red(` ✗ Usage: bizar model <subcommand> — run 'bizar model --help'`));
636
- process.exit(EXIT_USAGE);
637
- }
638
- break;
639
- }
640
-
641
598
  case 'workflow': {
642
599
  const mod = await importCommand('workflow');
643
600
  if (!mod) {
@@ -3,16 +3,16 @@ import { OpenKanError, runOpenKanOk } from '../openkan.mjs';
3
3
 
4
4
  function help() {
5
5
  process.stdout.write(`
6
- bizar claim — claim an OpenKan task lease
6
+ ok task claim — claim an OpenKan task lease
7
7
 
8
8
  Usage:
9
- bizar claim <task-id> [--who <agent>] [--lease-ms <ms>]
10
- bizar claim release <task-id> [--who <agent>]
11
- bizar claim heartbeat <task-id> [--who <agent>] [--lease-ms <ms>]
12
- bizar claim list [--status <status>] [--json]
9
+ ok task claim <task-id> [--who <agent>] [--lease-ms <ms>]
10
+ ok task release <task-id> [--who <agent>]
11
+ ok task heartbeat <task-id> [--who <agent>] [--lease-ms <ms>]
12
+ ok task list [--status <status>] [--json]
13
13
 
14
14
  Claims are OpenKan .ok locks, not feature_list.json annotations. Use
15
- \`bizar task update\` for status transitions and \`bizar goals\` for PRDs.
15
+ \`ok task update\` for status transitions and \`ok prd\` for PRDs.
16
16
  `);
17
17
  }
18
18
 
@@ -9,7 +9,7 @@ function usage() {
9
9
  bizar goal-bootstrap — retired compatibility alias
10
10
 
11
11
  OpenKan PRDs are Bizar's default durable goal system.
12
- Use: bizar goals list | bizar goals add <title> | bizar goals update <id> ...
12
+ Use: ok prd list | ok prd add <title> | ok prd update <id> ...
13
13
  `);
14
14
  }
15
15
 
@@ -18,14 +18,12 @@ const HOOK_ROOT = resolve(PACKAGE_ROOT, 'config', 'claude', 'hooks');
18
18
  const PRETOOL_SAFETY_LEAVES = new Set([
19
19
  'pretooluse-editwrite', 'path-ownership-guard',
20
20
  'pretooluse-bash', 'git-workflow-guard',
21
- 'agent-model-guard',
22
21
  'workflow-route-guard',
23
22
  ]);
24
23
 
25
24
  export const HOOK_PROGRAMS = Object.freeze({
26
25
  'advisor-context': 'advisor-context.mjs',
27
26
  'agent-grounding': 'agent-grounding.mjs',
28
- 'agent-model-guard': 'agent-model-guard.mjs',
29
27
  'content-style-guard': 'content-style-guard.mjs',
30
28
  'completion-artifact': 'completion-artifact.mjs',
31
29
  'control-inbox': 'control-inbox.mjs',
@@ -40,11 +38,9 @@ export const HOOK_PROGRAMS = Object.freeze({
40
38
  'pretooluse-bash': 'pretooluse-bash.mjs',
41
39
  'pretooluse-editwrite': 'pretooluse-editwrite.mjs',
42
40
  'sessionend-recall': 'sessionend-recall.mjs',
43
- 'sessionstart-model-sync': 'sessionstart-model-sync.mjs',
44
41
  'sessionstart-prime': 'sessionstart-prime.mjs',
45
42
  'simplify-guard': 'simplify-guard.mjs',
46
43
  telemetry: 'telemetry.mjs',
47
- 'thinking-route': 'thinking-route.mjs',
48
44
  'team-lifecycle': 'team-lifecycle.mjs',
49
45
  'verify-deliverables': 'verify-deliverables.mjs',
50
46
  'worker-suggest': 'worker-suggest.mjs',
@@ -59,12 +55,10 @@ export const EVENT_CHAINS = Object.freeze({
59
55
  'keyword-router',
60
56
  'workflow-route-guard',
61
57
  'worker-suggest',
62
- 'thinking-route',
63
58
  'telemetry',
64
59
  ]),
65
60
  'session-start': Object.freeze([
66
61
  'control-inbox',
67
- 'sessionstart-model-sync',
68
62
  'sessionstart-prime',
69
63
  'persistent-mode',
70
64
  'telemetry',
@@ -238,7 +232,6 @@ export function selectEventChain(eventKey, input = '') {
238
232
  if (toolName === 'Bash') {
239
233
  return ['workflow-route-guard', 'pretooluse-bash', 'git-workflow-guard'];
240
234
  }
241
- if (toolName === 'Agent') return ['workflow-route-guard', 'agent-model-guard'];
242
235
  return [];
243
236
  }
244
237
 
@@ -53,18 +53,23 @@ export function showInstallHelp() {
53
53
  while the prior ANTHROPIC_* and BIZAR_* env vars are merged back
54
54
  in from the stash.
55
55
 
56
- 1. Installs @polderlabs/bizar via npm (skipped if already current).
57
- 2. Installs or updates OpenKan from its official installer as Bizar's
58
- default durable planning, progression, and PRD-goal runtime.
59
- 3. Shells to ./install.sh for platform-specific system dependencies.
60
- 4. Syncs agent files, slash commands, and bundled skills into
56
+ 1. Uses the already-installed @polderlabs/bizar package.
57
+ 2. Installs or updates Claude Code with Anthropic's native installer
58
+ (never npm) when the native launcher is absent.
59
+ 3. Installs or updates OpenKan from npm as Bizar's default durable
60
+ planning, progression, and PRD-goal runtime.
61
+ 4. Uses platform dependencies prepared by ./install.sh when invoked
62
+ through that bootstrap.
63
+ 5. Syncs agent files, slash commands, and bundled skills into
61
64
  ~/.claude/ (or $CLAUDE_CONFIG_DIR).
62
- 5. Registers the Bizar MCP server in ~/.claude/settings.json.
63
- 6. Wires Claude Code lifecycle hooks (SessionStart / PreToolUse /
65
+ 6. Registers the Bizar MCP server in ~/.claude/settings.json.
66
+ 7. Wires Claude Code lifecycle hooks (SessionStart / PreToolUse /
64
67
  PostToolUse / UserPromptSubmit) under ~/.claude/hooks/.
65
- 7. In a terminal, confirms the install and securely asks for a provider
66
- URL and key only when they are not already configured.
67
- 8. Runs 'bizar doctor' as a post-install health check.
68
+ 8. In a terminal, confirms the install and securely asks for a provider
69
+ URL and key only when they are not already configured. Fresh setups
70
+ can also choose a default model, agent teams, OpenKan home, and whether
71
+ to initialise the current project's .ok/ workspace.
72
+ 9. Runs 'bizar doctor' as a post-install health check.
68
73
 
69
74
  Provider settings are global (~/.claude/settings.json), so they work from
70
75
  every project. Key input is hidden. Use --yes or --non-interactive to skip
@@ -1,5 +1,5 @@
1
1
  import { spawnSync } from 'node:child_process';
2
- import { executableOnPath, ensureOpenKanProject, installOpenKanPromise, OpenKanError, runOpenKanOk } from '../openkan.mjs';
2
+ import { ensureOpenKanProject, installOpenKanPromise, OpenKanError, resolveOpenKanDashboard, runOpenKanOk } from '../openkan.mjs';
3
3
 
4
4
  function print(result) {
5
5
  if (result.stdout) process.stdout.write(result.stdout);
@@ -13,23 +13,28 @@ bizar openkan — default durable planning and goals surface
13
13
 
14
14
  Usage:
15
15
  bizar openkan install Install @polderlabs/openkan@latest from npm
16
- bizar openkan init Initialise .ok/ in this project
17
- bizar openkan task <ok task args...> Manage durable tasks
18
- bizar openkan plan <ok plan args...> Manage plans and phases
19
- bizar openkan goals <ok prd args...> Manage PRDs, goals, and milestones
20
- bizar openkan doctor Validate the .ok/ workspace
16
+ ok init Initialise .ok/ in this project
17
+ ok task <add|list|show|update|...> Manage durable tasks
18
+ ok plan <add|list|show|update> Manage plans and phases
19
+ ok prd <add|list|show|update> Manage PRDs, goals, and milestones
20
+ ok doctor Validate the .ok/ workspace
21
21
  bizar openkan dashboard [args...] Forward to the OpenKan dashboard CLI
22
22
 
23
- Shortcuts: \`bizar task\`, \`bizar plan\`, and \`bizar goals\` use this
24
- same OpenKan workspace. Bizar no longer creates a SQLite task ledger or
23
+ Canonical commands are \`ok task\`, \`ok plan\`, and \`ok prd\`; they use this
24
+ same OpenKan workspace. The Bizar planning aliases remain compatibility-only.
25
+ Bizar no longer creates a SQLite task ledger or
25
26
  feature/progress files for live planning.
26
27
  `);
27
28
  }
28
29
 
29
30
  function runDashboard(args) {
30
- const bin = process.env.BIZAR_OPENKAN_BIN || executableOnPath('openkan');
31
- if (!bin) throw new OpenKanError('OPENKAN_NOT_FOUND', 'OpenKan is required. Run `bizar openkan install`.');
32
- const result = spawnSync(bin, args, { cwd: process.cwd(), encoding: 'utf8', shell: false });
31
+ const launcher = resolveOpenKanDashboard();
32
+ const command = launcher.endsWith('.ts')
33
+ ? [process.execPath, '--experimental-strip-types', launcher, ...args]
34
+ : launcher.endsWith('.mjs')
35
+ ? [process.execPath, launcher, ...args]
36
+ : [launcher, ...args];
37
+ const result = spawnSync(command[0], command.slice(1), { cwd: process.cwd(), encoding: 'utf8', shell: false });
33
38
  if (result.error) throw result.error;
34
39
  print({ ok: result.status === 0, status: result.status ?? 1, stdout: result.stdout || '', stderr: result.stderr || '' });
35
40
  }
@@ -40,8 +45,9 @@ export async function run(name, args, isHelpRequest) {
40
45
  if (isHelpRequest || !subcommand || subcommand === 'help') { help(); return true; }
41
46
  try {
42
47
  if (subcommand === 'install') {
43
- const result = await installOpenKanPromise();
44
- print(result);
48
+ const result = await installOpenKanPromise({ persistConfig: true });
49
+ process.stdout.write(` ✓ ${result.message}\n`);
50
+ if (result.agent?.skipped) process.stdout.write(' ! OpenKan agent/skill installation was skipped by configuration.\n');
45
51
  return true;
46
52
  }
47
53
  if (subcommand === 'init') {
@@ -3,7 +3,7 @@ import { OpenKanError, runOpenKanOk } from '../openkan.mjs';
3
3
 
4
4
  function usage(name) {
5
5
  const resource = name === 'goals' ? 'prd' : 'plan';
6
- process.stdout.write(`\n bizar ${name} — OpenKan ${resource} lifecycle\n\n Usage: bizar ${name} <ok ${resource} args...>\n Run \`bizar openkan ${name} --help\` for the canonical OpenKan surface.\n`);
6
+ process.stdout.write(`\n bizar ${name} — compatibility alias for OpenKan ${resource}\n\n Usage: ok ${resource} <args...>\n Run \`ok ${resource} --help\` for the canonical OpenKan surface.\n`);
7
7
  }
8
8
 
9
9
  export async function run(name, args, isHelpRequest) {
@@ -43,7 +43,9 @@ export function updateProviderSettings(current, options) {
43
43
  const next = { ...current, env: { ...(current.env || {}) } };
44
44
  if (options.gateway !== undefined) {
45
45
  next.env.ANTHROPIC_BASE_URL = options.gateway;
46
- next.env.BIZAR_MODEL_ROUTER_URL = options.gateway;
46
+ // Legacy compatibility: drop any pre-existing router-URL mirror so the
47
+ // install surface converges on a single provider URL.
48
+ delete next.env.BIZAR_MODEL_ROUTER_URL;
47
49
  }
48
50
  if (options.key !== undefined) next.env.ANTHROPIC_AUTH_TOKEN = options.key;
49
51
  if (options.model !== undefined) next.env.ANTHROPIC_MODEL = options.model;
@@ -87,7 +89,7 @@ export async function runSetupProvider(args = []) {
87
89
 
88
90
  if (options.list) {
89
91
  console.log(` Settings: ${path}`);
90
- console.log(` Gateway: ${current.env?.ANTHROPIC_BASE_URL || current.env?.BIZAR_MODEL_ROUTER_URL || '(Anthropic default)'}`);
92
+ console.log(` Gateway: ${current.env?.ANTHROPIC_BASE_URL || '(Anthropic default)'}`);
91
93
  console.log(` Model: ${current.env?.ANTHROPIC_MODEL || '(Claude Code default)'}`);
92
94
  console.log(` API key: ${redact(current.env?.ANTHROPIC_AUTH_TOKEN || current.env?.ANTHROPIC_API_KEY)}`);
93
95
  return { ok: true, path, settings: current };
@@ -3,18 +3,18 @@ import { OpenKanError, runOpenKanOk } from '../openkan.mjs';
3
3
 
4
4
  function help() {
5
5
  process.stdout.write(`
6
- bizar task — OpenKan-backed task lifecycle
6
+ ok task — OpenKan-backed task lifecycle
7
7
 
8
8
  Usage:
9
- bizar task add <title> [--owner agent] [--priority p0|p1|p2|p3]
10
- bizar task list [--status pending|in_progress|review|done|cancelled] [--json]
11
- bizar task show <id> [--json]
12
- bizar task claim <id> --owner <agent> [--lease-ms <ms>]
13
- bizar task heartbeat <id> --owner <agent> [--lease-ms <ms>]
14
- bizar task update <id> --status <status> [--evidence <text>]
15
- bizar task complete <id> --owner <agent> --evidence <text>
16
- bizar task cancel <id> --owner <agent> --reason <text>
17
- bizar task release <id> --owner <agent>
9
+ ok task add <title> [--owner agent] [--priority p0|p1|p2|p3]
10
+ ok task list [--status pending|in_progress|review|done|cancelled] [--json]
11
+ ok task show <id> [--json]
12
+ ok task claim <id> --owner <agent> [--lease-ms <ms>]
13
+ ok task heartbeat <id> --owner <agent> [--lease-ms <ms>]
14
+ ok task update <id> --status <status> [--evidence <text>]
15
+ ok task complete <id> --owner <agent> --evidence <text>
16
+ ok task cancel <id> --owner <agent> --reason <text>
17
+ ok task release <id> --owner <agent>
18
18
 
19
19
  This is an exact convenience alias for \`ok task\`. OpenKan persists task
20
20
  state, scoped ownership, dependencies, evidence, plans, and goals under
@@ -15,7 +15,7 @@ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
15
15
  import { join, resolve } from 'node:path';
16
16
  import { fileURLToPath } from 'node:url';
17
17
 
18
- import { resolveClaudeConfigDir, resolveGlobalModelRouter } from '../config-paths.mjs';
18
+ import { resolveClaudeConfigDir } from '../config-paths.mjs';
19
19
  const __filename = fileURLToPath(import.meta.url);
20
20
  const __dirname = resolve(__filename, '..', '..');
21
21
  const CLAUDE_DIR = resolveClaudeConfigDir();
@@ -80,8 +80,6 @@ export async function runTools(cmdArgs) {
80
80
 
81
81
  const settingsPath = join(CLAUDE_DIR, 'settings.json');
82
82
  const hasSettings = existsSync(settingsPath);
83
- const modelRouterPath = resolveGlobalModelRouter();
84
- const hasModelRouter = existsSync(modelRouterPath);
85
83
 
86
84
  const summary = {
87
85
  userLevel: CLAUDE_DIR,
@@ -92,7 +90,6 @@ export async function runTools(cmdArgs) {
92
90
  wiredCommands,
93
91
  mcpTools,
94
92
  settings: { path: settingsPath, present: hasSettings },
95
- modelRouter: { path: modelRouterPath, present: hasModelRouter },
96
93
  };
97
94
 
98
95
  if (asJson) {
@@ -118,8 +115,24 @@ export async function runTools(cmdArgs) {
118
115
  section(`wired bizar commands (${wiredCommands.length})`, wiredCommands.map((c) => 'bizar ' + c));
119
116
  console.log(chalk.bold('\n settings'));
120
117
  console.log(` ${hasSettings ? '✓' : '✗'} ${settingsPath}`);
121
- console.log(chalk.bold(' model-router'));
122
- console.log(` ${hasModelRouter ? '✓' : '✗'} ${modelRouterPath}`);
118
+ if (hasSettings) {
119
+ try {
120
+ const parsed = JSON.parse(readFileSync(settingsPath, 'utf8'));
121
+ const env = (parsed && parsed.env) || {};
122
+ const aliases = {
123
+ sonnet: env.ANTHROPIC_DEFAULT_SONNET_MODEL,
124
+ haiku: env.ANTHROPIC_DEFAULT_HAIKU_MODEL,
125
+ opus: env.ANTHROPIC_DEFAULT_OPUS_MODEL,
126
+ fable: env.ANTHROPIC_DEFAULT_FABLE_MODEL,
127
+ };
128
+ console.log(chalk.bold(' alias map'));
129
+ for (const [key, value] of Object.entries(aliases)) {
130
+ console.log(` ${key.padEnd(8)} → ${value || '(unset)'}`);
131
+ }
132
+ const model = parsed?.model;
133
+ if (model) console.log(chalk.dim(` default model: ${model}`));
134
+ } catch { /* ignore malformed settings */ }
135
+ }
123
136
  }
124
137
 
125
138
  export async function run(name, args, isHelpRequest) {
@@ -35,42 +35,18 @@
35
35
  import chalk from 'chalk';
36
36
  import { existsSync, readFileSync, writeFileSync, copyFileSync } from 'node:fs';
37
37
  import { join } from 'node:path';
38
- import { resolveClaudeConfigDir, resolveGlobalModelRouter } from '../config-paths.mjs';
39
- import { configuredFallbackModels } from './models.mjs';
38
+ import { resolveClaudeConfigDir } from '../config-paths.mjs';
40
39
 
41
40
  const CLAUDE_DIR = resolveClaudeConfigDir();
42
41
  const SETTINGS_PATH = join(CLAUDE_DIR, 'settings.json');
43
- // 10.22.0 / Phase 4 spirit-of-constraint: the install model id comes
44
- // from the operator's `userSelected.models[0]`, not a hardcoded literal.
45
- // The Bizar global router is the sole model-policy source.
46
- const BIZAR_ROUTER_PATH = resolveGlobalModelRouter();
47
-
48
- function readConfiguredModels() {
49
- for (const path of [BIZAR_ROUTER_PATH]) {
50
- if (!existsSync(path)) continue;
51
- try {
52
- const parsed = JSON.parse(readFileSync(path, 'utf8'));
53
- const list = Array.isArray(parsed?.userSelected?.models)
54
- ? parsed.userSelected.models.filter((id) => typeof id === 'string' && id.trim())
55
- : [];
56
- if (list.length > 0) return list;
57
- const fallback = configuredFallbackModels(parsed);
58
- if (fallback.length > 0) return fallback;
59
- // An explicit empty selection is an intentional global policy.
60
- if (path === BIZAR_ROUTER_PATH && parsed && typeof parsed === 'object'
61
- && Array.isArray(parsed.userSelected?.models)) {
62
- return [];
63
- }
64
- } catch { /* keep falling through */ }
65
- }
66
- return [];
67
- }
68
42
 
69
43
  const STATIC_FAVORED = {
70
44
  permissions: { defaultMode: 'bypassPermissions' },
71
45
  worktree: { bgIsolation: 'worktree' },
72
- // `model` is intentionally absent — `buildFavored()` derives it from
73
- // userSelected.models[0] (or omits it when empty).
46
+ // `model` is intentionally absent — settings.json ships the alias
47
+ // binding (model + modelOverrides + the four ANTHROPIC_DEFAULT_*_MODEL
48
+ // env vars) as the canonical source. `upgrade-defaults` only re-applies
49
+ // the safe Bizar-owned UX defaults, not model policy.
74
50
  alwaysThinkingEnabled: true,
75
51
  effortLevel: 'high',
76
52
  skipDangerousModePermissionPrompt: true,
@@ -79,10 +55,7 @@ const STATIC_FAVORED = {
79
55
  };
80
56
 
81
57
  function buildFavored() {
82
- const out = { ...STATIC_FAVORED };
83
- const picks = readConfiguredModels();
84
- if (picks[0]) out.model = picks[0];
85
- return out;
58
+ return { ...STATIC_FAVORED };
86
59
  }
87
60
 
88
61
  export async function run(name, args, isHelpRequest) {
@@ -82,7 +82,7 @@ export function showDoctorHelp() {
82
82
  • hook wiring
83
83
  • installed agents and skills
84
84
  • required local tools
85
- model-router reachability
85
+ alias map (ANTHROPIC_DEFAULT_*_MODEL)
86
86
 
87
87
  Prints ✓/✗ for each check and a final summary. Exits non-zero
88
88
  if any check fails. Use \`bizar doctor\` after installation or