slash-do 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Adam Eivy (@antic|@atomantic)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ <p align="center">
2
+
3
+ ```
4
+ ██╗██████╗ ██████╗
5
+ ██╔╝██╔══██╗██╔═══██╗
6
+ ██╔╝ ██║ ██║██║ ██║
7
+ ██╔╝ ██║ ██║██║ ██║
8
+ ██╔╝ ██████╔╝╚██████╔╝
9
+ ╚═╝ ╚═════╝ ╚═════╝
10
+ ```
11
+
12
+ </p>
13
+
14
+ <h3 align="center">Curated slash commands for AI coding assistants</h3>
15
+ <p align="center">One install. Multiple environments. All the workflows.</p>
16
+
17
+ <p align="center">
18
+ <a href="#quick-start">Quick Start</a> &bull;
19
+ <a href="#commands">Commands</a> &bull;
20
+ <a href="#supported-environments">Environments</a> &bull;
21
+ <a href="#how-it-works">How It Works</a>
22
+ </p>
23
+
24
+ <p align="center">
25
+ <img src="https://img.shields.io/npm/v/slash-do?style=flat-square&color=blue" alt="npm version" />
26
+ <img src="https://img.shields.io/badge/environments-4-green?style=flat-square" alt="environments" />
27
+ <img src="https://img.shields.io/badge/commands-12-orange?style=flat-square" alt="commands" />
28
+ <img src="https://img.shields.io/badge/license-MIT-lightgrey?style=flat-square" alt="license" />
29
+ </p>
30
+
31
+ ---
32
+
33
+ ## Quick Start
34
+
35
+ **With npm/npx:**
36
+ ```bash
37
+ npx slash-do@latest
38
+ ```
39
+
40
+ **Without npm** (curl):
41
+ ```bash
42
+ curl -fsSL https://raw.githubusercontent.com/atomantic/slashdo/main/install.sh | bash
43
+ ```
44
+
45
+ That's it. slashdo detects your installed AI coding environments and installs commands to each one.
46
+
47
+ ## Commands
48
+
49
+ All commands live under the `do:` namespace:
50
+
51
+ | Command | What it does |
52
+ |:---|:---|
53
+ | `/do:cam` | Commit and push all work with changelog |
54
+ | `/do:pr` | Open a PR with self-review and Copilot review loop |
55
+ | `/do:fpr` | Fork PR -- push to fork, PR against upstream |
56
+ | `/do:rpr` | Resolve PR review feedback with parallel agents |
57
+ | `/do:release` | Create a release PR with version bump and changelog |
58
+ | `/do:review` | Deep code review against best practices |
59
+ | `/do:makegood` | Full DevSecOps audit with 7-agent scan and remediation |
60
+ | `/do:makegoals` | Generate GOALS.md from codebase analysis |
61
+ | `/do:replan` | Review and clean up PLAN.md |
62
+ | `/do:optimize-md` | Audit and optimize CLAUDE.md files |
63
+ | `/do:update` | Update slashdo to latest version |
64
+ | `/do:help` | List all available commands |
65
+
66
+ ## Supported Environments
67
+
68
+ ```
69
+ Claude Code ~/.claude/commands/do/ YAML frontmatter + subdirectories
70
+ OpenCode ~/.config/opencode/commands/ YAML frontmatter + flat naming
71
+ Gemini CLI ~/.gemini/commands/do/ TOML headers + subdirectories
72
+ Codex ~/.codex/skills/ SKILL.md per-command directories
73
+ ```
74
+
75
+ slashdo auto-detects which environments you have installed. Or specify manually:
76
+
77
+ ```bash
78
+ npx slash-do@latest --env claude # just Claude Code
79
+ npx slash-do@latest --env opencode,gemini # multiple environments
80
+ ```
81
+
82
+ ## Install Options
83
+
84
+ ```bash
85
+ npx slash-do@latest # auto-detect + install all
86
+ npx slash-do@latest --env claude # target specific environment
87
+ npx slash-do@latest --list # show commands and install status
88
+ npx slash-do@latest --dry-run # preview changes
89
+ npx slash-do@latest --uninstall # remove installed commands
90
+ npx slash-do@latest cam pr release # install specific commands only
91
+ ```
92
+
93
+ ## How It Works
94
+
95
+ ```
96
+ Source (commands/do/*.md)
97
+ |
98
+ v
99
+ +------------------+
100
+ | Transformer | Converts format per environment:
101
+ | | - YAML frontmatter (Claude, OpenCode)
102
+ +------------------+ - TOML headers (Gemini)
103
+ | - SKILL.md with inlined libs (Codex)
104
+ v
105
+ +------------------+
106
+ | Installer | Diff-based: only writes changed files
107
+ | | Tracks version for update notifications
108
+ +------------------+
109
+ |
110
+ v
111
+ ~/.claude/commands/do/cam.md
112
+ ~/.config/opencode/commands/do-cam.md
113
+ ~/.gemini/commands/do/cam.md
114
+ ~/.codex/skills/do-cam/SKILL.md
115
+ ```
116
+
117
+ ## Updating
118
+
119
+ ```bash
120
+ npx slash-do@latest # from your terminal
121
+ ```
122
+
123
+ ```
124
+ /do:update # from inside your AI coding assistant
125
+ ```
126
+
127
+ ## Contributing
128
+
129
+ 1. Commands live in `commands/do/` as Claude Code format `.md` files (source of truth)
130
+ 2. Lib files (shared partials) live in `lib/`
131
+ 3. The transformer handles format conversion for each environment
132
+ 4. Test with `node bin/cli.js --list` and `node bin/cli.js --dry-run`
133
+
134
+ ## License
135
+
136
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const path = require('path');
5
+ const readline = require('readline');
6
+ const { detectInstalled, getEnv, allEnvNames, ENVIRONMENTS } = require('../src/environments');
7
+ const { install, list } = require('../src/installer');
8
+
9
+ const PACKAGE_DIR = path.resolve(__dirname, '..');
10
+
11
+ const BANNER = `
12
+ \x1b[36m ██╗\x1b[33m██████╗ ██████╗ \x1b[0m
13
+ \x1b[36m ██╔╝\x1b[33m██╔══██╗██╔═══██╗\x1b[0m
14
+ \x1b[36m ██╔╝ \x1b[33m██║ ██║██║ ██║\x1b[0m
15
+ \x1b[36m ██╔╝ \x1b[33m██║ ██║██║ ██║\x1b[0m
16
+ \x1b[36m██╔╝ \x1b[33m██████╔╝╚██████╔╝\x1b[0m
17
+ \x1b[36m╚═╝ \x1b[33m╚═════╝ ╚═════╝ \x1b[0m
18
+ \x1b[2mslashdo — curated slash commands for AI coding assistants\x1b[0m
19
+ `;
20
+
21
+ function usage() {
22
+ console.log(BANNER);
23
+ console.log(`Usage:
24
+ npx slash-do@latest Install/update all, auto-detect envs
25
+ npx slash-do@latest --env claude Install for Claude Code only
26
+ npx slash-do@latest --env opencode,gemini Specific environments
27
+ npx slash-do@latest --list Show commands and install status
28
+ npx slash-do@latest --dry-run Preview changes
29
+ npx slash-do@latest --uninstall Remove installed commands
30
+ npx slash-do@latest cam pr Install specific commands only
31
+
32
+ Options:
33
+ --env <envs> Comma-separated environments: ${allEnvNames().join(', ')}
34
+ --list Show all commands and their install status
35
+ --dry-run Preview changes without applying them
36
+ --uninstall Remove all slashdo-installed commands
37
+ --help Show this help message
38
+
39
+ Environments:
40
+ claude Claude Code (~/.claude/commands/)
41
+ opencode OpenCode (~/.config/opencode/commands/)
42
+ gemini Gemini CLI (~/.gemini/commands/)
43
+ codex Codex (~/.codex/skills/)
44
+ `);
45
+ }
46
+
47
+ function parseArgs(argv) {
48
+ const args = {
49
+ envs: [],
50
+ list: false,
51
+ dryRun: false,
52
+ uninstall: false,
53
+ help: false,
54
+ commands: [],
55
+ };
56
+
57
+ let i = 0;
58
+ while (i < argv.length) {
59
+ const arg = argv[i];
60
+ switch (arg) {
61
+ case '--help':
62
+ case '-h':
63
+ args.help = true;
64
+ break;
65
+ case '--list':
66
+ args.list = true;
67
+ break;
68
+ case '--dry-run':
69
+ args.dryRun = true;
70
+ break;
71
+ case '--uninstall':
72
+ args.uninstall = true;
73
+ break;
74
+ case '--env':
75
+ i++;
76
+ if (i < argv.length) {
77
+ args.envs = argv[i].split(',').map(s => s.trim().toLowerCase());
78
+ }
79
+ break;
80
+ default:
81
+ if (!arg.startsWith('-')) {
82
+ args.commands.push(arg.replace(/^do:/, ''));
83
+ }
84
+ break;
85
+ }
86
+ i++;
87
+ }
88
+
89
+ return args;
90
+ }
91
+
92
+ function promptUser(question, choices) {
93
+ return new Promise((resolve) => {
94
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
95
+ console.log(`\n${question}`);
96
+ choices.forEach((c, i) => console.log(` ${i + 1}) ${c}`));
97
+ console.log(` a) All of the above`);
98
+ rl.question('\nSelect (comma-separated numbers, or "a" for all): ', (answer) => {
99
+ rl.close();
100
+ const trimmed = answer.trim().toLowerCase();
101
+ if (trimmed === 'a' || trimmed === 'all') {
102
+ resolve(choices.map((_, i) => i));
103
+ return;
104
+ }
105
+ const indices = trimmed.split(',')
106
+ .map(s => parseInt(s.trim(), 10) - 1)
107
+ .filter(n => !isNaN(n) && n >= 0 && n < choices.length);
108
+ resolve(indices);
109
+ });
110
+ });
111
+ }
112
+
113
+ function printListTable(items, envName) {
114
+ console.log(`\n Commands for ${envName}:\n`);
115
+ const nameWidth = Math.max(20, ...items.map(i => i.name.length + 2));
116
+ const statusWidth = 14;
117
+
118
+ console.log(
119
+ ` ${'COMMAND'.padEnd(nameWidth)} ${'STATUS'.padEnd(statusWidth)} DESCRIPTION`
120
+ );
121
+ console.log(
122
+ ` ${'-------'.padEnd(nameWidth)} ${'------'.padEnd(statusWidth)} -----------`
123
+ );
124
+ for (const item of items) {
125
+ console.log(
126
+ ` ${item.name.padEnd(nameWidth)} ${item.status.padEnd(statusWidth)} ${item.description}`
127
+ );
128
+ }
129
+ }
130
+
131
+ function printResults(results, envName, dryRun) {
132
+ const prefix = dryRun ? '(dry run) ' : '';
133
+ console.log(`\n ${prefix}${envName}:`);
134
+ for (const action of results.actions) {
135
+ console.log(` ${action.status}: ${action.name}`);
136
+ }
137
+ console.log(`\n ${results.installed} installed, ${results.updated} updated, ${results.upToDate} up to date${results.removed ? `, ${results.removed} removed` : ''}`);
138
+ }
139
+
140
+ async function main() {
141
+ const args = parseArgs(process.argv.slice(2));
142
+
143
+ if (args.help) {
144
+ usage();
145
+ process.exit(0);
146
+ }
147
+
148
+ let selectedEnvs = args.envs;
149
+
150
+ if (!selectedEnvs.length) {
151
+ const detected = detectInstalled();
152
+ if (!detected.length) {
153
+ console.log('\nNo supported AI coding environments detected.');
154
+ console.log('Supported environments:');
155
+ for (const [key, env] of Object.entries(ENVIRONMENTS)) {
156
+ console.log(` ${key.padEnd(12)} ${env.name}`);
157
+ }
158
+ console.log('\nUse --env to specify: npx slash-do@latest --env claude');
159
+ process.exit(1);
160
+ }
161
+
162
+ if (detected.length === 1) {
163
+ selectedEnvs = detected;
164
+ console.log(`Detected: ${ENVIRONMENTS[detected[0]].name}`);
165
+ } else {
166
+ const choices = detected.map(k => `${k} (${ENVIRONMENTS[k].name})`);
167
+ const indices = await promptUser('Multiple environments detected. Select which to install:', choices);
168
+ if (!indices.length) {
169
+ console.log('No environments selected.');
170
+ process.exit(0);
171
+ }
172
+ selectedEnvs = indices.map(i => detected[i]);
173
+ }
174
+ }
175
+
176
+ const invalidEnvs = selectedEnvs.filter(e => !getEnv(e));
177
+ if (invalidEnvs.length) {
178
+ console.error(`Unknown environment(s): ${invalidEnvs.join(', ')}`);
179
+ console.error(`Valid: ${allEnvNames().join(', ')}`);
180
+ process.exit(1);
181
+ }
182
+
183
+ if (args.list) {
184
+ for (const envName of selectedEnvs) {
185
+ const env = getEnv(envName);
186
+ const items = list({ env, packageDir: PACKAGE_DIR });
187
+ printListTable(items, env.name);
188
+ }
189
+ process.exit(0);
190
+ }
191
+
192
+ console.log(BANNER);
193
+
194
+ for (const envName of selectedEnvs) {
195
+ const env = getEnv(envName);
196
+ const results = install({
197
+ env,
198
+ packageDir: PACKAGE_DIR,
199
+ filterNames: args.commands.length ? args.commands : null,
200
+ dryRun: args.dryRun,
201
+ uninstall: args.uninstall,
202
+ });
203
+ printResults(results, env.name, args.dryRun);
204
+ }
205
+
206
+ if (!args.dryRun && !args.uninstall) {
207
+ console.log('\nDone! Commands are available as /do:<name> in your AI coding assistant.');
208
+ }
209
+ }
210
+
211
+ main().catch(err => {
212
+ console.error('Error:', err.message);
213
+ process.exit(1);
214
+ });
@@ -0,0 +1,57 @@
1
+ ---
2
+ description: Commit and push all work with changelog
3
+ ---
4
+
5
+ # Commit All My Work (cam)
6
+
7
+ Commit and push all work from this session, updating documentation as needed.
8
+
9
+ ## Instructions
10
+
11
+ 1. **Identify changes to commit**:
12
+ - Run `git status` and `git diff --stat` to see what changed
13
+ - If you edited files in this session, commit only those files
14
+ - If invoked without prior edit context, review all uncommitted changes
15
+ - if there are files that should be added to the .gitignore that are not yet there, ensure we have proper .gitignore coverage
16
+
17
+ 2. **Update the changelog**:
18
+ - Check for a changelog directory: `.changelogs/` or `.changelog/` (use whichever exists)
19
+ - If found, append to `{changelog_dir}/NEXT.md`
20
+ - If `NEXT.md` doesn't exist yet, create it with this template:
21
+ ```markdown
22
+ # Unreleased Changes
23
+
24
+ ## Added
25
+
26
+ ## Changed
27
+
28
+ ## Fixed
29
+
30
+ ## Removed
31
+ ```
32
+ - Add a concise entry describing the changes under the appropriate section (Added, Changed, Fixed, Removed)
33
+ - If no changelog directory exists, skip this step
34
+
35
+ 3. **Update PLAN.md** (if exists):
36
+ - Mark completed items as done
37
+ - Update progress notes if relevant
38
+ - Skip if no PLAN.md exists or changes aren't plan-related
39
+
40
+ 4. **Commit and push**:
41
+ - Stage all changed files (including `NEXT.md` if updated)
42
+ - Do NOT use `git add -A` or `git add .` - add specific files by name
43
+ - Write a clear, concise commit message describing what was done
44
+ - Do NOT include Co-Authored-By or generated-by annotations
45
+ - Use conventional commit prefix: `feat:` for features, `fix:` for bug fixes, `breaking:` for breaking changes
46
+ - Do NOT bump the version — version bumps only happen during `/release`
47
+
48
+ 5. **Push the changes**:
49
+ - Use `git pull --rebase --autostash && git push` to push safely
50
+
51
+ ## Important
52
+
53
+ - Never stage files you didn't edit
54
+ - Never use `git add -A` or `git add .`
55
+ - Keep commit messages focused on the "why" not just the "what"
56
+ - If there are no changes to commit, inform the user
57
+ - Do NOT bump the version in package.json — `/release` handles versioning
@@ -0,0 +1,107 @@
1
+ ---
2
+ description: Commit, push to fork, and open a PR against the upstream repo
3
+ ---
4
+
5
+ # Fork PR (fpr)
6
+
7
+ Commit changes, push to your fork, and open a pull request against the upstream (parent) repository.
8
+
9
+ ## Detect Fork Relationship
10
+
11
+ 1. **Verify this is a fork** — run:
12
+ ```bash
13
+ gh repo view --json isFork,parent,owner,name,defaultBranchRef
14
+ ```
15
+ - If `isFork` is `false` or `parent` is null: STOP and tell the user this repo is not a fork. Suggest using `/pr` instead.
16
+
17
+ 2. **Extract upstream info** from the `parent` field:
18
+ - `UPSTREAM_OWNER` = `parent.owner.login`
19
+ - `UPSTREAM_REPO` = `parent.name`
20
+ - `UPSTREAM_DEFAULT_BRANCH` = `parent.defaultBranchRef.name`
21
+
22
+ 3. **Extract fork info**:
23
+ - `FORK_OWNER` = `owner.login`
24
+ - `FORK_DEFAULT_BRANCH` = `defaultBranchRef.name`
25
+ - `CURRENT_BRANCH` = output of `git branch --show-current`
26
+
27
+ 4. Print: `Fork PR flow: {FORK_OWNER}/{CURRENT_BRANCH} → {UPSTREAM_OWNER}/{UPSTREAM_REPO}:{UPSTREAM_DEFAULT_BRANCH}`
28
+
29
+ ## Sync with Upstream
30
+
31
+ Before committing, ensure the fork is up to date with upstream:
32
+
33
+ 1. Add upstream remote if missing:
34
+ ```bash
35
+ git remote get-url upstream 2>/dev/null || git remote add upstream "https://github.com/{UPSTREAM_OWNER}/{UPSTREAM_REPO}.git"
36
+ ```
37
+ 2. Fetch upstream: `git fetch upstream`
38
+ 3. If on the fork's default branch and there are upstream changes, rebase:
39
+ ```bash
40
+ git rebase upstream/{UPSTREAM_DEFAULT_BRANCH}
41
+ ```
42
+ If rebase conflicts occur, abort and inform the user — do not auto-resolve.
43
+
44
+ ## Commit and Push
45
+
46
+ 1. **Identify changes to commit**:
47
+ - Run `git status` and `git diff --stat` to see what changed
48
+ - If there are no changes, inform the user and stop
49
+ - Do NOT use `git add -A` or `git add .` — add specific files by name
50
+
51
+ 2. **Commit**:
52
+ - Write a clear, concise commit message describing the changes
53
+ - Use conventional commit prefixes: `feat:`, `fix:`, `refactor:`, `docs:`, `chore:`
54
+ - Do NOT include Co-Authored-By or generated-by annotations
55
+ - Do NOT bump version or update changelog — upstream controls those
56
+
57
+ 3. **Push to fork**:
58
+ ```bash
59
+ git push -u origin {CURRENT_BRANCH}
60
+ ```
61
+
62
+ ## Local Code Review (before opening PR)
63
+
64
+ 1. Fetch upstream default branch for accurate diff:
65
+ ```bash
66
+ git fetch upstream {UPSTREAM_DEFAULT_BRANCH}
67
+ ```
68
+ 2. Run `git diff upstream/{UPSTREAM_DEFAULT_BRANCH}...{CURRENT_BRANCH}` to see the full diff against upstream
69
+ 3. **For each changed file**, read the full file (not just the diff hunks) and check:
70
+
71
+ !`cat ~/.claude/lib/code-review-checklist.md`
72
+ 4. If issues are found, fix them, recommit, and push before proceeding
73
+ 5. Summarize the review findings so the user can see what was checked
74
+
75
+ ## Check for Upstream Contributing Guidelines
76
+
77
+ Before opening the PR, check if upstream has contribution guidelines:
78
+ - Look for `CONTRIBUTING.md`, `.github/PULL_REQUEST_TEMPLATE.md`, or similar
79
+ - If a PR template exists, use it for the PR body structure
80
+ - If contribution guidelines mention branch naming, commit format, or other requirements, flag any violations to the user
81
+
82
+ ## Open the PR
83
+
84
+ Create a cross-fork PR targeting the upstream repo:
85
+
86
+ ```bash
87
+ gh pr create \
88
+ --repo {UPSTREAM_OWNER}/{UPSTREAM_REPO} \
89
+ --head {FORK_OWNER}:{CURRENT_BRANCH} \
90
+ --base {UPSTREAM_DEFAULT_BRANCH} \
91
+ --title "PR title here" \
92
+ --body "PR description here"
93
+ ```
94
+
95
+ - Write a clear title and rich description
96
+ - If a PR template was found, follow its structure
97
+ - Do NOT include co-author or "generated with" messages
98
+ - Print the resulting PR URL so the user can review it
99
+
100
+ ## Important
101
+
102
+ - Never stage files you didn't edit
103
+ - Never use `git add -A` or `git add .`
104
+ - Do NOT bump versions or update changelogs — upstream maintainers control those
105
+ - Do NOT merge the PR — upstream maintainers handle that
106
+ - Do NOT run Copilot review loops — you don't control the upstream repo's review settings
107
+ - If the fork is significantly behind upstream, warn the user about potential merge conflicts
@@ -0,0 +1,33 @@
1
+ ---
2
+ description: List all available slashdo commands
3
+ ---
4
+
5
+ # slashdo Commands
6
+
7
+ List all available `/do:*` commands with their descriptions.
8
+
9
+ ## Steps
10
+
11
+ 1. **List commands**: Print a table of all available slashdo commands:
12
+
13
+ | Command | Description |
14
+ |---|---|
15
+ | `/do:cam` | Commit and push all work with changelog |
16
+ | `/do:fpr` | Commit, push to fork, and open a PR against the upstream repo |
17
+ | `/do:help` | List all available slashdo commands |
18
+ | `/do:makegoals` | Scan codebase to infer project goals, clarify with user, and generate GOALS.md |
19
+ | `/do:makegood` | Unified DevSecOps audit, remediation, per-category PRs, CI verification, and Copilot review loop |
20
+ | `/do:optimize-md` | Audit and optimize CLAUDE.md files against best practices |
21
+ | `/do:pr` | Commit, push, and open a PR against the repo's default branch |
22
+ | `/do:release` | Create a release PR using the project's documented release workflow |
23
+ | `/do:replan` | Review and clean up PLAN.md, extract docs from completed work |
24
+ | `/do:review` | Deep code review of changed files against best practices |
25
+ | `/do:rpr` | Resolve PR review feedback with parallel agents |
26
+ | `/do:update` | Update slashdo commands to the latest version |
27
+
28
+ 2. **Check for updates**: Run `npm view slashdo version` and compare to the installed version in `~/.claude/.slashdo-version`. If an update is available, mention it.
29
+
30
+ ## Notes
31
+
32
+ - Commands are installed via `npx slash-do@latest`
33
+ - For more info, see https://github.com/atomantic/slashdo