Skip to content
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
86a8c52
chore: setup docs for GitHub Pages
laynepenney Jan 17, 2026
72a907b
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 17, 2026
4c39457
docs: add website link to README
laynepenney Jan 17, 2026
3bc0931
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 17, 2026
caee4f8
docs: add demo GIF to README
laynepenney Jan 17, 2026
e68bcc4
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 17, 2026
27d917b
fix: bracketed paste multi-line handling
laynepenney Jan 17, 2026
4c43e81
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 17, 2026
3274788
fix: add subcommands property to Command interface
laynepenney Jan 17, 2026
167fad2
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 17, 2026
59c8645
fix: rewrite bracketed paste to capture and display summary
laynepenney Jan 17, 2026
1249708
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 17, 2026
297b939
fix: add /log alias for /git log command
laynepenney Jan 17, 2026
1301d51
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 17, 2026
b9eb375
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 17, 2026
ab99575
docs: add TypeDoc, CHANGELOG, and ollama-cloud mentions
laynepenney Jan 18, 2026
92bf77e
docs: enhance PR review process for AI agents
laynepenney Jan 18, 2026
bc779fa
fix: update ollama-cloud to use ollama.com with API key auth
laynepenney Jan 18, 2026
21295d1
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 18, 2026
f509d62
feat: default RAG embeddings to Ollama instead of OpenAI
laynepenney Jan 18, 2026
24ba03e
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 18, 2026
f508abd
Merge remote-tracking branch 'origin/main' into dev
laynepenney Jan 18, 2026
1a06949
feat: add ! and ? CLI shortcuts
laynepenney Jan 18, 2026
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
69 changes: 69 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import { readFileSync, appendFileSync, existsSync, statSync } from 'fs';
import { glob } from 'node:fs/promises';
import { homedir } from 'os';
import { spawn } from 'child_process';
import { join } from 'path';

// History configuration - allow override for testing
Expand Down Expand Up @@ -448,6 +449,10 @@
* @param projectInfo - Detected information about the current project, if any.
*/
function showHelp(projectInfo: ProjectInfo | null): void {
console.log(chalk.bold('\nShortcuts:'));
console.log(chalk.dim(' !<command> - Run shell command directly (e.g., !ls, !git status)'));
console.log(chalk.dim(' ?[topic] - Show help, optionally filtered by topic'));

console.log(chalk.bold('\nBuilt-in Commands:'));
console.log(chalk.dim(' /help - Show this help message'));
console.log(chalk.dim(' /clear - Clear conversation history'));
Expand Down Expand Up @@ -2724,6 +2729,70 @@
// Audit log user input
auditLogger.userInput(trimmed);

// Handle ! prefix for direct shell commands
if (trimmed.startsWith('!')) {
const shellCommand = trimmed.slice(1).trim();
if (!shellCommand) {
console.log(chalk.dim('Usage: !<command> - run a shell command directly'));
rl.prompt();
return;
}

// Execute command with inherited stdio for real-time output
const child = spawn(shellCommand, [], {
shell: true,
stdio: 'inherit',
cwd: process.cwd(),
});

child.on('close', (code) => {
if (code !== 0) {
console.log(chalk.dim(`Exit code: ${code}`));
}
rl.prompt();
});

child.on('error', (err) => {
console.log(chalk.red(`Error: ${err.message}`));
rl.prompt();
});

return;
}

// Handle ? prefix for help
if (trimmed === '?' || trimmed.startsWith('?')) {
const topic = trimmed.slice(1).trim();
if (topic) {
// Search for commands matching the topic
const allCommands = getRegisteredCommands();

Check failure on line 2768 in src/index.ts

View workflow job for this annotation

GitHub Actions / Test & Coverage

Cannot find name 'getRegisteredCommands'. Did you mean 'registerCodeCommands'?

Check failure on line 2768 in src/index.ts

View workflow job for this annotation

GitHub Actions / Type Check

Cannot find name 'getRegisteredCommands'. Did you mean 'registerCodeCommands'?
const matches = allCommands.filter(
(cmd) =>

Check failure on line 2770 in src/index.ts

View workflow job for this annotation

GitHub Actions / Test & Coverage

Parameter 'cmd' implicitly has an 'any' type.

Check failure on line 2770 in src/index.ts

View workflow job for this annotation

GitHub Actions / Type Check

Parameter 'cmd' implicitly has an 'any' type.
cmd.name.includes(topic.toLowerCase()) ||
cmd.description.toLowerCase().includes(topic.toLowerCase()) ||
cmd.aliases?.some((a) => a.includes(topic.toLowerCase()))

Check failure on line 2773 in src/index.ts

View workflow job for this annotation

GitHub Actions / Test & Coverage

Parameter 'a' implicitly has an 'any' type.

Check failure on line 2773 in src/index.ts

View workflow job for this annotation

GitHub Actions / Type Check

Parameter 'a' implicitly has an 'any' type.
);

if (matches.length > 0) {
console.log(chalk.bold(`\nCommands matching "${topic}":\n`));
for (const cmd of matches) {
const aliases = cmd.aliases?.length ? chalk.dim(` (${cmd.aliases.join(', ')})`) : '';
console.log(` ${chalk.cyan('/' + cmd.name)}${aliases}`);
console.log(chalk.dim(` ${cmd.description}`));
if (cmd.usage) {
console.log(chalk.dim(` Usage: ${cmd.usage}`));
}
}
} else {
console.log(chalk.dim(`No commands found matching "${topic}"`));
}
} else {
showHelp(projectInfo);
}
rl.prompt();
return;
}

// Handle built-in commands
if (trimmed === '/exit' || trimmed === '/quit') {
console.log(chalk.dim('\nGoodbye!'));
Expand Down
Loading