mirror of
https://github.com/chenasraf/dotfiles.git
synced 2026-05-17 17:28:07 +00:00
feat: create claude skills for sofmani/wand
This commit is contained in:
306
.claude/skills/sofmani/SKILL.md
Normal file
306
.claude/skills/sofmani/SKILL.md
Normal file
@@ -0,0 +1,306 @@
|
||||
---
|
||||
name: sofmani
|
||||
description: Add, edit, or manage sofmani installer entries in sofmani.yml. This skill should be used when the user wants to add software to their provisioning manifest, modify existing installer steps, create cross-platform install groups, or troubleshoot sofmani configuration. Triggers on requests involving sofmani.yml, adding packages/tools to the manifest, or provisioning setup.
|
||||
---
|
||||
|
||||
# Sofmani
|
||||
|
||||
Work with [sofmani](https://github.com/chenasraf/sofmani) (Software Manifest) — a declarative provisioning tool that automates software installations via YAML config. The config file lives at `~/.dotfiles/.config/sofmani.yml`.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### CLI Flags
|
||||
|
||||
| Flag | Purpose |
|
||||
|------|---------|
|
||||
| `-u` / `-U` | Enable/disable update checking |
|
||||
| `-d` / `-D` | Enable/disable debug mode |
|
||||
| `-s` / `-S` | Enable/disable summary |
|
||||
| `-f <filter>` | Filter installers (see below) |
|
||||
| `-m` | Show machine ID |
|
||||
|
||||
Filter syntax: `-f <name>`, `-f tag:<tag>`, `-f type:<type>`. Negate with `!`: `-f "!tag:system"`.
|
||||
|
||||
### Template Variables
|
||||
|
||||
Available in shell commands and `opts` string fields:
|
||||
|
||||
| Variable | Value |
|
||||
|----------|-------|
|
||||
| `{{ .Arch }}` | CPU architecture |
|
||||
| `{{ .ArchAlias }}` | Architecture alias (e.g. `amd64`) |
|
||||
| `{{ .OS }}` | Operating system |
|
||||
| `{{ .DeviceID }}` | Machine unique ID |
|
||||
| `{{ .DeviceIDAlias }}` | Friendly machine name from `machine_aliases` |
|
||||
| `{{ .Tag }}` | Release tag (github-release only) |
|
||||
| `{{ .Version }}` | Version without `v` prefix (github-release only) |
|
||||
|
||||
Environment variables `$DEVICE_ID` and `$DEVICE_ID_ALIAS` are also injected into shell commands.
|
||||
|
||||
## Installer Entry Reference
|
||||
|
||||
Every entry in the `install` array supports these fields:
|
||||
|
||||
| Field | Type | Purpose |
|
||||
|-------|------|---------|
|
||||
| `name` | string (required) | Step identifier |
|
||||
| `type` | string (required) | Installer type |
|
||||
| `tags` | string | Space-separated tags for filtering |
|
||||
| `bin_name` | string | Binary name if different from `name` |
|
||||
| `enabled` | bool/string | Conditional execution (string = shell command) |
|
||||
| `platforms` | object | `only` / `except` arrays: `macos`, `linux`, `windows` |
|
||||
| `machines` | object | `only` / `except` arrays of machine alias names |
|
||||
| `check_installed` | string | Shell command to verify installation |
|
||||
| `check_has_update` | string | Shell command to check for updates |
|
||||
| `pre_install` | string | Shell hook before install |
|
||||
| `post_install` | string | Shell hook after install |
|
||||
| `pre_update` | string | Shell hook before update |
|
||||
| `post_update` | string | Shell hook after update |
|
||||
| `skip_summary` | bool/object | Exclude from summary (`true`, or `{ install: true, update: true }`) |
|
||||
| `env_shell` | object | Platform-specific shell override (e.g. `{ linux: /bin/bash }`) |
|
||||
| `opts` | object | Type-specific options (see below) |
|
||||
|
||||
## Installer Types
|
||||
|
||||
### brew
|
||||
|
||||
Homebrew package. The project defaults restrict brew to macOS only — no need to add `platforms` for brew entries.
|
||||
|
||||
```yaml
|
||||
- name: ripgrep
|
||||
type: brew
|
||||
```
|
||||
|
||||
With tap:
|
||||
|
||||
```yaml
|
||||
- name: sofmani
|
||||
type: brew
|
||||
opts:
|
||||
tap: chenasraf/tap
|
||||
```
|
||||
|
||||
opts: `tap`, `cask` (bool).
|
||||
|
||||
### group
|
||||
|
||||
Sequence multiple steps. The primary pattern for cross-platform installs: brew on macOS + github-release or apt on Linux.
|
||||
|
||||
```yaml
|
||||
- name: lazygit
|
||||
type: group
|
||||
steps:
|
||||
- name: lazygit
|
||||
type: brew
|
||||
- name: lazygit
|
||||
type: github-release
|
||||
platforms:
|
||||
only: ['linux']
|
||||
opts:
|
||||
repository: jesseduffield/lazygit
|
||||
strategy: tar
|
||||
destination: ~/.local/bin
|
||||
download_filename: lazygit_{{ .Version }}_Linux_{{ .ArchAlias }}.tar.gz
|
||||
```
|
||||
|
||||
### shell
|
||||
|
||||
Execute arbitrary shell commands. The most flexible type.
|
||||
|
||||
```yaml
|
||||
- name: git-config
|
||||
type: shell
|
||||
check_installed: git config --global user.name > /dev/null 2>&1
|
||||
opts:
|
||||
command: |
|
||||
git config --global user.name "Name"
|
||||
git config --global user.email "email@example.com"
|
||||
update_command: <same or different command for updates>
|
||||
```
|
||||
|
||||
opts: `command` (required), `update_command`.
|
||||
|
||||
### git
|
||||
|
||||
Clone a git repository.
|
||||
|
||||
```yaml
|
||||
- name: my-plugin
|
||||
type: git
|
||||
opts:
|
||||
repository: https://github.com/user/repo.git
|
||||
destination: ~/.local/share/plugins/repo
|
||||
ref: main
|
||||
```
|
||||
|
||||
opts: `repository` (required), `destination` (required), `ref`.
|
||||
|
||||
GitHub shorthand: `repository: user/repo` expands to `https://github.com/user/repo.git`.
|
||||
|
||||
### github-release
|
||||
|
||||
Download a binary from GitHub releases.
|
||||
|
||||
```yaml
|
||||
- name: tool
|
||||
type: github-release
|
||||
opts:
|
||||
repository: user/tool
|
||||
destination: ~/.local/bin
|
||||
strategy: tar # or: binary, zip
|
||||
download_filename: tool_{{ .Version }}_Linux_{{ .ArchAlias }}.tar.gz
|
||||
```
|
||||
|
||||
opts: `repository` (required), `destination` (required), `strategy` (`tar`/`binary`/`zip`), `download_filename` (supports template vars including `{{ .Version }}`, `{{ .Tag }}`, `{{ .Arch }}`, `{{ .ArchAlias }}`).
|
||||
|
||||
### manifest
|
||||
|
||||
Load an external sofmani config file (local or from a git repo).
|
||||
|
||||
```yaml
|
||||
- name: lazygit
|
||||
type: manifest
|
||||
opts:
|
||||
source: git@github.com/chenasraf/sofmani.git
|
||||
path: docs/recipes/lazygit.yml
|
||||
```
|
||||
|
||||
opts: `source`, `path`.
|
||||
|
||||
### apt
|
||||
|
||||
Debian/Ubuntu package manager.
|
||||
|
||||
```yaml
|
||||
- name: stow
|
||||
type: apt
|
||||
platforms:
|
||||
only: ['linux']
|
||||
```
|
||||
|
||||
### npm / pnpm / yarn
|
||||
|
||||
Node.js package managers. Install global packages.
|
||||
|
||||
```yaml
|
||||
- name: typescript
|
||||
type: pnpm
|
||||
opts:
|
||||
global: true
|
||||
```
|
||||
|
||||
### pipx
|
||||
|
||||
Python tool installer.
|
||||
|
||||
```yaml
|
||||
- name: black
|
||||
type: pipx
|
||||
```
|
||||
|
||||
### cargo
|
||||
|
||||
Rust package installer.
|
||||
|
||||
```yaml
|
||||
- name: ripgrep
|
||||
type: cargo
|
||||
```
|
||||
|
||||
### rsync
|
||||
|
||||
File synchronization.
|
||||
|
||||
```yaml
|
||||
- name: sync-config
|
||||
type: rsync
|
||||
opts:
|
||||
source: ./config/
|
||||
destination: ~/.config/app/
|
||||
```
|
||||
|
||||
### docker
|
||||
|
||||
Pull and optionally run containers.
|
||||
|
||||
```yaml
|
||||
- name: my-service
|
||||
type: docker
|
||||
opts:
|
||||
image: nginx:latest
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Cross-platform group (brew + github-release)
|
||||
|
||||
The standard pattern for CLI tools. Brew handles macOS, github-release handles Linux:
|
||||
|
||||
```yaml
|
||||
- name: tool-name
|
||||
type: group
|
||||
steps:
|
||||
- name: tool-name
|
||||
type: brew
|
||||
- name: tool-name
|
||||
type: github-release
|
||||
platforms:
|
||||
only: ['linux']
|
||||
opts:
|
||||
repository: owner/tool-name
|
||||
destination: ~/.local/bin
|
||||
strategy: tar
|
||||
download_filename: tool-name-linux-{{ .Arch }}.tar.gz
|
||||
```
|
||||
|
||||
### Cross-platform group (brew + apt)
|
||||
|
||||
For packages available in both package managers:
|
||||
|
||||
```yaml
|
||||
- name: stow
|
||||
type: group
|
||||
steps:
|
||||
- name: stow
|
||||
type: brew
|
||||
- name: stow
|
||||
type: apt
|
||||
platforms:
|
||||
only: ['linux']
|
||||
```
|
||||
|
||||
### Config installer with idempotency
|
||||
|
||||
Use `check_installed` and `check_has_update` for shell installers that manage config:
|
||||
|
||||
```yaml
|
||||
- name: tmux-config
|
||||
type: shell
|
||||
tags: config tmux
|
||||
enabled: test -f "$HOME/.config/tmux_{{ .DeviceIDAlias }}.yml"
|
||||
check_installed: test -f ~/.config/tmux_local.yml
|
||||
check_has_update: '! diff -q "$HOME/.config/tmux_{{ .DeviceIDAlias }}.yml" ~/.config/tmux_local.yml > /dev/null 2>&1'
|
||||
opts:
|
||||
command: cp "$HOME/.config/tmux_{{ .DeviceIDAlias }}.yml" ~/.config/tmux_local.yml
|
||||
update_command: cp "$HOME/.config/tmux_{{ .DeviceIDAlias }}.yml" ~/.config/tmux_local.yml
|
||||
```
|
||||
|
||||
### Machine-specific installer
|
||||
|
||||
Restrict to specific machines using aliases defined in `machine_aliases`:
|
||||
|
||||
```yaml
|
||||
- name: glab
|
||||
type: brew
|
||||
machines:
|
||||
only: ['planck']
|
||||
```
|
||||
|
||||
## Working with the Config File
|
||||
|
||||
- The config file is at `~/.dotfiles/.config/sofmani.yml` and symlinked to `~/.config/sofmani.yml` via stow.
|
||||
- Read the full file before making changes to understand existing structure and conventions.
|
||||
- New entries should be placed in the appropriate category section (marked by comment headers).
|
||||
- Follow the existing indentation and style conventions in the file.
|
||||
- When adding a new tool, check if a similar entry already exists that can be extended.
|
||||
- For detailed installer type documentation, see `references/installer-types.md`.
|
||||
148
.claude/skills/sofmani/references/installer-types.md
Normal file
148
.claude/skills/sofmani/references/installer-types.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# Sofmani Installer Types — Detailed Reference
|
||||
|
||||
Full documentation for each installer type's `opts` fields, behavior, and edge cases.
|
||||
|
||||
## shell
|
||||
|
||||
Runs arbitrary shell commands. Most flexible type.
|
||||
|
||||
**opts:**
|
||||
- `command` (string, required): Shell command to run for installation
|
||||
- `update_command` (string): Shell command for updates (defaults to `command` if omitted)
|
||||
|
||||
**Behavior:**
|
||||
- Uses the system shell (overridable with `env_shell`)
|
||||
- Template variables are expanded in commands
|
||||
- `$DEVICE_ID` and `$DEVICE_ID_ALIAS` env vars are injected
|
||||
|
||||
## group
|
||||
|
||||
Orchestrates a sequence of sub-installers. The group itself has no `opts`; configuration lives on each child step.
|
||||
|
||||
**Fields:**
|
||||
- `steps` (array, required): Array of installer entries (same schema as top-level `install`)
|
||||
- `post_install` / `pre_install`: Hooks run before/after the entire group
|
||||
|
||||
**Behavior:**
|
||||
- Steps execute sequentially
|
||||
- If any step fails, subsequent steps are skipped
|
||||
- The group is considered "installed" if all steps report installed
|
||||
|
||||
## git
|
||||
|
||||
Clones a git repository.
|
||||
|
||||
**opts:**
|
||||
- `repository` (string, required): Git URL or GitHub shorthand (`user/repo`)
|
||||
- `destination` (string, required): Local clone path
|
||||
- `ref` (string): Branch, tag, or commit to check out
|
||||
|
||||
**Behavior:**
|
||||
- GitHub shorthand `user/repo` expands to `https://github.com/user/repo.git`
|
||||
- If destination exists, performs `git pull` on update
|
||||
- Supports template variables in all string opts
|
||||
|
||||
## github-release
|
||||
|
||||
Downloads assets from GitHub releases.
|
||||
|
||||
**opts:**
|
||||
- `repository` (string, required): GitHub `owner/repo`
|
||||
- `destination` (string, required): Directory to extract/copy to
|
||||
- `strategy` (string): `tar` (extract tar.gz), `binary` (direct binary), `zip` (extract zip)
|
||||
- `download_filename` (string): Asset filename pattern with template variables
|
||||
- `github_token` (string): GitHub API token for private repos / rate limits
|
||||
|
||||
**Template variables available:**
|
||||
- `{{ .Tag }}`: Full release tag (e.g. `v1.2.3`)
|
||||
- `{{ .Version }}`: Tag without `v` prefix (e.g. `1.2.3`)
|
||||
- `{{ .Arch }}`: Raw architecture string
|
||||
- `{{ .ArchAlias }}`: Normalized architecture (e.g. `amd64`, `arm64`)
|
||||
- `{{ .OS }}`: Operating system
|
||||
|
||||
**Behavior:**
|
||||
- Automatically finds the latest release
|
||||
- Compares installed version to latest for update detection
|
||||
|
||||
## manifest
|
||||
|
||||
Loads and executes an external sofmani config file.
|
||||
|
||||
**opts:**
|
||||
- `source` (string): Git repository URL for remote manifests
|
||||
- `path` (string): Path to the manifest file (relative to repo root for remote, or absolute/relative for local)
|
||||
|
||||
**Behavior:**
|
||||
- Remote manifests are cloned/cached locally
|
||||
- The loaded manifest's `install` array is executed inline
|
||||
- Useful for sharing common recipes across machines
|
||||
|
||||
## rsync
|
||||
|
||||
Synchronizes files/directories.
|
||||
|
||||
**opts:**
|
||||
- `source` (string, required): Source path
|
||||
- `destination` (string, required): Destination path
|
||||
- Additional rsync flags can be set
|
||||
|
||||
**Behavior:**
|
||||
- Uses rsync under the hood
|
||||
- `verbose: true` in defaults enables `-v` flag
|
||||
|
||||
## brew
|
||||
|
||||
Homebrew package manager.
|
||||
|
||||
**opts:**
|
||||
- `tap` (string): Custom tap to install from (e.g. `chenasraf/tap`)
|
||||
- `cask` (bool): Install as a cask instead of formula
|
||||
|
||||
**Behavior:**
|
||||
- The project's global defaults restrict brew to `platforms: { only: ['macos'] }`
|
||||
- No need to add platform restriction on individual brew entries
|
||||
- Taps are added automatically before install
|
||||
|
||||
## npm / pnpm / yarn
|
||||
|
||||
Node.js package managers.
|
||||
|
||||
**opts:**
|
||||
- `global` (bool): Install globally
|
||||
|
||||
**Behavior:**
|
||||
- Defaults to global installation in most configurations
|
||||
|
||||
## apt
|
||||
|
||||
Debian/Ubuntu package manager.
|
||||
|
||||
No special opts. Always requires `platforms: { only: ['linux'] }` unless in a group that already restricts.
|
||||
|
||||
## apk
|
||||
|
||||
Alpine Linux package manager. Same behavior as apt.
|
||||
|
||||
## pacman / yay
|
||||
|
||||
Arch Linux package managers. Yay is an AUR helper that wraps pacman.
|
||||
|
||||
## pipx
|
||||
|
||||
Python application installer. Installs Python CLI tools in isolated environments.
|
||||
|
||||
No special opts — uses the package `name` directly.
|
||||
|
||||
## cargo
|
||||
|
||||
Rust package installer.
|
||||
|
||||
No special opts — uses the package `name` directly.
|
||||
|
||||
## docker
|
||||
|
||||
Docker container management.
|
||||
|
||||
**opts:**
|
||||
- `image` (string, required): Docker image to pull
|
||||
- Additional run configuration as needed
|
||||
157
.claude/skills/wand/SKILL.md
Normal file
157
.claude/skills/wand/SKILL.md
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
name: wand
|
||||
description:
|
||||
Refactor shell functions and aliases into wand YAML configs. This skill should be used when the
|
||||
user wants to extract shell functions, aliases, or scripts into a wand.yml command runner config,
|
||||
create new wand configs, or add commands to existing wand configs. Triggers on requests like "move
|
||||
these functions to wand", "create a wand config for X", "refactor this script into wand commands".
|
||||
---
|
||||
|
||||
# Wand Refactor
|
||||
|
||||
Extract shell functions and aliases into [wand](https://github.com/chenasraf/wand) YAML configs,
|
||||
replacing inline logic with declarative command definitions and thin alias wrappers.
|
||||
|
||||
## Wand Config Reference
|
||||
|
||||
Wand is a YAML-driven command runner. Config files are auto-discovered from CWD upward, `~/`, and
|
||||
`~/.config/`. A custom path can be specified via `--wand-file <path>` or `WAND_FILE=<path>`.
|
||||
|
||||
### Command Fields
|
||||
|
||||
| Field | Type | Purpose |
|
||||
| ----------------- | -------------------- | ------------------------------------ |
|
||||
| `description` | `string` | Help text shown in `--help` |
|
||||
| `cmd` | `string` | Shell command to execute |
|
||||
| `children` | `map[string]Command` | Nested subcommands |
|
||||
| `flags` | `map[string]Flag` | Custom typed flags |
|
||||
| `env` | `map[string]string` | Environment variables |
|
||||
| `working_dir` | `string` | Execution directory |
|
||||
| `aliases` | `string[]` | Alternate command names |
|
||||
| `confirm` | `bool` or `string` | Confirmation prompt before execution |
|
||||
| `confirm_default` | `string` | Default answer for confirm |
|
||||
|
||||
### Flag Fields
|
||||
|
||||
| Field | Type | Purpose |
|
||||
| ------------- | -------- | ------------------------------------------- |
|
||||
| `alias` | `string` | Single-letter shorthand (e.g. `o` for `-o`) |
|
||||
| `description` | `string` | Description shown in `--help` |
|
||||
| `default` | `any` | Default value |
|
||||
| `type` | `string` | `"bool"` for boolean flags, omit for string |
|
||||
|
||||
Flag values are accessible as `$WAND_FLAG_<NAME>` env vars (uppercased, hyphens become underscores).
|
||||
|
||||
### Positional Arguments
|
||||
|
||||
Extra CLI arguments are available as `$1`, `$2`, `$@` in the command's `cmd`.
|
||||
|
||||
## Refactoring Process
|
||||
|
||||
### Step 1: Analyze the Source
|
||||
|
||||
Read the source file(s) containing the shell functions/aliases to refactor. Identify:
|
||||
|
||||
- **Command groups**: Functions that share a common prefix or domain (e.g. `nc-dev-*`, `nc-aio-*`)
|
||||
- **Shared state**: Variables, config paths, or logic used across multiple functions
|
||||
- **Modal behavior**: Functions that differ only by a mode/target (e.g. dev vs aio) — these become a
|
||||
single command with a flag
|
||||
- **Subcommand hierarchies**: Related commands that naturally nest (e.g.
|
||||
`db-proxy start`/`db-proxy stop`)
|
||||
|
||||
### Step 2: Design the Wand Config
|
||||
|
||||
Map the analyzed functions to wand commands following these principles:
|
||||
|
||||
1. **Merge modal variants into flags**: If two functions differ only by target (e.g. `nc-dev-occ` vs
|
||||
`nc-aio-occ`), create one command with a `--<mode>` flag (default to the more common mode).
|
||||
2. **Use `children` for related pairs**: Commands that are natural opposites (start/stop,
|
||||
enable/disable, backup/restore) belong as children of a parent command.
|
||||
3. **Use `env` for shared config**: Constants like paths, container names, etc. go in the `env`
|
||||
field rather than hardcoded in `cmd`.
|
||||
4. **Use `working_dir`** instead of `pushd`/`popd` or `cd`.
|
||||
5. **Use `confirm`** for destructive or long-running operations.
|
||||
6. **Keep commands self-contained**: Each command's `cmd` must be independently runnable — do not
|
||||
call other wand commands or rely on shell aliases being available.
|
||||
7. **Add `set -euo pipefail`** at the top of multi-line commands that should fail fast.
|
||||
8. **Use `aliases`** for common shorthand names within wand itself.
|
||||
|
||||
### Step 3: Choose Config File Location
|
||||
|
||||
- If adding to the existing global wand config: edit `~/.dotfiles/.config/wand.yml`
|
||||
- If creating a domain-specific config (preferred for large command sets): create
|
||||
`~/.dotfiles/.config/wand/<domain>.yml` and define an alias:
|
||||
`alias <shortname>="wand --wand-file \$HOME/.config/wand/<domain>.yml"`
|
||||
|
||||
After creating or modifying a config file in `~/.dotfiles/.config/`, run
|
||||
`stow -v -d $DOTFILES -t ~ .` to symlink it.
|
||||
|
||||
### Step 4: Create Aliases
|
||||
|
||||
Replace the original shell file with thin aliases that point to wand commands. This preserves
|
||||
backward compatibility with existing muscle memory.
|
||||
|
||||
Alias conventions:
|
||||
|
||||
- Define a **base alias** for the wand config (e.g.
|
||||
`alias nxc="wand --wand-file $HOME/.config/wand/nextcloud.yml"`)
|
||||
- Map each old function/alias to `<base> <command> [--flags] [--]`
|
||||
- Append `--` before positional args when the command has flags, to prevent flag/arg ambiguity
|
||||
- Keep old alias names working so existing scripts and habits are preserved
|
||||
|
||||
### Step 5: Clean Up
|
||||
|
||||
- Remove the original shell functions from the source file, keeping only the alias definitions
|
||||
- Remove any global variables that were only used by the extracted functions (they now live in `env`
|
||||
fields)
|
||||
- If the source file becomes aliases-only, consider whether it should stay as-is or merge into
|
||||
`aliases.zsh`
|
||||
|
||||
## Example: Before and After
|
||||
|
||||
### Before (shell functions)
|
||||
|
||||
```zsh
|
||||
APP_DIR="$HOME/myapp"
|
||||
my-build() { pushd $APP_DIR; make build; popd; }
|
||||
my-test() { pushd $APP_DIR; make test; popd; }
|
||||
my-deploy() {
|
||||
echo "Deploying..."
|
||||
pushd $APP_DIR; make deploy ENV=$1; popd
|
||||
}
|
||||
alias my-deploy-prod="my-deploy prod"
|
||||
alias my-deploy-staging="my-deploy staging"
|
||||
```
|
||||
|
||||
### After (wand.yml + aliases)
|
||||
|
||||
```yaml
|
||||
# ~/.dotfiles/.config/wand/myapp.yml
|
||||
build:
|
||||
description: Build the project
|
||||
working_dir: ~/myapp
|
||||
cmd: make build
|
||||
|
||||
test:
|
||||
description: Run tests
|
||||
working_dir: ~/myapp
|
||||
cmd: make test
|
||||
|
||||
deploy:
|
||||
description: Deploy the project
|
||||
working_dir: ~/myapp
|
||||
confirm: Deploy to $1?
|
||||
cmd: |
|
||||
echo "Deploying..."
|
||||
make deploy ENV=$1
|
||||
```
|
||||
|
||||
```zsh
|
||||
# aliases
|
||||
alias myapp="wand --wand-file \$HOME/.config/wand/myapp.yml"
|
||||
alias my-build="myapp build"
|
||||
alias my-test="myapp test"
|
||||
alias my-deploy="myapp deploy --"
|
||||
alias my-deploy-prod="myapp deploy prod"
|
||||
alias my-deploy-staging="myapp deploy staging"
|
||||
```
|
||||
Reference in New Issue
Block a user