- Add worktreeNaming setting type with 'random' | 'task-id' | 'task-title' options - Update executor to generate worktree names based on setting value - Create worktree-names.ts utility module with generateWorktreeName function - Add comprehensive executor tests for all naming strategies - Update AGENTS.md documentation with setting description and usage - Include changeset for patch release
8.7 KiB
Project Guidelines
Finalizing changes
When making changes that affect published packages, create a changeset file:
cat > .changeset/<short-description>.md << 'EOF'
---
"@dustinbyrne/kb": patch
---
Short description of the change.
EOF
Bump types:
- patch: bug fixes, internal changes
- minor: new features, new CLI commands, new tools
- major: breaking changes
Include the changeset file in the same commit as the code change. The filename should be a short kebab-case description (e.g. fix-merge-conflict.md, add-retry-button.md).
Only create changesets for changes that affect the published @dustinbyrne/kb package — user-facing features, bug fixes, CLI changes, tool changes. Do NOT create changesets for internal docs (AGENTS.md, README), CI config, or refactors that don't change behavior.
Package Structure
@kb/core— domain model, task store (private, not published)@kb/dashboard— web UI + API server (private, not published)@kb/engine— AI agents: triage, executor, reviewer, merger, scheduler (private, not published)@dustinbyrne/kb— CLI + pi extension (published to npm)
Only @dustinbyrne/kb is published. The others are internal workspace packages.
Testing
pnpm test # run all tests
pnpm build # build all packages
Tests are required. Typechecks and manual verification are not substitutes for real tests with assertions.
Pi Extension (packages/cli/src/extension.ts)
The pi extension provides tools and a /kb command for interacting with kb from within a pi session. It ships as part of @dustinbyrne/kb — one pi install gives you both the CLI and the extension.
Update it when:
- CLI commands change — if
kb task create,kb task list,kb task show,kb task attach,kb task pause, orkb task unpausechange their behavior, flags, or output, update the corresponding tool inpackages/cli/src/extension.ts. - Task store API changes — the extension calls
TaskStoredirectly (createTask,listTasks,getTask,addAttachment,pauseTask). If these methods change signature or behavior, update the extension. - New user-facing features — if a new CLI command is added that the chat agent should be able to use (task creation, status checking, automation control), add a tool for it.
Don't add tools for engine-internal operations (move, step updates, logging, merge) — those are handled by the engine's own agents.
The extension has no skills — tool descriptions, promptSnippet, and promptGuidelines give the LLM everything it needs.
Git
- Commit messages:
feat(KB-XXX):,fix(KB-XXX):,test(KB-XXX): - One commit per step (not per file change)
- Always include the task ID prefix
Settings
The following settings are available in the kb configuration (stored in .kb/config.json):
autoResolveConflicts (default: true)
When enabled, the auto-merge system will intelligently resolve common merge conflict patterns without requiring manual intervention:
- Lock files (
package-lock.json,pnpm-lock.yaml,yarn.lock,Gemfile.lock, etc.) — automatically resolved using the current branch's version ("ours") - Generated files (
*.gen.ts,dist/*,coverage/*, etc.) — automatically resolved using the branch's fresh generation ("theirs") - Trivial conflicts (whitespace-only differences) — automatically resolved
When a merge encounters conflicts and the AI agent fails to resolve them on the first attempt, the system implements a 3-attempt retry logic with escalating strategies:
- Attempt 1: Standard merge with AI agent using full context
- Attempt 2: Auto-resolve lock/generated files, then retry AI with simplified context
- Attempt 3: Use
git merge -X theirsstrategy for remaining conflicts
If all 3 attempts fail, the task remains in "in-review" for manual resolution. The per-task retry counter (mergeRetries) tracks how many attempts have been made.
To disable automatic conflict resolution and require manual intervention for all conflicts:
{
"settings": {
"autoResolveConflicts": false
}
}
smartConflictResolution (default: true)
Alias for autoResolveConflicts. When enabled, enables automatic resolution of:
- Lock files using "ours" strategy (keep current branch's version)
- Generated files using "theirs" strategy (keep branch's fresh generation)
- Trivial whitespace conflicts via
git diff-tree -w
This setting is preferred for new configurations. If both settings are present, smartConflictResolution takes precedence.
requirePlanApproval (default: false)
When enabled, AI-generated task specifications require manual approval before the task can move from "triage" to "todo".
How it works:
- After the AI reviewer approves a specification, instead of automatically moving to "todo", the task remains in "triage" with status
"awaiting-approval" - Users can review the PROMPT.md in the task detail modal
- Users can click "Approve Plan" to move the task to "todo" and begin execution
- Users can click "Reject Plan" to discard the specification and trigger regeneration
To enable manual plan approval:
{
"settings": {
"requirePlanApproval": true
}
}
ntfyEnabled (default: false)
When true, enables ntfy.sh push notifications for task completion and failures.
Notification events:
- Task moves to "in-review" — "Task completed — ready for review"
- Task moves to "done" — "Task merged to main"
- Task status becomes "failed" — "Task failed" (high priority)
Configuration:
- Go to https://ntfy.sh and pick a unique topic name (or self-host ntfy)
- Open dashboard Settings → Notifications
- Enable notifications and enter your topic name
- Install the ntfy app on your phone/desktop and subscribe to your topic
{
"settings": {
"ntfyEnabled": true,
"ntfyTopic": "my-kb-notifications"
}
}
Notes:
- No authentication required for public topics (keep it simple)
- Topic must be 1–64 alphanumeric/hyphen/underscore characters
- Notifications are best-effort: failures are logged but don't block task execution
worktreeNaming (default: "random")
Controls how worktree directory names are generated when recycleWorktrees is NOT enabled. This setting only affects fresh worktrees (not pooled/recycled ones).
Valid values:
"random"— Human-friendly random names likeswift-falcon,calm-river(default)"task-id"— Use the task ID as the directory name, e.g.,kb-042"task-title"— Use a slugified version of the task title, e.g.,fix-login-bug
Example:
{
"settings": {
"worktreeNaming": "task-id"
}
}
Notes:
- This setting has no effect when
recycleWorktreesis enabled (pooled worktrees retain their existing names) - Task branches are always named
kb/{task-id}regardless of this setting - When using
"task-title"mode, special characters are replaced with hyphens and the result is lowercased
Per-Task Model Overrides
The kb dashboard allows overriding the global AI model selection on a per-task basis. This enables using different models for different types of work without changing global settings.
How It Works
Each task can optionally specify:
- Executor Model: The AI model used to implement the task (executor agent)
- Validator Model: The AI model used to review code and plans (reviewer agent)
When not specified, tasks use the global default settings (defaultProvider/defaultModelId).
Setting Per-Task Models
In the dashboard, open any task's detail modal and click the Model tab. Select models from the dropdown:
- Use default: Uses the global default model (shown when no override is set)
- Specific model: Override with a chosen provider/model combination
Both provider and model ID must be selected together — selecting only one is treated as "not set" and falls back to defaults.
Storage
Per-task model overrides are stored in the task's task.json:
{
"modelProvider": "anthropic",
"modelId": "claude-sonnet-4-5",
"validatorModelProvider": "openai",
"validatorModelId": "gpt-4o"
}
To clear overrides, select "Use default" for both fields and save.
Engine Behavior
- Executor: When both
modelProviderandmodelIdare set on a task, the executor uses those instead of global settings when creating the agent session. - Reviewer: When both
validatorModelProviderandvalidatorModelIdare set, the reviewer uses those instead of global settings. The validator model is passed viaReviewOptionstoreviewStep().
Limitations
- Triage (task specification) always uses global defaults — per-task overrides apply only to execution and review
- Both provider and modelId must be set together; partial configuration falls back to defaults