@viniciuscarvalho/feature-marker 4.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.
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/bin/feature-marker.js +299 -0
- package/dist/agents/feature-marker.md +656 -0
- package/dist/feature-marker/.claude/settings.local.json +13 -0
- package/dist/feature-marker/SKILL.md +405 -0
- package/dist/feature-marker/feature-marker.sh +239 -0
- package/dist/feature-marker/install.sh +183 -0
- package/dist/feature-marker/lib/config.sh +89 -0
- package/dist/feature-marker/lib/dependency-installer.sh +206 -0
- package/dist/feature-marker/lib/menu.sh +329 -0
- package/dist/feature-marker/lib/platform-detector.sh +105 -0
- package/dist/feature-marker/lib/spec-workflow-bridge.sh +383 -0
- package/dist/feature-marker/lib/state-manager.sh +168 -0
- package/dist/feature-marker/lib/ui.sh +148 -0
- package/dist/feature-marker/resources/commit.md +165 -0
- package/dist/feature-marker/resources/spec-workflow/ABSTRACTION_PLAN.md +712 -0
- package/dist/feature-marker/resources/spec-workflow/README.md +129 -0
- package/dist/feature-marker/resources/spec-workflow/references/config.md +201 -0
- package/dist/feature-marker/resources/spec-workflow/references/personas.md +165 -0
- package/dist/feature-marker/resources/spec-workflow/references/spec-template.md +189 -0
- package/dist/feature-marker/resources/spec-workflow/references/spec-writer-integration.md +150 -0
- package/dist/feature-marker/resources/spec-workflow/skills/create-worktree/SKILL.md +135 -0
- package/dist/feature-marker/resources/spec-workflow/skills/idea-explorer/SKILL.md +107 -0
- package/dist/feature-marker/resources/spec-workflow/skills/spec-executor/SKILL.md +367 -0
- package/dist/feature-marker/resources/spec-workflow/skills/spec-orchestrator/SKILL.md +398 -0
- package/dist/feature-marker/resources/spec-workflow/skills/spec-workflow-init/SKILL.md +331 -0
- package/dist/feature-marker/resources/spec-workflow/skills/spec-writer/SKILL.md +379 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vinicius Carvalho Marques
|
|
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,69 @@
|
|
|
1
|
+
# feature-marker
|
|
2
|
+
|
|
3
|
+
> Automate your feature development workflow with AI-powered checkpoints for Claude Code
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/feature-marker)
|
|
6
|
+
[](https://github.com/Viniciuscarvalho/Feature-marker/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
**feature-marker** is a Claude Code skill that guides you through the complete feature development lifecycle: PRD → Tech Spec → Tasks → Implementation → Tests → PR.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Install via npx (recommended)
|
|
14
|
+
npx @viniciuscarvalho/feature-marker install
|
|
15
|
+
|
|
16
|
+
# Or install globally
|
|
17
|
+
npm install -g @viniciuscarvalho/feature-marker
|
|
18
|
+
feature-marker install
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
After installation, use in Claude Code:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Start a new feature workflow
|
|
27
|
+
/feature-marker prd-user-authentication
|
|
28
|
+
|
|
29
|
+
# Interactive mode
|
|
30
|
+
/feature-marker --interactive prd-user-authentication
|
|
31
|
+
|
|
32
|
+
# Check status
|
|
33
|
+
/feature-marker --status prd-user-authentication
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Commands
|
|
37
|
+
|
|
38
|
+
| Command | Description |
|
|
39
|
+
|---------|-------------|
|
|
40
|
+
| `npx feature-marker install` | Install skill to ~/.claude |
|
|
41
|
+
| `npx feature-marker uninstall` | Remove skill from ~/.claude |
|
|
42
|
+
| `npx feature-marker status` | Check installation status |
|
|
43
|
+
| `npx feature-marker help` | Show help |
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
- **Artifact Generation** — Auto-generates PRD, Tech Spec, and Tasks from requirements
|
|
48
|
+
- **4-Phase Workflow** — Analysis → Implementation → Tests → Commit & PR
|
|
49
|
+
- **Checkpoint/Resume** — Pause anytime, resume where you left off
|
|
50
|
+
- **Platform Detection** — Auto-detects GitHub, Azure DevOps, GitLab for PR creation
|
|
51
|
+
- **Multiple Modes** — Full workflow, tasks-only, Ralph Loop, or Spec-Driven
|
|
52
|
+
|
|
53
|
+
## Requirements
|
|
54
|
+
|
|
55
|
+
Commands in `~/.claude/commands/`:
|
|
56
|
+
- `create-prd.md`
|
|
57
|
+
- `generate-spec.md`
|
|
58
|
+
- `generate-tasks.md`
|
|
59
|
+
|
|
60
|
+
Templates in `~/.claude/docs/specs/`:
|
|
61
|
+
- `prd-template.md`
|
|
62
|
+
- `techspec-template.md`
|
|
63
|
+
- `tasks-template.md`
|
|
64
|
+
|
|
65
|
+
> Get these from [mindkit](https://github.com/Viniciuscarvalho/mindkit) or create your own.
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
MIT © [Vinicius Carvalho](https://github.com/Viniciuscarvalho)
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* feature-marker CLI
|
|
4
|
+
* Installs the feature-marker skill for Claude Code
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import { dirname, join } from 'path';
|
|
9
|
+
import { existsSync, mkdirSync, cpSync, chmodSync, readdirSync } from 'fs';
|
|
10
|
+
import { homedir } from 'os';
|
|
11
|
+
import { execSync } from 'child_process';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
const PACKAGE_ROOT = join(__dirname, '..');
|
|
16
|
+
|
|
17
|
+
const VERSION = '4.0.0';
|
|
18
|
+
|
|
19
|
+
const COLORS = {
|
|
20
|
+
reset: '\x1b[0m',
|
|
21
|
+
bold: '\x1b[1m',
|
|
22
|
+
green: '\x1b[32m',
|
|
23
|
+
yellow: '\x1b[33m',
|
|
24
|
+
blue: '\x1b[34m',
|
|
25
|
+
cyan: '\x1b[36m',
|
|
26
|
+
red: '\x1b[31m',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function log(msg, color = '') {
|
|
30
|
+
console.log(`${color}${msg}${COLORS.reset}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function success(msg) {
|
|
34
|
+
log(`✓ ${msg}`, COLORS.green);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function info(msg) {
|
|
38
|
+
log(`ℹ ${msg}`, COLORS.blue);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function warn(msg) {
|
|
42
|
+
log(`⚠ ${msg}`, COLORS.yellow);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function error(msg) {
|
|
46
|
+
log(`✗ ${msg}`, COLORS.red);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function banner() {
|
|
50
|
+
console.log(`
|
|
51
|
+
${COLORS.cyan}╔═══════════════════════════════════════════════════════════╗
|
|
52
|
+
║ ║
|
|
53
|
+
║ ${COLORS.bold}feature-marker${COLORS.reset}${COLORS.cyan} ║
|
|
54
|
+
║ AI-Powered Feature Development Workflow ║
|
|
55
|
+
║ ║
|
|
56
|
+
╚═══════════════════════════════════════════════════════════════╝${COLORS.reset}
|
|
57
|
+
`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function showHelp() {
|
|
61
|
+
banner();
|
|
62
|
+
console.log(`${COLORS.bold}Usage:${COLORS.reset}
|
|
63
|
+
npx feature-marker [command] [options]
|
|
64
|
+
|
|
65
|
+
${COLORS.bold}Commands:${COLORS.reset}
|
|
66
|
+
install Install feature-marker skill to ~/.claude
|
|
67
|
+
uninstall Remove feature-marker skill from ~/.claude
|
|
68
|
+
status Check installation status
|
|
69
|
+
help Show this help message
|
|
70
|
+
|
|
71
|
+
${COLORS.bold}Options:${COLORS.reset}
|
|
72
|
+
--silent Suppress output (for postinstall)
|
|
73
|
+
--with-tui Also install the TUI application (requires Rust)
|
|
74
|
+
--dry-run Show what would be installed without making changes
|
|
75
|
+
--version Show version
|
|
76
|
+
|
|
77
|
+
${COLORS.bold}Examples:${COLORS.reset}
|
|
78
|
+
npx feature-marker install
|
|
79
|
+
npx feature-marker install --with-tui
|
|
80
|
+
npx feature-marker uninstall
|
|
81
|
+
npx feature-marker status
|
|
82
|
+
|
|
83
|
+
${COLORS.bold}After installation:${COLORS.reset}
|
|
84
|
+
In Claude Code, use: /feature-marker <feature-slug>
|
|
85
|
+
Example: /feature-marker prd-user-authentication
|
|
86
|
+
`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function getInstallPaths() {
|
|
90
|
+
const home = homedir();
|
|
91
|
+
return {
|
|
92
|
+
skillDst: join(home, '.claude', 'skills', 'feature-marker'),
|
|
93
|
+
agentDst: join(home, '.claude', 'agents', 'feature-marker.md'),
|
|
94
|
+
skillSrc: join(PACKAGE_ROOT, 'dist', 'feature-marker'),
|
|
95
|
+
agentSrc: join(PACKAGE_ROOT, 'dist', 'agents', 'feature-marker.md'),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function checkStatus() {
|
|
100
|
+
const paths = getInstallPaths();
|
|
101
|
+
|
|
102
|
+
banner();
|
|
103
|
+
log(`${COLORS.bold}Installation Status:${COLORS.reset}\n`);
|
|
104
|
+
|
|
105
|
+
const skillInstalled = existsSync(paths.skillDst);
|
|
106
|
+
const agentInstalled = existsSync(paths.agentDst);
|
|
107
|
+
|
|
108
|
+
if (skillInstalled) {
|
|
109
|
+
success(`Skill installed: ${paths.skillDst}`);
|
|
110
|
+
} else {
|
|
111
|
+
warn(`Skill not installed: ${paths.skillDst}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (agentInstalled) {
|
|
115
|
+
success(`Agent installed: ${paths.agentDst}`);
|
|
116
|
+
} else {
|
|
117
|
+
warn(`Agent not installed: ${paths.agentDst}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
console.log('');
|
|
121
|
+
|
|
122
|
+
if (skillInstalled && agentInstalled) {
|
|
123
|
+
info('feature-marker is ready to use!');
|
|
124
|
+
info('In Claude Code, use: /feature-marker <feature-slug>');
|
|
125
|
+
} else {
|
|
126
|
+
info('Run "npx feature-marker install" to install.');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function install(options = {}) {
|
|
131
|
+
const { silent = false, dryRun = false, withTui = false } = options;
|
|
132
|
+
const paths = getInstallPaths();
|
|
133
|
+
|
|
134
|
+
if (!silent) {
|
|
135
|
+
banner();
|
|
136
|
+
log(`${COLORS.bold}Installing feature-marker v${VERSION}${COLORS.reset}\n`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Validate source files
|
|
140
|
+
if (!existsSync(paths.skillSrc)) {
|
|
141
|
+
error(`Skill source not found: ${paths.skillSrc}`);
|
|
142
|
+
error('Package may be corrupted. Try reinstalling.');
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (!existsSync(paths.agentSrc)) {
|
|
147
|
+
error(`Agent source not found: ${paths.agentSrc}`);
|
|
148
|
+
error('Package may be corrupted. Try reinstalling.');
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (dryRun) {
|
|
153
|
+
info('Dry-run mode: No files will be copied.\n');
|
|
154
|
+
log(`Would copy:`);
|
|
155
|
+
log(` ${paths.skillSrc}/ -> ${paths.skillDst}/`);
|
|
156
|
+
log(` ${paths.agentSrc} -> ${paths.agentDst}`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Create directories
|
|
161
|
+
if (!silent) info('Creating directories...');
|
|
162
|
+
mkdirSync(paths.skillDst, { recursive: true });
|
|
163
|
+
mkdirSync(dirname(paths.agentDst), { recursive: true });
|
|
164
|
+
|
|
165
|
+
// Copy skill files
|
|
166
|
+
if (!silent) info('Copying skill files...');
|
|
167
|
+
cpSync(paths.skillSrc, paths.skillDst, { recursive: true });
|
|
168
|
+
|
|
169
|
+
// Copy agent file
|
|
170
|
+
if (!silent) info('Copying agent file...');
|
|
171
|
+
cpSync(paths.agentSrc, paths.agentDst);
|
|
172
|
+
|
|
173
|
+
// Set permissions
|
|
174
|
+
if (!silent) info('Setting permissions...');
|
|
175
|
+
try {
|
|
176
|
+
chmodSync(join(paths.skillDst, 'feature-marker.sh'), 0o755);
|
|
177
|
+
const libDir = join(paths.skillDst, 'lib');
|
|
178
|
+
if (existsSync(libDir)) {
|
|
179
|
+
readdirSync(libDir)
|
|
180
|
+
.filter(f => f.endsWith('.sh'))
|
|
181
|
+
.forEach(f => chmodSync(join(libDir, f), 0o755));
|
|
182
|
+
}
|
|
183
|
+
} catch (e) {
|
|
184
|
+
// Ignore permission errors on Windows
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (!silent) {
|
|
188
|
+
console.log('');
|
|
189
|
+
log(`${COLORS.green}${COLORS.bold}╔═══════════════════════════════════════╗${COLORS.reset}`);
|
|
190
|
+
log(`${COLORS.green}${COLORS.bold}║ Installation Complete! ║${COLORS.reset}`);
|
|
191
|
+
log(`${COLORS.green}${COLORS.bold}╚═══════════════════════════════════════╝${COLORS.reset}`);
|
|
192
|
+
console.log('');
|
|
193
|
+
success(`Skill: ${paths.skillDst}`);
|
|
194
|
+
success(`Agent: ${paths.agentDst}`);
|
|
195
|
+
console.log('');
|
|
196
|
+
info('In Claude Code, use: /feature-marker <feature-slug>');
|
|
197
|
+
info('Example: /feature-marker prd-user-authentication');
|
|
198
|
+
console.log('');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Install TUI if requested
|
|
202
|
+
if (withTui) {
|
|
203
|
+
installTui(silent);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function installTui(silent = false) {
|
|
208
|
+
if (!silent) {
|
|
209
|
+
console.log('');
|
|
210
|
+
info('TUI installation requires Rust/Cargo and building from source.');
|
|
211
|
+
info('To install TUI manually:');
|
|
212
|
+
console.log('');
|
|
213
|
+
log(' git clone https://github.com/Viniciuscarvalho/Feature-marker.git');
|
|
214
|
+
log(' cd Feature-marker/feature-marker-tui');
|
|
215
|
+
log(' cargo build --release');
|
|
216
|
+
log(' cp target/release/feature-marker-tui ~/.local/bin/');
|
|
217
|
+
console.log('');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function uninstall(options = {}) {
|
|
222
|
+
const { silent = false, dryRun = false } = options;
|
|
223
|
+
const paths = getInstallPaths();
|
|
224
|
+
|
|
225
|
+
if (!silent) {
|
|
226
|
+
banner();
|
|
227
|
+
log(`${COLORS.bold}Uninstalling feature-marker${COLORS.reset}\n`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const skillExists = existsSync(paths.skillDst);
|
|
231
|
+
const agentExists = existsSync(paths.agentDst);
|
|
232
|
+
|
|
233
|
+
if (!skillExists && !agentExists) {
|
|
234
|
+
if (!silent) warn('feature-marker is not installed.');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (dryRun) {
|
|
239
|
+
info('Dry-run mode: No files will be removed.\n');
|
|
240
|
+
if (skillExists) log(`Would remove: ${paths.skillDst}`);
|
|
241
|
+
if (agentExists) log(`Would remove: ${paths.agentDst}`);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (skillExists) {
|
|
246
|
+
if (!silent) info(`Removing skill: ${paths.skillDst}`);
|
|
247
|
+
execSync(`rm -rf "${paths.skillDst}"`);
|
|
248
|
+
if (!silent) success('Skill removed');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (agentExists) {
|
|
252
|
+
if (!silent) info(`Removing agent: ${paths.agentDst}`);
|
|
253
|
+
execSync(`rm -f "${paths.agentDst}"`);
|
|
254
|
+
if (!silent) success('Agent removed');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (!silent) {
|
|
258
|
+
console.log('');
|
|
259
|
+
success('feature-marker has been uninstalled.');
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function main() {
|
|
264
|
+
const args = process.argv.slice(2);
|
|
265
|
+
const command = args.find(a => !a.startsWith('-')) || 'help';
|
|
266
|
+
const options = {
|
|
267
|
+
silent: args.includes('--silent'),
|
|
268
|
+
dryRun: args.includes('--dry-run'),
|
|
269
|
+
withTui: args.includes('--with-tui'),
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
if (args.includes('--version') || args.includes('-V')) {
|
|
273
|
+
console.log(`feature-marker v${VERSION}`);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
switch (command) {
|
|
278
|
+
case 'install':
|
|
279
|
+
install(options);
|
|
280
|
+
break;
|
|
281
|
+
case 'uninstall':
|
|
282
|
+
uninstall(options);
|
|
283
|
+
break;
|
|
284
|
+
case 'status':
|
|
285
|
+
checkStatus();
|
|
286
|
+
break;
|
|
287
|
+
case 'help':
|
|
288
|
+
default:
|
|
289
|
+
showHelp();
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Helper function for path operations
|
|
295
|
+
function dirname(path) {
|
|
296
|
+
return path.split('/').slice(0, -1).join('/') || '/';
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
main();
|