sidetable is a Go CLI and library for managing a project-local tool area (for example .$USER/) and delegating external tools.
Define tools in config, then execute them as sidetable <tool-or-alias> ....
Each tool gets its own directory under your configured local area, so you can keep per-project state in a predictable layout.
brew install --cask sushichan044/tap/sidetableUsing mise
mise install github:sushichan044/sidetablego install github.com/sushichan044/sidetable/cmd/sidetable@latestDownload the latest release binaries from Releases.
# List tools and aliases
$ sidetable list
NAME KIND TARGET DESCRIPTION
example tool - An example tool
ex alias example Shortcut for example
# Run a tool or alias
$ sidetable example arg1 arg2
$ sidetable ex arg1 arg2
# Show help
$ sidetable --help
$ sidetable help
# Show version
$ sidetable --versionExample: integrate with ghq
directory: ".private"
tools:
ghq:
run: "ghq"
env:
GHQ_ROOT: "{{.ToolDir}}"
description: "Manage repositories in project-local directory"
aliases:
q:
tool: "ghq"
args:
prepend:
- "get"
- "-u"
description: "Clone repository into project-local directory"Example:
$ cd ~/myproject
$ sidetable q https://github.com/example/repo
# Or call the tool directly:
# sidetable ghq get -u https://github.com/example/repo
# => cloned into ~/myproject/.private/ghq/github.com/example/repoYou can enable shell completion for sidetable commands, including tools and aliases defined in config.
# bash
source <(sidetable completion bash)
# zsh
source <(sidetable completion zsh)
# fish
sidetable completion fish | source
# PowerShell
sidetable completion powershell | Out-String | Invoke-Expressionconfig.yml is searched in the following order:
- If
SIDETABLE_CONFIG_DIRis set:$SIDETABLE_CONFIG_DIR/config.yml - Otherwise:
$XDG_CONFIG_HOME/sidetable/config.yml(or~/.config/sidetable/config.ymlifXDG_CONFIG_HOMEis not set)
# Required. Project-local tool area name (relative path).
directory: ".sidetable"
tools:
ghq:
# Required. Program name to execute.
# Templating: allowed.
run: "ghq"
# Optional. Arguments to inject.
# Order: tool.prepend + userArgs + tool.append
# Templating: allowed.
args:
# prepend:
# - "--some-flag"
# append:
# - "--some-flag"
# Optional. Override environment variables for the tool.
# Templating: allowed.
env:
GHQ_ROOT: "{{.ToolDir}}"
# Optional. Description shown in `sidetable list`.
description: "ghq wrapper with project-local root"
note:
run: "{{.ConfigDir}}/vim-note.sh"
args:
append:
- "{{.ToolDir}}/note.md"
description: "Open project note file"
# Optional. Aliases for tools.
aliases:
gg:
# Required. Target tool name defined in `tools`.
tool: "ghq"
# Optional. Arguments to inject.
# Order: alias.prepend + tool.prepend + userArgs + tool.append + alias.append
# Templating: allowed.
args:
prepend:
- "get"
- "-u"
# append:
# - "--some-flag"
# Optional. Description shown in `sidetable list`.
description: "ghq get shortcut"These fields are treated as Go text/template and rendered with the following variables.
tools.<toolName>.runtools.<toolName>.args.prependtools.<toolName>.args.appendtools.<toolName>.env.<envVar>aliases.<aliasName>.args.prependaliases.<aliasName>.args.append
| Variable | Description |
|---|---|
.WorkspaceRoot |
current directory when running sidetable |
.ToolDir |
.WorkspaceRoot/<directory>/<toolName> |
.ConfigDir |
directory containing the config file |
All directory variables are absolute paths.
Arguments are concatenated in the following order.
alias.prepend + tool.prepend + userArgs + tool.append + alias.append
Example:
tools:
example:
run: "mycommand"
args:
prepend:
- "--flag"
append:
- "--output=result.txt"
aliases:
ex:
tool: "example"
args:
prepend:
- "--alias-start"
append:
- "--alias-end"$ sidetable ex arg1 arg2
# Executed command:
# mycommand --alias-start --flag arg1 arg2 --output=result.txt --alias-end- Go 1.25+
- mise (optional)
# Run tests
mise run test
# Format code
mise run fmt
# Run lint
mise run lint
# Fix lint issues
mise run lint-fix
# Build cross-platform snapshot binaries
mise run build-snapshot
# Remove generated files
mise run cleanIssues and PRs are welcome.