Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions knowledge.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,25 @@ Codebuff is a tool for editing codebases via natural language instruction to Buf
- ESC key to toggle menu or stop AI response
- CTRL+C to exit the application

### Shell Shims (Direct Commands)

Codebuff supports shell shims for direct command invocation without the `codebuff` prefix.

- **Cross-platform**: Works on Windows (CMD/PowerShell), macOS, and Linux (bash/zsh/fish)
- **Store integration**: Uses fully qualified agent IDs from the agent store
- **Easy management**: Install, update, list, and uninstall shims via CLI commands### Quick Start (Recommended)

```bash
# One-step setup: install and add to PATH automatically
codebuff shims install codebuff/base-lite@1.0.0

# Use immediately in current session (follow the printed instruction)
eval "$(codebuff shims env)"

# Now use direct commands!
base-lite "fix this bug" # Works right away!
```

## Package Management

- Use Bun for all package management operations
Expand Down Expand Up @@ -326,11 +345,13 @@ Templates are maintained in the codebuff community repo. Each directory correspo
**Important**: When adding database indexes or schema changes, modify the schema file directly (`common/src/db/schema.ts`) using Drizzle's index syntax, then run the migration generation script to create the actual migration files.

**Do NOT** write migration SQL files directly. The proper workflow is:

1. Update `common/src/db/schema.ts` with new indexes using Drizzle syntax
2. Run the migration generation script to create the SQL migration files
3. Apply the migrations using the deployment process

Example of adding performance indexes:

```typescript
index('idx_table_optimized')
.on(table.column1, table.column2)
Expand Down
5 changes: 5 additions & 0 deletions npm-app/src/cli-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,9 @@ export const cliOptions: CliParam[] = [
menuDescription: 'Log subagent messages to trace files',
hidden: false,
},
{
flags: '--force',
description: 'Force overwrite existing shims',
hidden: true,
},
]
143 changes: 143 additions & 0 deletions npm-app/src/cli-handlers/shims.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { red } from 'picocolors'

import {
installShims,
uninstallShims,
listShims,
updateShims,
doctorShims,
upgradeShims,
} from '../shell-dispatcher'
import { logger } from '../utils/logger'

/**
* Handle the 'shims install' command
*/
export async function handleShimsInstall(
agentSpecs: string[],
options: { force?: boolean } = {},
): Promise<void> {
try {
if (!agentSpecs || agentSpecs.length === 0) {
console.error(red('Error: No agent IDs specified to install as shims.'))
console.log(
'Usage: codebuff shims install <publisher/agent-id@version> [publisher/agent-id@version:custom-command] ...',
)
process.exit(1)
}
installShims(agentSpecs, options)
} catch (error) {
logger.error(
{
errorMessage: error instanceof Error ? error.message : String(error),
errorStack: error instanceof Error ? error.stack : undefined,
agentSpecs,
options,
},
'Error installing shims',
)
console.error(red(`Error installing shims: ${error}`))
process.exit(1)
}
}

/**
* Handle the 'shims uninstall' command
*/
export async function handleShimsUninstall(
commandNames?: string[],
): Promise<void> {
try {
uninstallShims(commandNames)
} catch (error) {
logger.error(
{
errorMessage: error instanceof Error ? error.message : String(error),
errorStack: error instanceof Error ? error.stack : undefined,
commandNames,
},
'Error uninstalling shims',
)
console.error(red(`Error uninstalling shims: ${error}`))
process.exit(1)
}
}

/**
* Handle the 'shims list' command
*/
export async function handleShimsList(): Promise<void> {
try {
listShims()
} catch (error) {
logger.error(
{
errorMessage: error instanceof Error ? error.message : String(error),
errorStack: error instanceof Error ? error.stack : undefined,
},
'Error listing shims',
)
console.error(red(`Error listing shims: ${error}`))
process.exit(1)
}
}

/**
* Handle the 'shims update' command
*/
export async function handleShimsUpdate(
commandNames?: string[],
): Promise<void> {
try {
updateShims(commandNames)
} catch (error) {
logger.error(
{
errorMessage: error instanceof Error ? error.message : String(error),
errorStack: error instanceof Error ? error.stack : undefined,
commandNames,
},
'Error updating shims',
)
console.error(red(`Error updating shims: ${error}`))
process.exit(1)
}
}

/**
* Handle the 'shims doctor' command
*/
export async function handleShimsDoctor(): Promise<void> {
try {
doctorShims()
} catch (error) {
logger.error(
{
errorMessage: error instanceof Error ? error.message : String(error),
errorStack: error instanceof Error ? error.stack : undefined,
},
'Error running shims doctor',
)
console.error(red(`Error running shims doctor: ${error}`))
process.exit(1)
}
}

/**
* Handle the 'shims upgrade' command
*/
export async function handleShimsUpgrade(): Promise<void> {
try {
await upgradeShims()
} catch (error) {
logger.error(
{
errorMessage: error instanceof Error ? error.message : String(error),
errorStack: error instanceof Error ? error.stack : undefined,
},
'Error upgrading shims',
)
console.error(red(`Error upgrading shims: ${error}`))
process.exit(1)
}
}
60 changes: 58 additions & 2 deletions npm-app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ import { cliArguments, cliOptions } from './cli-definitions'
import { handlePublish } from './cli-handlers/publish'
import { handleInitAgents } from './cli-handlers/init-agents'
import { handleSaveAgent } from './cli-handlers/save-agent'
import { npmAppVersion, backendUrl } from './config'
import {
handleShimsInstall,
handleShimsUninstall,
handleShimsList,
handleShimsUpdate,
handleShimsDoctor,
handleShimsUpgrade,
} from './cli-handlers/shims'
import { generateEvalCommand } from './shell-dispatcher'
import { npmAppVersion } from './config'
import { createTemplateProject } from './create-template-project'
import { printModeLog, setPrintMode } from './display/print-mode'
import { enableSquashNewlines } from './display/squash-newlines'
Expand Down Expand Up @@ -128,6 +137,13 @@ Examples:
$ codebuff --agent file-picker "find relevant files for authentication"
$ codebuff --agent reviewer --params '{"focus": "security"}' "review this code"

Direct Commands (via shell shims):
$ codebuff shims install codebuff/base-lite@1.0.0 # One-step setup!
$ eval "$(codebuff shims env)" # Run this for immediate use
$ base-lite "fix the bug" # Direct command (after eval)
$ codebuff shims list # List installed shims
$ codebuff shims upgrade # Upgrade all shims to latest versions

For all commands and options, run 'codebuff' and then type 'help'.
`,
)
Expand Down Expand Up @@ -168,6 +184,46 @@ For all commands and options, run 'codebuff' and then type 'help'.
process.exit(0)
}

// Handle shims command
if (args[0] === 'shims') {
const subcommand = args[1]
const subArgs = args.slice(2)

switch (subcommand) {
case 'install':
await handleShimsInstall(subArgs, {
force: options.force,
})
break
case 'uninstall':
case 'remove':
await handleShimsUninstall(subArgs.length > 0 ? subArgs : undefined)
break
case 'list':
await handleShimsList()
break
case 'update':
await handleShimsUpdate(subArgs.length > 0 ? subArgs : undefined)
break
case 'doctor':
await handleShimsDoctor()
break
case 'upgrade':
await handleShimsUpgrade()
break
case 'env':
console.log(generateEvalCommand())
break
default:
console.error(red(`Unknown shims subcommand: ${subcommand}`))
console.log(
'Available subcommands: install, uninstall, list, update, doctor, upgrade, env',
)
process.exit(1)
}
process.exit(0)
}

// Handle deprecated --pro flag
if (options.pro) {
console.error(
Expand Down Expand Up @@ -235,7 +291,7 @@ For all commands and options, run 'codebuff' and then type 'help'.
const filteredArgs = args[0]?.startsWith('/$bunfs') ? args.slice(1) : args

// If first arg is a command like 'publish' or 'save-agent', don't treat it as initial input
const isCommand = ['publish', 'init-agents', 'save-agent'].includes(
const isCommand = ['publish', 'init-agents', 'save-agent', 'shims'].includes(
filteredArgs[0],
)
const initialInput = isCommand ? '' : filteredArgs.join(' ')
Expand Down
Loading
Loading