Add development plan with 13 milestone specifications
- docs/plan.md: Master roadmap with phases and priorities - docs/milestones/01-13: Detailed specs for each feature - Updated CLAUDE.md with plan references and build commands Milestones cover: - Phase 1: Temporal versioning, auto-capture, context injection, codebase indexing - Phase 2: Daily journal, content ingestion, graph visualization, import/export - Phase 3: Multi-graph, smart retrieval, TUI dashboard, browser extension, shell completions
This commit is contained in:
396
docs/milestones/13-shell-completions.md
Normal file
396
docs/milestones/13-shell-completions.md
Normal file
@@ -0,0 +1,396 @@
|
||||
# Milestone 13: Shell Completions
|
||||
|
||||
## Overview
|
||||
|
||||
Auto-completion for Cortex CLI in Bash, Zsh, Fish, and PowerShell. Tab-complete commands, node IDs, tags, and options.
|
||||
|
||||
## Motivation
|
||||
|
||||
- Tab completion is expected in modern CLIs
|
||||
- Reduces typing and errors
|
||||
- Helps discoverability of commands
|
||||
- Professional polish
|
||||
|
||||
## Features
|
||||
|
||||
### 13.1 Command Completion
|
||||
|
||||
```bash
|
||||
cortex <TAB>
|
||||
# add children decay export graph index journal link list query remove serve show update
|
||||
```
|
||||
|
||||
### 13.2 Option Completion
|
||||
|
||||
```bash
|
||||
cortex add --<TAB>
|
||||
# --title --content --tags --status --section --help
|
||||
```
|
||||
|
||||
### 13.3 Node ID Completion
|
||||
|
||||
```bash
|
||||
cortex show <TAB>
|
||||
# abc123 def456 ghi789 (recent node IDs)
|
||||
|
||||
cortex show abc<TAB>
|
||||
# abc123 abc456 (matching prefixes)
|
||||
```
|
||||
|
||||
### 13.4 Tag Completion
|
||||
|
||||
```bash
|
||||
cortex list --tags <TAB>
|
||||
# auth backend security api docs (existing tags)
|
||||
```
|
||||
|
||||
### 13.5 Kind/Status Completion
|
||||
|
||||
```bash
|
||||
cortex add <TAB>
|
||||
# memory component task decision
|
||||
|
||||
cortex list --status <TAB>
|
||||
# active todo done deprecated
|
||||
```
|
||||
|
||||
### 13.6 Graph Completion
|
||||
|
||||
```bash
|
||||
cortex use <TAB>
|
||||
# default work personal myproject
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
### Completion Generator
|
||||
|
||||
```typescript
|
||||
// src/cli/completions/index.ts
|
||||
export function generateCompletions(shell: 'bash' | 'zsh' | 'fish' | 'powershell'): string {
|
||||
switch (shell) {
|
||||
case 'bash':
|
||||
return generateBashCompletions();
|
||||
case 'zsh':
|
||||
return generateZshCompletions();
|
||||
case 'fish':
|
||||
return generateFishCompletions();
|
||||
case 'powershell':
|
||||
return generatePowerShellCompletions();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Bash Completions
|
||||
|
||||
```bash
|
||||
# Generated by cortex completions bash
|
||||
_cortex_completions() {
|
||||
local cur prev words cword
|
||||
_init_completion || return
|
||||
|
||||
local commands="add children decay export graph index journal link list query remove serve show update use graphs"
|
||||
local kinds="memory component task decision"
|
||||
local statuses="active todo doing done deprecated"
|
||||
|
||||
case "${prev}" in
|
||||
cortex)
|
||||
COMPREPLY=($(compgen -W "${commands}" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
add)
|
||||
COMPREPLY=($(compgen -W "${kinds}" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--kind)
|
||||
COMPREPLY=($(compgen -W "${kinds}" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--status)
|
||||
COMPREPLY=($(compgen -W "${statuses}" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--tags)
|
||||
# Dynamic: fetch existing tags
|
||||
local tags=$(cortex --get-tags 2>/dev/null)
|
||||
COMPREPLY=($(compgen -W "${tags}" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
show|update|remove|link|children)
|
||||
# Dynamic: fetch node IDs
|
||||
local nodes=$(cortex --get-nodes "${cur}" 2>/dev/null)
|
||||
COMPREPLY=($(compgen -W "${nodes}" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
use)
|
||||
# Dynamic: fetch graphs
|
||||
local graphs=$(cortex --get-graphs 2>/dev/null)
|
||||
COMPREPLY=($(compgen -W "${graphs}" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Options
|
||||
if [[ "${cur}" == -* ]]; then
|
||||
local opts="--help --version --title --content --tags --status --kind --limit --format"
|
||||
COMPREPLY=($(compgen -W "${opts}" -- "${cur}"))
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
complete -F _cortex_completions cortex
|
||||
```
|
||||
|
||||
### Zsh Completions
|
||||
|
||||
```zsh
|
||||
#compdef cortex
|
||||
|
||||
_cortex() {
|
||||
local -a commands
|
||||
commands=(
|
||||
'add:Add a node to the knowledge graph'
|
||||
'query:Search the knowledge graph'
|
||||
'show:Show a node and its connections'
|
||||
'list:List nodes'
|
||||
'update:Update a node'
|
||||
'remove:Remove a node'
|
||||
'link:Create a link between nodes'
|
||||
'graph:Visualize the knowledge graph'
|
||||
'children:List child nodes'
|
||||
'journal:Daily journal'
|
||||
'index:Index project'
|
||||
'serve:Start web server'
|
||||
'decay:Mark old nodes as stale'
|
||||
'use:Switch active graph'
|
||||
'graphs:Manage graphs'
|
||||
)
|
||||
|
||||
local -a kinds=(memory component task decision)
|
||||
local -a statuses=(active todo doing done deprecated)
|
||||
|
||||
_arguments -C \
|
||||
'1:command:->command' \
|
||||
'*::arg:->args'
|
||||
|
||||
case "$state" in
|
||||
command)
|
||||
_describe -t commands 'cortex commands' commands
|
||||
;;
|
||||
args)
|
||||
case "$words[1]" in
|
||||
add)
|
||||
_arguments \
|
||||
'1:kind:(memory component task decision)' \
|
||||
'--title[Node title]:title:' \
|
||||
'--content[Node content]:content:' \
|
||||
'--tags[Tags]:tags:->tags' \
|
||||
'--status[Status]:status:(active todo doing done deprecated)'
|
||||
;;
|
||||
show|update|remove|children)
|
||||
_arguments '1:node:->nodes'
|
||||
;;
|
||||
link)
|
||||
_arguments \
|
||||
'1:from:->nodes' \
|
||||
'2:to:->nodes' \
|
||||
'--type[Edge type]:type:(depends_on contains implements blocked_by subtask_of relates_to supersedes about)'
|
||||
;;
|
||||
list)
|
||||
_arguments \
|
||||
'--kind[Filter by kind]:kind:(memory component task decision)' \
|
||||
'--status[Filter by status]:status:(active todo doing done deprecated)' \
|
||||
'--tags[Filter by tags]:tags:->tags'
|
||||
;;
|
||||
use)
|
||||
_arguments '1:graph:->graphs'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$state" in
|
||||
nodes)
|
||||
local -a nodes
|
||||
nodes=(${(f)"$(cortex --get-nodes 2>/dev/null)"})
|
||||
_describe -t nodes 'nodes' nodes
|
||||
;;
|
||||
tags)
|
||||
local -a tags
|
||||
tags=(${(f)"$(cortex --get-tags 2>/dev/null)"})
|
||||
_describe -t tags 'tags' tags
|
||||
;;
|
||||
graphs)
|
||||
local -a graphs
|
||||
graphs=(${(f)"$(cortex --get-graphs 2>/dev/null)"})
|
||||
_describe -t graphs 'graphs' graphs
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_cortex
|
||||
```
|
||||
|
||||
### Fish Completions
|
||||
|
||||
```fish
|
||||
# cortex.fish
|
||||
complete -c cortex -f
|
||||
|
||||
# Commands
|
||||
complete -c cortex -n __fish_use_subcommand -a add -d 'Add a node'
|
||||
complete -c cortex -n __fish_use_subcommand -a query -d 'Search'
|
||||
complete -c cortex -n __fish_use_subcommand -a show -d 'Show node'
|
||||
complete -c cortex -n __fish_use_subcommand -a list -d 'List nodes'
|
||||
complete -c cortex -n __fish_use_subcommand -a update -d 'Update node'
|
||||
complete -c cortex -n __fish_use_subcommand -a remove -d 'Remove node'
|
||||
complete -c cortex -n __fish_use_subcommand -a link -d 'Link nodes'
|
||||
complete -c cortex -n __fish_use_subcommand -a graph -d 'Visualize graph'
|
||||
|
||||
# Kinds
|
||||
complete -c cortex -n '__fish_seen_subcommand_from add' -a 'memory component task decision'
|
||||
|
||||
# Dynamic node completion
|
||||
complete -c cortex -n '__fish_seen_subcommand_from show update remove' -a '(cortex --get-nodes)'
|
||||
|
||||
# Tags
|
||||
complete -c cortex -n '__fish_seen_subcommand_from list' -l tags -a '(cortex --get-tags)'
|
||||
```
|
||||
|
||||
### PowerShell Completions
|
||||
|
||||
```powershell
|
||||
# cortex.ps1
|
||||
Register-ArgumentCompleter -Native -CommandName cortex -ScriptBlock {
|
||||
param($wordToComplete, $commandAst, $cursorPosition)
|
||||
|
||||
$commands = @('add', 'query', 'show', 'list', 'update', 'remove', 'link', 'graph', 'children', 'journal', 'index', 'serve', 'decay', 'use', 'graphs')
|
||||
$kinds = @('memory', 'component', 'task', 'decision')
|
||||
$statuses = @('active', 'todo', 'doing', 'done', 'deprecated')
|
||||
|
||||
$elements = $commandAst.CommandElements
|
||||
$command = $elements[1].Value
|
||||
|
||||
if ($elements.Count -eq 2) {
|
||||
$commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||
}
|
||||
}
|
||||
elseif ($command -eq 'add' -and $elements.Count -eq 3) {
|
||||
$kinds | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||
}
|
||||
}
|
||||
elseif ($command -in @('show', 'update', 'remove')) {
|
||||
$nodes = cortex --get-nodes $wordToComplete 2>$null
|
||||
$nodes -split "`n" | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
||||
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CLI Support Commands
|
||||
|
||||
```typescript
|
||||
// Hidden commands for completion scripts
|
||||
program
|
||||
.command('--get-nodes [prefix]', { hidden: true })
|
||||
.action(async (prefix) => {
|
||||
const nodes = await listNodes({ limit: 20 });
|
||||
const filtered = prefix
|
||||
? nodes.filter(n => n.id.startsWith(prefix))
|
||||
: nodes;
|
||||
console.log(filtered.map(n => `${n.id.slice(0, 8)}\t${n.title}`).join('\n'));
|
||||
});
|
||||
|
||||
program
|
||||
.command('--get-tags', { hidden: true })
|
||||
.action(async () => {
|
||||
const tags = await getAllTags();
|
||||
console.log(tags.join('\n'));
|
||||
});
|
||||
|
||||
program
|
||||
.command('--get-graphs', { hidden: true })
|
||||
.action(async () => {
|
||||
const graphs = listGraphs();
|
||||
console.log(graphs.map(g => g.name).join('\n'));
|
||||
});
|
||||
```
|
||||
|
||||
## CLI Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `cortex completions bash` | Output bash completions |
|
||||
| `cortex completions zsh` | Output zsh completions |
|
||||
| `cortex completions fish` | Output fish completions |
|
||||
| `cortex completions powershell` | Output PowerShell completions |
|
||||
| `cortex completions install` | Auto-install for current shell |
|
||||
|
||||
## Installation Instructions
|
||||
|
||||
### Bash
|
||||
```bash
|
||||
cortex completions bash > /etc/bash_completion.d/cortex
|
||||
# or
|
||||
cortex completions bash >> ~/.bashrc
|
||||
```
|
||||
|
||||
### Zsh
|
||||
```bash
|
||||
cortex completions zsh > ~/.zsh/completions/_cortex
|
||||
# Add to ~/.zshrc: fpath=(~/.zsh/completions $fpath)
|
||||
```
|
||||
|
||||
### Fish
|
||||
```bash
|
||||
cortex completions fish > ~/.config/fish/completions/cortex.fish
|
||||
```
|
||||
|
||||
### PowerShell
|
||||
```powershell
|
||||
cortex completions powershell >> $PROFILE
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
- [ ] Bash completions work
|
||||
- [ ] Zsh completions work
|
||||
- [ ] Fish completions work
|
||||
- [ ] PowerShell completions work
|
||||
- [ ] Dynamic node ID completion
|
||||
- [ ] Dynamic tag completion
|
||||
- [ ] Install command works
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] All four shells supported
|
||||
- [ ] Commands and options complete
|
||||
- [ ] Node IDs complete dynamically
|
||||
- [ ] Tags complete dynamically
|
||||
- [ ] Easy installation command
|
||||
- [ ] No errors on missing cortex binary
|
||||
|
||||
## Estimated Effort
|
||||
|
||||
- Bash completions: 2 hours
|
||||
- Zsh completions: 3 hours
|
||||
- Fish completions: 2 hours
|
||||
- PowerShell completions: 2 hours
|
||||
- CLI support commands: 2 hours
|
||||
- Install command: 1 hour
|
||||
- Testing: 2 hours
|
||||
- **Total: ~14 hours**
|
||||
|
||||
## Dependencies
|
||||
|
||||
- None
|
||||
|
||||
## References
|
||||
|
||||
- [Bash Programmable Completion](https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html)
|
||||
- [Zsh Completion System](https://zsh.sourceforge.io/Doc/Release/Completion-System.html)
|
||||
- [Fish Completions](https://fishshell.com/docs/current/completions.html)
|
||||
- [PowerShell Tab Completion](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/register-argumentcompleter)
|
||||
Reference in New Issue
Block a user