docs(KB-222): rebrand kb to Fusion across documentation and CLI
- Rebrand root README from kb to Fusion with updated descriptions - Update CLI package README with Fusion branding - Rebrand STANDALONE.md documentation to Fusion - Update CLI help text to use 'fn' command reference - Update pi extension descriptions and tool names for Fusion - Add changeset for rebranding documentation - Update dashboard ListView component and styles - Remove obsolete store tests and ListView tests
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# @dustinbyrne/kb
|
||||
|
||||
An automated Kanban board for [pi](https://github.com/badlogic/pi-mono). You (or an agent) add high level ideas to your task list, and a team of agents execute them using worktrees.
|
||||
An automated Kanban board for [pi](https://github.com/badlogic/pi-mono). Fusion is an AI-orchestrated task board where you (or an agent) add high level ideas to your task list, and a team of agents execute them using worktrees.
|
||||
|
||||

|
||||

|
||||
|
||||
## Installation
|
||||
|
||||
@@ -10,16 +10,16 @@ An automated Kanban board for [pi](https://github.com/badlogic/pi-mono). You (or
|
||||
pi install npm:@dustinbyrne/kb
|
||||
```
|
||||
|
||||
This gives pi the ability to manage and create tasks in your kanban dashboard.
|
||||
This gives pi the ability to manage and create tasks in your Fusion dashboard.
|
||||
|
||||
## The dashboard
|
||||
|
||||
Run `/kb` in pi to launch the dashboard and AI engine.
|
||||
Run `/fn` in pi to launch the dashboard and AI engine.
|
||||
|
||||
```
|
||||
/kb # start on default port 4040
|
||||
/kb stop # stop it
|
||||
/kb 8080 # run on a custom port
|
||||
/fn # start on default port 4040
|
||||
/fn stop # stop it
|
||||
/fn 8080 # run on a custom port
|
||||
```
|
||||
|
||||
The dashboard gives you:
|
||||
@@ -49,14 +49,14 @@ An executor agent works through the spec step by step in the worktree. At each s
|
||||
|
||||
### Merge
|
||||
|
||||
When execution finishes and the reviewer signs off, the task moves to "in review." kb supports two completion modes:
|
||||
When execution finishes and the reviewer signs off, the task moves to "in review." Fusion supports two completion modes:
|
||||
|
||||
- **Direct merge** *(default)* — automatically squash-merges the completed task branch into your current branch with a clean commit.
|
||||
- **Pull request** — automatically creates or links a GitHub PR for the task branch, waits for GitHub reviews/checks, then merges the PR once policy conditions are satisfied.
|
||||
|
||||
`autoMerge` still controls whether kb performs completion automatically at all. If `autoMerge` is disabled, tasks stay in **In Review** until you finish the merge yourself.
|
||||
`autoMerge` still controls whether Fusion performs completion automatically at all. If `autoMerge` is disabled, tasks stay in **In Review** until you finish the merge yourself.
|
||||
|
||||
For PR-first mode, authenticate GitHub with `gh auth login` or `GITHUB_TOKEN`, and make sure the task branch already exists on GitHub as `kb/<task-id-lower>`. kb does **not** push branches for you before PR creation.
|
||||
For PR-first mode, authenticate GitHub with `gh auth login` or `GITHUB_TOKEN`, and make sure the task branch already exists on GitHub as `kb/<task-id-lower>`. Fusion does **not** push branches for you before PR creation.
|
||||
|
||||
Worktrees can be cleaned up after merge or reused by the next task to keep build caches warm.
|
||||
|
||||
@@ -68,7 +68,7 @@ You can manage tasks without leaving the conversation:
|
||||
|
||||
> "Every ten minutes, analyze the server code for logic the client hasn't implemented yet and create tasks. Tasks may spawn additional tasks, so just add enough to keep the board saturated."
|
||||
|
||||
> "Create a kb task to fix the login redirect bug"
|
||||
> "Create a Fusion task to fix the login redirect bug"
|
||||
|
||||
> "Add a task for dark mode support, it depends on KB-003"
|
||||
|
||||
@@ -82,7 +82,7 @@ The extension gives pi tools to create tasks, check progress, attach files, and
|
||||
|
||||
## Standalone CLI
|
||||
|
||||
kb also works as a standalone CLI outside of pi. See [STANDALONE.md](./STANDALONE.md) for installation and usage without the pi extension.
|
||||
Fusion also works as a standalone CLI outside of pi. See [STANDALONE.md](./STANDALONE.md) for installation and usage without the pi extension.
|
||||
|
||||
## Full documentation
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Standalone CLI
|
||||
|
||||
kb works as a standalone CLI without pi. This is useful for CI environments, scripting, or if you prefer working from the terminal.
|
||||
Fusion works as a standalone CLI without pi. This is useful for CI environments, scripting, or if you prefer working from the terminal.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -10,7 +10,7 @@ npm install -g @dustinbyrne/kb
|
||||
|
||||
## Authentication
|
||||
|
||||
kb uses [pi](https://github.com/badlogic/pi-mono) for AI agent sessions and reuses your existing pi authentication. You can also authenticate directly through the dashboard UI.
|
||||
Fusion uses [pi](https://github.com/badlogic/pi-mono) for AI agent sessions and reuses your existing pi authentication. You can also authenticate directly through the dashboard UI.
|
||||
|
||||
If you don't have pi set up yet: `npm i -g @mariozechner/pi-coding-agent && pi` then `/login`.
|
||||
|
||||
@@ -21,11 +21,11 @@ If you don't have pi set up yet: `npm i -g @mariozechner/pi-coding-agent && pi`
|
||||
Launch the web UI and AI engine:
|
||||
|
||||
```bash
|
||||
kb dashboard
|
||||
kb dashboard --port 8080
|
||||
kb dashboard --interactive # Interactive port selection (prompts for port)
|
||||
kb dashboard --paused # Start with automation paused (review before work begins)
|
||||
kb dashboard --dev # Start web UI only (no AI engine)
|
||||
fn dashboard
|
||||
fn dashboard --port 8080
|
||||
fn dashboard --interactive # Interactive port selection (prompts for port)
|
||||
fn dashboard --paused # Start with automation paused (review before work begins)
|
||||
fn dashboard --dev # Start web UI only (no AI engine)
|
||||
```
|
||||
|
||||
### Multi-Instance Deployments
|
||||
@@ -39,7 +39,7 @@ export KB_BADGE_PUBSUB_REDIS_URL="redis://redis.example.com:6379"
|
||||
# Optional: customize the pub/sub channel (default: kb:badge-updates)
|
||||
export KB_BADGE_PUBSUB_CHANNEL="my-app-badge-updates"
|
||||
|
||||
kb dashboard
|
||||
fn dashboard
|
||||
```
|
||||
|
||||
With this configuration, PR/issue badge updates received via webhook on one instance are delivered to subscribed WebSocket clients on all instances.
|
||||
@@ -82,40 +82,40 @@ When webhooks are not configured or delivery fails, the dashboard falls back to
|
||||
### Create a task
|
||||
|
||||
```bash
|
||||
kb task create "Fix the login redirect bug"
|
||||
kb task create "Update hero section" --attach screenshot.png --attach design.pdf
|
||||
fn task create "Fix the login redirect bug"
|
||||
fn task create "Update hero section" --attach screenshot.png --attach design.pdf
|
||||
```
|
||||
|
||||
### Manage tasks
|
||||
|
||||
```bash
|
||||
kb task list # List all tasks
|
||||
kb task show KB-001 # Show task details, steps, and log
|
||||
kb task move KB-001 todo # Move a task to a column
|
||||
kb task merge KB-001 # Merge an in-review task and close it
|
||||
kb task log KB-001 "Added context" # Add a log entry
|
||||
kb task pause KB-001 # Pause a task (stops automation)
|
||||
kb task unpause KB-001 # Resume a paused task
|
||||
kb task attach KB-001 ./error.log # Attach a file to a task
|
||||
kb task import owner/repo # Import GitHub issues as tasks
|
||||
kb task import owner/repo --limit 10 --labels "bug,enhancement"
|
||||
fn task list # List all tasks
|
||||
fn task show KB-001 # Show task details, steps, and log
|
||||
fn task move KB-001 todo # Move a task to a column
|
||||
fn task merge KB-001 # Merge an in-review task and close it
|
||||
fn task log KB-001 "Added context" # Add a log entry
|
||||
fn task pause KB-001 # Pause a task (stops automation)
|
||||
fn task unpause KB-001 # Resume a paused task
|
||||
fn task attach KB-001 ./error.log # Attach a file to a task
|
||||
fn task import owner/repo # Import GitHub issues as tasks
|
||||
fn task import owner/repo --limit 10 --labels "bug,enhancement"
|
||||
```
|
||||
|
||||
### Typical workflow
|
||||
|
||||
```bash
|
||||
# 1. Create a task — it lands in triage
|
||||
kb task create "Add dark mode support"
|
||||
fn task create "Add dark mode support"
|
||||
|
||||
# 2. Start the dashboard — AI specs the task and begins working
|
||||
kb dashboard
|
||||
fn dashboard
|
||||
|
||||
# 3. Check progress
|
||||
kb task list
|
||||
kb task show KB-042
|
||||
fn task list
|
||||
fn task show KB-042
|
||||
|
||||
# 4. When it reaches "in-review", review the changes and merge
|
||||
kb task merge KB-042
|
||||
fn task merge KB-042
|
||||
```
|
||||
|
||||
## Standalone binary
|
||||
|
||||
@@ -44,41 +44,41 @@ const { runSettingsShow, runSettingsSet } = await import("./commands/settings.js
|
||||
const { runGitStatus, runGitFetch, runGitPull, runGitPush } = await import("./commands/git.js");
|
||||
|
||||
const HELP = `
|
||||
kb — AI-orchestrated task board
|
||||
fn — AI-orchestrated task board
|
||||
|
||||
Usage:
|
||||
kb dashboard Start the board web UI
|
||||
kb dashboard --paused Start with automation paused
|
||||
kb dashboard --dev Start web UI only (no AI engine)
|
||||
kb dashboard --interactive Start with interactive port selection
|
||||
kb task create [desc] [opts] Create a new task (goes to triage)
|
||||
kb task plan [description] [opts] Create task via AI-guided planning
|
||||
kb task list List all tasks
|
||||
kb task show <id> Show task details, steps, log
|
||||
kb task logs <id> [--follow] [--limit <n>] [--type <type>]
|
||||
fn dashboard Start the board web UI
|
||||
fn dashboard --paused Start with automation paused
|
||||
fn dashboard --dev Start web UI only (no AI engine)
|
||||
fn dashboard --interactive Start with interactive port selection
|
||||
fn task create [desc] [opts] Create a new task (goes to triage)
|
||||
fn task plan [description] [opts] Create task via AI-guided planning
|
||||
fn task list List all tasks
|
||||
fn task show <id> Show task details, steps, log
|
||||
fn task logs <id> [--follow] [--limit <n>] [--type <type>]
|
||||
Show task agent execution logs
|
||||
kb task move <id> <col> Move a task to a column
|
||||
kb task update <id> <step> <status> Update step status (pending|in-progress|done|skipped)
|
||||
kb task log <id> <message> Add a log entry
|
||||
kb task merge <id> Merge an in-review task and close it
|
||||
kb task duplicate <id> Duplicate a task (creates copy in triage)
|
||||
kb task refine <id> [opts] Create a refinement task from done/in-review
|
||||
kb task archive <id> Archive a done task
|
||||
kb task unarchive <id> Unarchive an archived task
|
||||
kb task delete <id> [--force] Delete a task (use --force to skip confirmation)
|
||||
kb task attach <id> <file> Attach a file to a task
|
||||
kb task pause <id> Pause a task (stops all automation)
|
||||
kb task unpause <id> Unpause a task (resumes automation)
|
||||
kb task steer <id> [message] Add steering comment (prompts if message omitted)
|
||||
kb task retry <id> Retry a failed task (clears error, moves to todo)
|
||||
kb task import <owner/repo> [opts] Import GitHub issues as tasks
|
||||
kb settings Show current kb configuration
|
||||
kb settings set <key> <value> Update a configuration setting
|
||||
fn task move <id> <col> Move a task to a column
|
||||
fn task update <id> <step> <status> Update step status (pending|in-progress|done|skipped)
|
||||
fn task log <id> <message> Add a log entry
|
||||
fn task merge <id> Merge an in-review task and close it
|
||||
fn task duplicate <id> Duplicate a task (creates copy in triage)
|
||||
fn task refine <id> [opts] Create a refinement task from done/in-review
|
||||
fn task archive <id> Archive a done task
|
||||
fn task unarchive <id> Unarchive an archived task
|
||||
fn task delete <id> [--force] Delete a task (use --force to skip confirmation)
|
||||
fn task attach <id> <file> Attach a file to a task
|
||||
fn task pause <id> Pause a task (stops all automation)
|
||||
fn task unpause <id> Unpause a task (resumes automation)
|
||||
fn task steer <id> [message] Add steering comment (prompts if message omitted)
|
||||
fn task retry <id> Retry a failed task (clears error, moves to todo)
|
||||
fn task import <owner/repo> [opts] Import GitHub issues as tasks
|
||||
fn settings Show current Fusion configuration
|
||||
fn settings set <key> <value> Update a configuration setting
|
||||
|
||||
kb git status Show current branch, commit, dirty state, ahead/behind
|
||||
kb git push Push current branch
|
||||
kb git pull Pull current branch
|
||||
kb git fetch [remote] Fetch from remote (default: origin)
|
||||
fn git status Show current branch, commit, dirty state, ahead/behind
|
||||
fn git push Push current branch
|
||||
fn git pull Pull current branch
|
||||
fn git fetch [remote] Fetch from remote (default: origin)
|
||||
|
||||
Options:
|
||||
--port, -p <port> Dashboard port (default: 4040)
|
||||
@@ -171,7 +171,7 @@ async function main() {
|
||||
const id = args[2];
|
||||
const column = args[3];
|
||||
if (!id || !column) {
|
||||
console.error("Usage: kb task move <id> <column>");
|
||||
console.error("Usage: fn task move <id> <column>");
|
||||
process.exit(1);
|
||||
}
|
||||
await runTaskMove(id, column);
|
||||
@@ -179,14 +179,14 @@ async function main() {
|
||||
}
|
||||
case "show": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task show <id>"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task show <id>"); process.exit(1); }
|
||||
await runTaskShow(id);
|
||||
break;
|
||||
}
|
||||
case "update": {
|
||||
const id = args[2], step = args[3], status = args[4];
|
||||
if (!id || !step || !status) {
|
||||
console.error("Usage: kb task update <id> <step> <status>");
|
||||
console.error("Usage: fn task update <id> <step> <status>");
|
||||
console.error("Status: pending | in-progress | done | skipped");
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -195,13 +195,13 @@ async function main() {
|
||||
}
|
||||
case "log": {
|
||||
const id = args[2], message = args.slice(3).join(" ");
|
||||
if (!id || !message) { console.error("Usage: kb task log <id> <message>"); process.exit(1); }
|
||||
if (!id || !message) { console.error("Usage: fn task log <id> <message>"); process.exit(1); }
|
||||
await runTaskLog(id, message);
|
||||
break;
|
||||
}
|
||||
case "logs": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task logs <id> [--follow] [--limit <n>] [--type <type>]"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task logs <id> [--follow] [--limit <n>] [--type <type>]"); process.exit(1); }
|
||||
|
||||
// Parse flags
|
||||
const follow = args.includes("--follow");
|
||||
@@ -226,19 +226,19 @@ async function main() {
|
||||
}
|
||||
case "merge": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task merge <id>"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task merge <id>"); process.exit(1); }
|
||||
await runTaskMerge(id);
|
||||
break;
|
||||
}
|
||||
case "duplicate": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task duplicate <id>"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task duplicate <id>"); process.exit(1); }
|
||||
await runTaskDuplicate(id);
|
||||
break;
|
||||
}
|
||||
case "refine": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task refine <id> [--feedback <text>]"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task refine <id> [--feedback <text>]"); process.exit(1); }
|
||||
// Parse optional --feedback flag
|
||||
const feedbackIdx = args.indexOf("--feedback");
|
||||
const feedback = feedbackIdx !== -1 && feedbackIdx + 1 < args.length
|
||||
@@ -249,19 +249,19 @@ async function main() {
|
||||
}
|
||||
case "archive": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task archive <id>"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task archive <id>"); process.exit(1); }
|
||||
await runTaskArchive(id);
|
||||
break;
|
||||
}
|
||||
case "unarchive": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task unarchive <id>"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task unarchive <id>"); process.exit(1); }
|
||||
await runTaskUnarchive(id);
|
||||
break;
|
||||
}
|
||||
case "delete": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task delete <id> [--force]"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task delete <id> [--force]"); process.exit(1); }
|
||||
const force = args.includes("--force");
|
||||
await runTaskDelete(id, force);
|
||||
break;
|
||||
@@ -269,7 +269,7 @@ async function main() {
|
||||
case "attach": {
|
||||
const id = args[2], file = args[3];
|
||||
if (!id || !file) {
|
||||
console.error("Usage: kb task attach <id> <file>");
|
||||
console.error("Usage: fn task attach <id> <file>");
|
||||
process.exit(1);
|
||||
}
|
||||
await runTaskAttach(id, file);
|
||||
@@ -277,27 +277,27 @@ async function main() {
|
||||
}
|
||||
case "pause": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task pause <id>"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task pause <id>"); process.exit(1); }
|
||||
await runTaskPause(id);
|
||||
break;
|
||||
}
|
||||
case "unpause": {
|
||||
const id = args[2];
|
||||
if (!id) { console.error("Usage: kb task unpause <id>"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task unpause <id>"); process.exit(1); }
|
||||
await runTaskUnpause(id);
|
||||
break;
|
||||
}
|
||||
case "steer": {
|
||||
const id = args[2];
|
||||
const message = args.slice(3).join(" ");
|
||||
if (!id) { console.error("Usage: kb task steer <id> [message]"); process.exit(1); }
|
||||
if (!id) { console.error("Usage: fn task steer <id> [message]"); process.exit(1); }
|
||||
await runTaskSteer(id, message || undefined);
|
||||
break;
|
||||
}
|
||||
case "retry": {
|
||||
const id = args[2];
|
||||
if (!id) {
|
||||
console.error("Usage: kb task retry <id>");
|
||||
console.error("Usage: fn task retry <id>");
|
||||
process.exit(1);
|
||||
}
|
||||
await runTaskRetry(id);
|
||||
@@ -306,7 +306,7 @@ async function main() {
|
||||
case "import": {
|
||||
const ownerRepo = args[2];
|
||||
if (!ownerRepo) {
|
||||
console.error("Usage: kb task import <owner/repo> [options]");
|
||||
console.error("Usage: fn task import <owner/repo> [options]");
|
||||
console.error("Options: --limit <n>, -l <n> (default: 30, max: 100)");
|
||||
console.error(" --labels <labels>, -L <labels> (comma-separated)");
|
||||
console.error(" --interactive, -i (interactive mode)");
|
||||
@@ -346,7 +346,7 @@ async function main() {
|
||||
}
|
||||
default:
|
||||
console.error(`Unknown subcommand: task ${subcommand || ""}`);
|
||||
console.log("Try: kb task create | list | move");
|
||||
console.log("Try: fn task create | list | move");
|
||||
process.exit(1);
|
||||
}
|
||||
break;
|
||||
@@ -362,15 +362,15 @@ async function main() {
|
||||
const key = args[2];
|
||||
const value = args.slice(3).join(" ");
|
||||
if (!key || value === undefined) {
|
||||
console.error("Usage: kb settings set <key> <value>");
|
||||
console.error("Example: kb settings set maxConcurrent 4");
|
||||
console.error("Usage: fn settings set <key> <value>");
|
||||
console.error("Example: fn settings set maxConcurrent 4");
|
||||
process.exit(1);
|
||||
}
|
||||
await runSettingsSet(key, value);
|
||||
break;
|
||||
}
|
||||
console.error(`Unknown settings subcommand: ${subcommand}`);
|
||||
console.error("Try: kb settings | kb settings set <key> <value>");
|
||||
console.error("Try: fn settings | fn settings set <key> <value>");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -397,7 +397,7 @@ async function main() {
|
||||
}
|
||||
default:
|
||||
console.error(`Unknown subcommand: git ${subcommand || ""}`);
|
||||
console.log("Try: kb git status | fetch | pull | push");
|
||||
console.log("Try: fn git status | fetch | pull | push");
|
||||
process.exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -60,10 +60,10 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
name: "kb_task_create",
|
||||
label: "KB: Create Task",
|
||||
description:
|
||||
"Create a new task on the kb task board. The task enters the triage column " +
|
||||
"Create a new task on the Fusion task board. The task enters the triage column " +
|
||||
"where the AI triage agent will specify it into a full prompt with steps, " +
|
||||
"file scope, and acceptance criteria.",
|
||||
promptSnippet: "Create a task on the kb AI-orchestrated task board",
|
||||
promptSnippet: "Create a task on the Fusion AI-orchestrated task board",
|
||||
promptGuidelines: [
|
||||
"Use kb_task_create for task tracking — be descriptive so the triage agent can write a good spec.",
|
||||
"Include the problem AND desired outcome. For bugs, describe current vs expected behavior.",
|
||||
@@ -112,8 +112,8 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
pi.registerTool({
|
||||
name: "kb_task_list",
|
||||
label: "KB: List Tasks",
|
||||
description: "List all tasks on the kb board, grouped by column.",
|
||||
promptSnippet: "List all tasks on the kb board grouped by column",
|
||||
description: "List all tasks on the Fusion board, grouped by column.",
|
||||
promptSnippet: "List all tasks on the Fusion board grouped by column",
|
||||
parameters: Type.Object({
|
||||
column: Type.Optional(
|
||||
StringEnum([...COLUMNS] as unknown as string[], {
|
||||
@@ -171,7 +171,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
name: "kb_task_show",
|
||||
label: "KB: Show Task",
|
||||
description: "Show full details for a task including steps, progress, and log entries.",
|
||||
promptSnippet: "Show full details for a kb task",
|
||||
promptSnippet: "Show full details for a Fusion task",
|
||||
parameters: Type.Object({
|
||||
id: Type.String({ description: "Task ID (e.g. KB-001)" }),
|
||||
}),
|
||||
@@ -252,7 +252,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
description:
|
||||
"Attach a file to a task. Supports images (png, jpg, gif, webp) and " +
|
||||
"text files (txt, log, json, yaml, yml, toml, csv, xml).",
|
||||
promptSnippet: "Attach a file to a kb task",
|
||||
promptSnippet: "Attach a file to a Fusion task",
|
||||
parameters: Type.Object({
|
||||
id: Type.String({ description: "Task ID (e.g. KB-001)" }),
|
||||
path: Type.String({ description: "Path to the file to attach" }),
|
||||
@@ -302,7 +302,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
label: "KB: Pause Task",
|
||||
description:
|
||||
"Pause a task — stops all automated agent and scheduler interaction for this task.",
|
||||
promptSnippet: "Pause a kb task (stops automation)",
|
||||
promptSnippet: "Pause a Fusion task (stops automation)",
|
||||
parameters: Type.Object({
|
||||
id: Type.String({ description: "Task ID (e.g. KB-001)" }),
|
||||
}),
|
||||
@@ -325,7 +325,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
label: "KB: Unpause Task",
|
||||
description:
|
||||
"Unpause a task — resumes automated agent and scheduler interaction.",
|
||||
promptSnippet: "Unpause a kb task (resumes automation)",
|
||||
promptSnippet: "Unpause a Fusion task (resumes automation)",
|
||||
parameters: Type.Object({
|
||||
id: Type.String({ description: "Task ID (e.g. KB-001)" }),
|
||||
}),
|
||||
@@ -348,7 +348,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
label: "KB: Retry Task",
|
||||
description:
|
||||
"Retry a failed task — clears the error state and moves it back to the todo column for re-execution.",
|
||||
promptSnippet: "Retry a failed kb task (clears error, moves to todo)",
|
||||
promptSnippet: "Retry a failed Fusion task (clears error, moves to todo)",
|
||||
promptGuidelines: [
|
||||
"Use when a task has failed and needs to be retried from the beginning",
|
||||
"Only tasks in 'failed' state can be retried",
|
||||
@@ -407,7 +407,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
"Duplicate an existing task, creating a fresh copy in triage. " +
|
||||
"Copies the title and description but resets all execution state. " +
|
||||
"The AI triage agent will re-specify the new task.",
|
||||
promptSnippet: "Duplicate a kb task (creates copy in triage)",
|
||||
promptSnippet: "Duplicate a Fusion task (creates copy in triage)",
|
||||
promptGuidelines: [
|
||||
"Use when a task needs to be re-done, split, or used as a template",
|
||||
"The duplicated task will be placed in triage for re-specification",
|
||||
@@ -474,7 +474,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
description:
|
||||
"Archive a done task (move from done → archived). " +
|
||||
"Archived tasks are preserved for historical reference but moved out of the main board view.",
|
||||
promptSnippet: "Archive a done kb task (moves to archived column)",
|
||||
promptSnippet: "Archive a done Fusion task (moves to archived column)",
|
||||
promptGuidelines: [
|
||||
"Use to clean up old completed tasks from the done column",
|
||||
"Only tasks in the 'done' column can be archived",
|
||||
@@ -503,7 +503,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
description:
|
||||
"Unarchive an archived task (move from archived → done). " +
|
||||
"Restores the task to the done column.",
|
||||
promptSnippet: "Unarchive a kb task (restores to done column)",
|
||||
promptSnippet: "Unarchive a Fusion task (restores to done column)",
|
||||
promptGuidelines: [
|
||||
"Use to restore an archived task back to the done column",
|
||||
"Only tasks in the 'archived' column can be unarchived",
|
||||
@@ -529,9 +529,9 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
name: "kb_task_delete",
|
||||
label: "KB: Delete Task",
|
||||
description:
|
||||
"Permanently delete a task from the kb board. " +
|
||||
"Permanently delete a task from the Fusion board. " +
|
||||
"Tasks are deleted immediately and cannot be recovered.",
|
||||
promptSnippet: "Delete a kb task",
|
||||
promptSnippet: "Delete a Fusion task",
|
||||
promptGuidelines: [
|
||||
"Use for cleaning up test tasks or tasks created in error",
|
||||
"Tasks are permanently deleted and cannot be recovered",
|
||||
@@ -558,12 +558,12 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
name: "kb_task_import_github",
|
||||
label: "KB: Import GitHub Issues",
|
||||
description:
|
||||
"Import GitHub issues as kb tasks. Fetches open issues from a repository " +
|
||||
"Import GitHub issues as Fusion tasks. Fetches open issues from a repository " +
|
||||
"and creates tasks in the triage column. Each task includes the issue title " +
|
||||
"and body with a link to the source issue.",
|
||||
promptSnippet: "Import GitHub issues as kb tasks",
|
||||
promptSnippet: "Import GitHub issues as Fusion tasks",
|
||||
promptGuidelines: [
|
||||
"Use for syncing GitHub issue backlog to kb board",
|
||||
"Use for syncing GitHub issue backlog to Fusion board",
|
||||
"Uses gh CLI authentication when available (run 'gh auth login')",
|
||||
"Falls back to GITHUB_TOKEN env var for private repositories without gh CLI",
|
||||
"Use --limit to control how many issues to import (default: 30)",
|
||||
@@ -648,9 +648,9 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
name: "kb_task_import_github_issue",
|
||||
label: "KB: Import GitHub Issue",
|
||||
description:
|
||||
"Import a specific GitHub issue as a kb task. Fetches the issue by number " +
|
||||
"Import a specific GitHub issue as a Fusion task. Fetches the issue by number " +
|
||||
"and creates a single task in the triage column with the issue title and body.",
|
||||
promptSnippet: "Import a specific GitHub issue as a kb task",
|
||||
promptSnippet: "Import a specific GitHub issue as a Fusion task",
|
||||
promptGuidelines: [
|
||||
"Use for importing a single known issue by its number",
|
||||
"Uses gh CLI authentication when available (run 'gh auth login')",
|
||||
@@ -680,7 +680,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
const headers: Record<string, string> = {
|
||||
Accept: "application/vnd.github+json",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
"User-Agent": "kb-cli/1.0",
|
||||
"User-Agent": "fusion-cli/1.0",
|
||||
};
|
||||
|
||||
if (token) {
|
||||
@@ -819,7 +819,7 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
const headers: Record<string, string> = {
|
||||
Accept: "application/vnd.github+json",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
"User-Agent": "kb-cli/1.0",
|
||||
"User-Agent": "fusion-cli/1.0",
|
||||
};
|
||||
|
||||
if (token) {
|
||||
@@ -975,46 +975,46 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
},
|
||||
});
|
||||
|
||||
// ── /kb command — start the dashboard + engine ───────────────────
|
||||
// ── /fn command — start the dashboard + engine ───────────────────
|
||||
|
||||
let dashboardProcess: ChildProcess | null = null;
|
||||
let dashboardPort: number | null = null;
|
||||
|
||||
pi.registerCommand("kb", {
|
||||
description: "Start (or stop) the kb dashboard and AI engine",
|
||||
pi.registerCommand("fn", {
|
||||
description: "Start (or stop) the Fusion dashboard and AI engine",
|
||||
handler: async (args, ctx) => {
|
||||
const trimmed = (args ?? "").trim();
|
||||
|
||||
// /kb stop — kill the dashboard
|
||||
// /fn stop — kill the dashboard
|
||||
if (trimmed === "stop") {
|
||||
if (dashboardProcess) {
|
||||
dashboardProcess.kill("SIGINT");
|
||||
dashboardProcess = null;
|
||||
dashboardPort = null;
|
||||
ctx.ui.setStatus("kb", "");
|
||||
ctx.ui.notify("kb dashboard stopped", "info");
|
||||
ctx.ui.setStatus("fn", "");
|
||||
ctx.ui.notify("Fusion dashboard stopped", "info");
|
||||
} else {
|
||||
ctx.ui.notify("kb dashboard is not running", "warning");
|
||||
ctx.ui.notify("Fusion dashboard is not running", "warning");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// /kb status
|
||||
// /fn status
|
||||
if (trimmed === "status") {
|
||||
if (dashboardProcess && !dashboardProcess.killed) {
|
||||
ctx.ui.notify(`kb dashboard running on http://localhost:${dashboardPort}`, "info");
|
||||
ctx.ui.notify(`Fusion dashboard running on http://localhost:${dashboardPort}`, "info");
|
||||
} else {
|
||||
dashboardProcess = null;
|
||||
dashboardPort = null;
|
||||
ctx.ui.notify("kb dashboard is not running", "info");
|
||||
ctx.ui.notify("Fusion dashboard is not running", "info");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// /kb [port] — start the dashboard
|
||||
// /fn [port] — start the dashboard
|
||||
if (dashboardProcess && !dashboardProcess.killed) {
|
||||
ctx.ui.notify(
|
||||
`kb dashboard already running on http://localhost:${dashboardPort}. Use /kb stop first.`,
|
||||
`Fusion dashboard already running on http://localhost:${dashboardPort}. Use /fn stop first.`,
|
||||
"warning",
|
||||
);
|
||||
return;
|
||||
@@ -1022,8 +1022,8 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
|
||||
const port = trimmed ? parseInt(trimmed, 10) || 4040 : 4040;
|
||||
|
||||
// Find the kb binary: prefer local node_modules, then global
|
||||
const child = spawn("kb", ["dashboard", "--port", String(port)], {
|
||||
// Find the fn binary: prefer local node_modules, then global
|
||||
const child = spawn("fn", ["dashboard", "--port", String(port)], {
|
||||
cwd: ctx.cwd,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
detached: false,
|
||||
@@ -1033,21 +1033,21 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
dashboardProcess = child;
|
||||
dashboardPort = port;
|
||||
|
||||
// Watch for early exit (e.g. kb not found)
|
||||
// Watch for early exit (e.g. fn not found)
|
||||
child.on("error", (err) => {
|
||||
dashboardProcess = null;
|
||||
dashboardPort = null;
|
||||
ctx.ui.setStatus("kb", "");
|
||||
ctx.ui.notify(`Failed to start kb dashboard: ${err.message}`, "error");
|
||||
ctx.ui.setStatus("fn", "");
|
||||
ctx.ui.notify(`Failed to start Fusion dashboard: ${err.message}`, "error");
|
||||
});
|
||||
|
||||
child.on("exit", (code) => {
|
||||
if (dashboardProcess === child) {
|
||||
dashboardProcess = null;
|
||||
dashboardPort = null;
|
||||
ctx.ui.setStatus("kb", "");
|
||||
ctx.ui.setStatus("fn", "");
|
||||
if (code !== 0 && code !== null) {
|
||||
ctx.ui.notify(`kb dashboard exited with code ${code}`, "warning");
|
||||
ctx.ui.notify(`Fusion dashboard exited with code ${code}`, "warning");
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1057,9 +1057,9 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
|
||||
if (dashboardProcess && !dashboardProcess.killed) {
|
||||
const url = `http://localhost:${port}`;
|
||||
ctx.ui.notify(`kb dashboard started on ${url} (AI engine active)`, "info");
|
||||
ctx.ui.notify(`Fusion dashboard started on ${url} (AI engine active)`, "info");
|
||||
const link = `\x1b]8;;${url}\x1b\\${url}\x1b]8;;\x1b\\`;
|
||||
ctx.ui.setStatus("kb", `kb ● ${link}`);
|
||||
ctx.ui.setStatus("fn", `Fusion ● ${link}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user