slashdev 0.1.0 → 1.0.0

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.
Files changed (70) hide show
  1. package/.gitmodules +3 -0
  2. package/CLAUDE.md +87 -0
  3. package/README.md +158 -21
  4. package/bin/check-setup.js +27 -0
  5. package/claude-skills/agentswarm/SKILL.md +479 -0
  6. package/claude-skills/bug-diagnosis/SKILL.md +34 -0
  7. package/claude-skills/code-review/SKILL.md +26 -0
  8. package/claude-skills/frontend-design/LICENSE.txt +177 -0
  9. package/claude-skills/frontend-design/SKILL.md +42 -0
  10. package/claude-skills/pr-description/SKILL.md +35 -0
  11. package/claude-skills/scope-estimate/SKILL.md +37 -0
  12. package/hooks/post-response.sh +242 -0
  13. package/package.json +11 -3
  14. package/skills/front-end-design/prompts/system.md +37 -0
  15. package/skills/front-end-testing/prompts/system.md +66 -0
  16. package/skills/github-manager/prompts/system.md +79 -0
  17. package/skills/product-expert/prompts/system.md +52 -0
  18. package/skills/server-admin/prompts/system.md +39 -0
  19. package/src/auth/index.js +115 -0
  20. package/src/cli.js +188 -18
  21. package/src/commands/setup-internals.js +137 -0
  22. package/src/commands/setup.js +104 -0
  23. package/src/commands/update.js +60 -0
  24. package/src/connections/index.js +449 -0
  25. package/src/connections/providers/github.js +71 -0
  26. package/src/connections/providers/servers.js +175 -0
  27. package/src/connections/registry.js +21 -0
  28. package/src/core/claude.js +78 -0
  29. package/src/core/codebase.js +119 -0
  30. package/src/core/config.js +110 -0
  31. package/src/index.js +8 -1
  32. package/src/info.js +54 -21
  33. package/src/skills/index.js +252 -0
  34. package/src/utils/ssh-keys.js +67 -0
  35. package/vendor/gstack/.env.example +5 -0
  36. package/vendor/gstack/autoplan/SKILL.md +1116 -0
  37. package/vendor/gstack/browse/SKILL.md +538 -0
  38. package/vendor/gstack/canary/SKILL.md +587 -0
  39. package/vendor/gstack/careful/SKILL.md +59 -0
  40. package/vendor/gstack/codex/SKILL.md +862 -0
  41. package/vendor/gstack/connect-chrome/SKILL.md +549 -0
  42. package/vendor/gstack/cso/ACKNOWLEDGEMENTS.md +14 -0
  43. package/vendor/gstack/cso/SKILL.md +929 -0
  44. package/vendor/gstack/design-consultation/SKILL.md +962 -0
  45. package/vendor/gstack/design-review/SKILL.md +1314 -0
  46. package/vendor/gstack/design-shotgun/SKILL.md +730 -0
  47. package/vendor/gstack/document-release/SKILL.md +718 -0
  48. package/vendor/gstack/freeze/SKILL.md +82 -0
  49. package/vendor/gstack/gstack-upgrade/SKILL.md +232 -0
  50. package/vendor/gstack/guard/SKILL.md +82 -0
  51. package/vendor/gstack/investigate/SKILL.md +504 -0
  52. package/vendor/gstack/land-and-deploy/SKILL.md +1367 -0
  53. package/vendor/gstack/office-hours/SKILL.md +1317 -0
  54. package/vendor/gstack/plan-ceo-review/SKILL.md +1537 -0
  55. package/vendor/gstack/plan-design-review/SKILL.md +1227 -0
  56. package/vendor/gstack/plan-eng-review/SKILL.md +1120 -0
  57. package/vendor/gstack/qa/SKILL.md +1136 -0
  58. package/vendor/gstack/qa/references/issue-taxonomy.md +85 -0
  59. package/vendor/gstack/qa/templates/qa-report-template.md +126 -0
  60. package/vendor/gstack/qa-only/SKILL.md +726 -0
  61. package/vendor/gstack/retro/SKILL.md +1197 -0
  62. package/vendor/gstack/review/SKILL.md +1138 -0
  63. package/vendor/gstack/review/TODOS-format.md +62 -0
  64. package/vendor/gstack/review/checklist.md +220 -0
  65. package/vendor/gstack/review/design-checklist.md +132 -0
  66. package/vendor/gstack/review/greptile-triage.md +220 -0
  67. package/vendor/gstack/setup-browser-cookies/SKILL.md +348 -0
  68. package/vendor/gstack/setup-deploy/SKILL.md +528 -0
  69. package/vendor/gstack/ship/SKILL.md +1931 -0
  70. package/vendor/gstack/unfreeze/SKILL.md +40 -0
@@ -0,0 +1,252 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import { isAuthenticated } from '../core/config.js';
4
+ import { chat } from '../core/claude.js';
5
+ import { getProjectContext, listFiles, readFile, getFrontendFiles } from '../core/codebase.js';
6
+ import { isConnected, getConnection } from '../connections/index.js';
7
+ import { fileURLToPath } from 'url';
8
+ import { dirname, join } from 'path';
9
+
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+
13
+ // Built-in skills registry
14
+ const SKILLS = {
15
+ 'front-end-design': {
16
+ name: 'Front-end Design',
17
+ description: 'Expert UI/UX design assistance',
18
+ commands: ['design', 'ui', 'ux'],
19
+ promptFile: '../../skills/front-end-design/prompts/system.md',
20
+ },
21
+ 'product-expert': {
22
+ name: 'Product Expert',
23
+ description: 'Product management and specifications',
24
+ commands: ['product', 'prd', 'spec'],
25
+ promptFile: '../../skills/product-expert/prompts/system.md',
26
+ },
27
+ 'github-manager': {
28
+ name: 'GitHub Manager',
29
+ description: 'GitHub workflows and PR management',
30
+ commands: ['github', 'gh', 'pr'],
31
+ promptFile: '../../skills/github-manager/prompts/system.md',
32
+ requiredConnections: ['github'],
33
+ },
34
+ 'front-end-testing': {
35
+ name: 'Front-end Testing',
36
+ description: 'Test generation and coverage analysis',
37
+ commands: ['test', 'testing', 'jest'],
38
+ promptFile: '../../skills/front-end-testing/prompts/system.md',
39
+ },
40
+ 'server-admin': {
41
+ name: 'Server Admin',
42
+ description: 'AI-assisted server administration',
43
+ commands: ['server', 'ssh', 'admin'],
44
+ promptFile: '../../skills/server-admin/prompts/system.md',
45
+ requiredConnections: ['servers'],
46
+ },
47
+ };
48
+
49
+ export function listSkills() {
50
+ console.log();
51
+ console.log(chalk.hex('#215ff6').bold(' Installed Skills'));
52
+ console.log(chalk.hex('#4d7fff')(' ─────────────────────────────────────────'));
53
+ console.log();
54
+
55
+ for (const [id, skill] of Object.entries(SKILLS)) {
56
+ const commands = skill.commands.map(c => `slashdev ${c}`).join(', ');
57
+ console.log(` ${chalk.hex('#4d7fff')('◈')} ${chalk.hex('#215ff6').bold(skill.name)}`);
58
+ console.log(` ${chalk.dim(skill.description)}`);
59
+ console.log(` ${chalk.dim('Commands:')} ${chalk.hex('#7a9fff')(commands)}`);
60
+ console.log();
61
+ }
62
+ }
63
+
64
+ export function getSkillByCommand(command) {
65
+ for (const [id, skill] of Object.entries(SKILLS)) {
66
+ if (skill.commands.includes(command)) {
67
+ return { id, ...skill };
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+
73
+ export async function runSkill(skillId, prompt, options = {}) {
74
+ const skill = SKILLS[skillId];
75
+ if (!skill) {
76
+ console.log(chalk.red(` Unknown skill: ${skillId}`));
77
+ return;
78
+ }
79
+
80
+ if (!isAuthenticated()) {
81
+ console.log();
82
+ console.log(chalk.hex('#7a9fff')(' You need to login first.'));
83
+ console.log(chalk.dim(` Run ${chalk.hex('#215ff6')('slashdev login')} to authenticate.`));
84
+ console.log();
85
+ return;
86
+ }
87
+
88
+ if (skill.requiredConnections) {
89
+ for (const connId of skill.requiredConnections) {
90
+ if (!isConnected(connId)) {
91
+ console.log();
92
+ console.log(
93
+ chalk.hex('#7a9fff')(
94
+ ` This skill requires a ${connId} connection.`
95
+ )
96
+ );
97
+ console.log(
98
+ chalk.dim(
99
+ ` Run ${chalk.hex('#215ff6')(`slashdev connect ${connId}`)} to set it up.`
100
+ )
101
+ );
102
+ console.log();
103
+ return;
104
+ }
105
+ }
106
+ }
107
+
108
+ const cwd = process.cwd();
109
+ const projectContext = getProjectContext(cwd);
110
+
111
+ // Load system prompt
112
+ let systemPrompt = '';
113
+ try {
114
+ const promptPath = join(__dirname, skill.promptFile);
115
+ systemPrompt = readFile(promptPath);
116
+ } catch (e) {
117
+ // Use default if file doesn't exist
118
+ systemPrompt = getDefaultPrompt(skillId);
119
+ }
120
+
121
+ // Add project context to system prompt
122
+ systemPrompt += `\n\n## Current Project Context\n`;
123
+ systemPrompt += `- Framework: ${projectContext.framework}\n`;
124
+ systemPrompt += `- Has TypeScript: ${projectContext.hasTsConfig}\n`;
125
+ systemPrompt += `- Working Directory: ${cwd}\n`;
126
+
127
+ // Add connected services context
128
+ if (skill.requiredConnections) {
129
+ systemPrompt += `\n## Connected Services\n`;
130
+ for (const connId of skill.requiredConnections) {
131
+ const conn = getConnection(connId);
132
+ if (conn) {
133
+ if (Array.isArray(conn)) {
134
+ systemPrompt += `- ${connId}: ${conn.length} server(s) configured\n`;
135
+ for (const entry of conn) {
136
+ systemPrompt += ` - ${entry.name}: ${entry.username}@${entry.host}:${entry.port} (auth: ${entry.authType})\n`;
137
+ }
138
+ } else {
139
+ systemPrompt += `- ${connId}: connected as ${conn.username}\n`;
140
+ }
141
+ }
142
+ }
143
+ }
144
+
145
+ // Get relevant files based on skill
146
+ if (skillId === 'front-end-design' || skillId === 'front-end-testing') {
147
+ const files = getFrontendFiles(cwd).slice(0, 5);
148
+ if (files.length > 0) {
149
+ systemPrompt += `\n## Relevant Files\n`;
150
+ for (const file of files) {
151
+ systemPrompt += `- ${file.relativePath}\n`;
152
+ }
153
+ }
154
+ }
155
+
156
+ console.log();
157
+ console.log(chalk.hex('#215ff6').bold(` ${skill.name}`));
158
+ console.log(chalk.hex('#4d7fff')(' ─────────────────────────────────────────'));
159
+ console.log();
160
+
161
+ const spinner = ora({
162
+ text: chalk.hex('#4d7fff')('Thinking...'),
163
+ color: 'blue',
164
+ }).start();
165
+
166
+ try {
167
+ let response = '';
168
+
169
+ if (options.stream !== false) {
170
+ spinner.stop();
171
+ process.stdout.write(chalk.hex('#7a9fff')(' '));
172
+
173
+ response = await chat({
174
+ messages: [{ role: 'user', content: prompt }],
175
+ systemPrompt,
176
+ stream: true,
177
+ onStream: (text) => {
178
+ process.stdout.write(chalk.hex('#a6bfff')(text));
179
+ },
180
+ });
181
+
182
+ console.log('\n');
183
+ } else {
184
+ response = await chat({
185
+ messages: [{ role: 'user', content: prompt }],
186
+ systemPrompt,
187
+ });
188
+ spinner.stop();
189
+ console.log(chalk.hex('#a6bfff')(` ${response}`));
190
+ console.log();
191
+ }
192
+
193
+ return response;
194
+ } catch (error) {
195
+ spinner.fail(chalk.red(`Error: ${error.message}`));
196
+ }
197
+ }
198
+
199
+ function getDefaultPrompt(skillId) {
200
+ const prompts = {
201
+ 'front-end-design': `You are a senior front-end design expert. You help with:
202
+ - UI/UX design decisions
203
+ - Component architecture
204
+ - CSS and styling best practices
205
+ - Accessibility (WCAG compliance)
206
+ - Responsive design
207
+ - Design systems
208
+
209
+ Provide clear, actionable advice. Use code examples when helpful.`,
210
+
211
+ 'product-expert': `You are a senior product manager. You help with:
212
+ - Writing PRDs (Product Requirements Documents)
213
+ - Creating user stories with acceptance criteria
214
+ - Feature specifications
215
+ - Roadmap planning
216
+ - Stakeholder communication
217
+
218
+ Be thorough but concise. Focus on clarity and actionability.`,
219
+
220
+ 'github-manager': `You are a GitHub workflow expert. You help with:
221
+ - Creating well-structured PRs
222
+ - Writing clear commit messages
223
+ - Issue management and triage
224
+ - Release notes and changelogs
225
+ - Branch strategies
226
+ - Code review best practices
227
+
228
+ Provide practical, ready-to-use suggestions.`,
229
+
230
+ 'front-end-testing': `You are a front-end testing expert. You help with:
231
+ - Writing unit tests (Jest, Vitest)
232
+ - E2E tests (Playwright, Cypress)
233
+ - Component testing (Testing Library)
234
+ - Test coverage analysis
235
+ - Mock and stub strategies
236
+ - Testing best practices
237
+
238
+ Always provide complete, runnable test code.`,
239
+
240
+ 'server-admin': `You are an expert Linux server administrator. You help with:
241
+ - System administration and service management
242
+ - Security hardening and firewall configuration
243
+ - Web server setup (Nginx, Apache, Caddy)
244
+ - Database administration
245
+ - Docker and container management
246
+ - Monitoring, networking, and deployment
247
+
248
+ Always warn about destructive commands and suggest backups before changes.`,
249
+ };
250
+
251
+ return prompts[skillId] || 'You are a helpful assistant.';
252
+ }
@@ -0,0 +1,67 @@
1
+ import { homedir } from 'os';
2
+ import { join } from 'path';
3
+ import { existsSync, readdirSync } from 'fs';
4
+
5
+ const KNOWN_KEY_NAMES = [
6
+ 'id_rsa',
7
+ 'id_ed25519',
8
+ 'id_ecdsa',
9
+ 'id_dsa',
10
+ 'id_ed25519_sk',
11
+ 'id_ecdsa_sk',
12
+ ];
13
+
14
+ /**
15
+ * Scans ~/.ssh/ for SSH key pairs.
16
+ * Works on Linux, macOS, and Windows (all use os.homedir() + '.ssh').
17
+ * @returns {Array<{ name: string, privatePath: string, hasPublic: boolean }>}
18
+ */
19
+ export function detectSSHKeys() {
20
+ const sshDir = join(homedir(), '.ssh');
21
+
22
+ if (!existsSync(sshDir)) {
23
+ return [];
24
+ }
25
+
26
+ let entries;
27
+ try {
28
+ entries = readdirSync(sshDir);
29
+ } catch {
30
+ return [];
31
+ }
32
+
33
+ const keys = [];
34
+
35
+ // Check known key names first
36
+ for (const name of KNOWN_KEY_NAMES) {
37
+ const privatePath = join(sshDir, name);
38
+ const publicPath = join(sshDir, `${name}.pub`);
39
+
40
+ if (existsSync(privatePath)) {
41
+ keys.push({
42
+ name,
43
+ privatePath,
44
+ hasPublic: existsSync(publicPath),
45
+ });
46
+ }
47
+ }
48
+
49
+ // Discover custom keys via .pub file matching
50
+ for (const entry of entries) {
51
+ if (entry.endsWith('.pub')) {
52
+ const baseName = entry.slice(0, -4);
53
+ if (!KNOWN_KEY_NAMES.includes(baseName)) {
54
+ const privatePath = join(sshDir, baseName);
55
+ if (existsSync(privatePath)) {
56
+ keys.push({
57
+ name: baseName,
58
+ privatePath,
59
+ hasPublic: true,
60
+ });
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ return keys;
67
+ }
@@ -0,0 +1,5 @@
1
+ # Copy to .env and fill in values
2
+ # bun auto-loads .env — no dotenv needed
3
+
4
+ # Required for LLM-as-judge evals (bun run test:eval)
5
+ ANTHROPIC_API_KEY=sk-ant-your-key-here