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 +21 -0
- package/README.md +136 -0
- package/bin/cli.js +214 -0
- package/commands/do/cam.md +57 -0
- package/commands/do/fpr.md +107 -0
- package/commands/do/help.md +33 -0
- package/commands/do/makegoals.md +219 -0
- package/commands/do/makegood.md +587 -0
- package/commands/do/optimize-md.md +138 -0
- package/commands/do/pr.md +41 -0
- package/commands/do/release.md +96 -0
- package/commands/do/replan.md +212 -0
- package/commands/do/review.md +75 -0
- package/commands/do/rpr.md +85 -0
- package/commands/do/update.md +26 -0
- package/hooks/update-check.md +21 -0
- package/install.sh +161 -0
- package/lib/code-review-checklist.md +48 -0
- package/lib/copilot-review-loop.md +44 -0
- package/lib/graphql-escaping.md +8 -0
- package/package.json +40 -0
- package/src/environments.js +83 -0
- package/src/installer.js +272 -0
- package/src/transformer.js +141 -0
- package/src/version-check.js +51 -0
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> •
|
|
19
|
+
<a href="#commands">Commands</a> •
|
|
20
|
+
<a href="#supported-environments">Environments</a> •
|
|
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
|