productkit 1.6.0 → 1.7.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/README.md +1 -0
- package/package.json +1 -1
- package/src/cli.js +9 -1
- package/src/commands/completion.js +91 -0
- package/src/commands/reset.js +47 -13
package/README.md
CHANGED
|
@@ -99,6 +99,7 @@ These markdown files are your product foundation — share them with your team,
|
|
|
99
99
|
| `productkit update` | Refresh slash commands to the latest version |
|
|
100
100
|
| `productkit reset` | Remove all artifacts and start over |
|
|
101
101
|
| `productkit list` | Show available slash commands with descriptions |
|
|
102
|
+
| `productkit completion` | Output shell completion script (bash/zsh) |
|
|
102
103
|
| `productkit check` | Verify Claude Code is installed |
|
|
103
104
|
|
|
104
105
|
## How It Works
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -8,13 +8,14 @@ const statusCommand = require('./commands/status');
|
|
|
8
8
|
const updateCommand = require('./commands/update');
|
|
9
9
|
const resetCommand = require('./commands/reset');
|
|
10
10
|
const listCommand = require('./commands/list');
|
|
11
|
+
const completionCommand = require('./commands/completion');
|
|
11
12
|
|
|
12
13
|
const program = new Command();
|
|
13
14
|
|
|
14
15
|
program
|
|
15
16
|
.name('productkit')
|
|
16
17
|
.description(chalk.cyan.bold('Product thinking toolkit for Claude Code'))
|
|
17
|
-
.version('1.
|
|
18
|
+
.version('1.7.0');
|
|
18
19
|
|
|
19
20
|
program
|
|
20
21
|
.command('init [projectName]')
|
|
@@ -40,6 +41,7 @@ program
|
|
|
40
41
|
program
|
|
41
42
|
.command('reset')
|
|
42
43
|
.description('Remove all artifacts and start over')
|
|
44
|
+
.option('--force', 'Skip confirmation prompt')
|
|
43
45
|
.action(resetCommand);
|
|
44
46
|
|
|
45
47
|
program
|
|
@@ -47,6 +49,12 @@ program
|
|
|
47
49
|
.description('Show available slash commands with descriptions')
|
|
48
50
|
.action(listCommand);
|
|
49
51
|
|
|
52
|
+
program
|
|
53
|
+
.command('completion')
|
|
54
|
+
.description('Output shell completion script')
|
|
55
|
+
.option('--shell <shell>', 'Shell type (bash or zsh)')
|
|
56
|
+
.action(completionCommand);
|
|
57
|
+
|
|
50
58
|
program.parse(process.argv);
|
|
51
59
|
|
|
52
60
|
if (process.argv.length === 2) {
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
|
|
3
|
+
const ZSH_COMPLETION = `#compdef productkit
|
|
4
|
+
|
|
5
|
+
_productkit() {
|
|
6
|
+
local -a commands
|
|
7
|
+
commands=(
|
|
8
|
+
'init:Initialize a new product research project'
|
|
9
|
+
'check:Verify Claude Code is installed and available'
|
|
10
|
+
'status:Show which artifacts exist and what steps remain'
|
|
11
|
+
'update:Refresh slash commands to the latest version'
|
|
12
|
+
'reset:Remove all artifacts and start over'
|
|
13
|
+
'list:Show available slash commands with descriptions'
|
|
14
|
+
'completion:Output shell completion script'
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
_arguments -C \\
|
|
18
|
+
'1:command:->command' \\
|
|
19
|
+
'*::arg:->args'
|
|
20
|
+
|
|
21
|
+
case "$state" in
|
|
22
|
+
command)
|
|
23
|
+
_describe 'command' commands
|
|
24
|
+
;;
|
|
25
|
+
args)
|
|
26
|
+
case "$words[1]" in
|
|
27
|
+
init)
|
|
28
|
+
_arguments \\
|
|
29
|
+
'--existing[Add Product Kit to the current directory]' \\
|
|
30
|
+
'1:project name:_files -/'
|
|
31
|
+
;;
|
|
32
|
+
reset)
|
|
33
|
+
_arguments \\
|
|
34
|
+
'--force[Skip confirmation prompt]'
|
|
35
|
+
;;
|
|
36
|
+
esac
|
|
37
|
+
;;
|
|
38
|
+
esac
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
_productkit "$@"`;
|
|
42
|
+
|
|
43
|
+
const BASH_COMPLETION = `_productkit() {
|
|
44
|
+
local cur prev commands
|
|
45
|
+
COMPREPLY=()
|
|
46
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
47
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
48
|
+
commands="init check status update reset list completion"
|
|
49
|
+
|
|
50
|
+
case "\${prev}" in
|
|
51
|
+
productkit)
|
|
52
|
+
COMPREPLY=( $(compgen -W "\${commands}" -- "\${cur}") )
|
|
53
|
+
return 0
|
|
54
|
+
;;
|
|
55
|
+
init)
|
|
56
|
+
COMPREPLY=( $(compgen -W "--existing" -- "\${cur}") )
|
|
57
|
+
return 0
|
|
58
|
+
;;
|
|
59
|
+
reset)
|
|
60
|
+
COMPREPLY=( $(compgen -W "--force" -- "\${cur}") )
|
|
61
|
+
return 0
|
|
62
|
+
;;
|
|
63
|
+
esac
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
complete -F _productkit productkit`;
|
|
67
|
+
|
|
68
|
+
async function completion(options) {
|
|
69
|
+
if (options.shell === 'bash') {
|
|
70
|
+
console.log(BASH_COMPLETION);
|
|
71
|
+
} else if (options.shell === 'zsh') {
|
|
72
|
+
console.log(ZSH_COMPLETION);
|
|
73
|
+
} else {
|
|
74
|
+
// Auto-detect
|
|
75
|
+
const shell = process.env.SHELL || '';
|
|
76
|
+
if (shell.includes('zsh')) {
|
|
77
|
+
console.log(ZSH_COMPLETION);
|
|
78
|
+
} else {
|
|
79
|
+
console.log(BASH_COMPLETION);
|
|
80
|
+
}
|
|
81
|
+
console.error();
|
|
82
|
+
console.error(chalk.cyan('Add to your shell config:'));
|
|
83
|
+
if (shell.includes('zsh')) {
|
|
84
|
+
console.error(` echo 'eval "$(productkit completion)"' >> ~/.zshrc`);
|
|
85
|
+
} else {
|
|
86
|
+
console.error(` echo 'eval "$(productkit completion)"' >> ~/.bashrc`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = completion;
|
package/src/commands/reset.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
|
+
const readline = require('readline');
|
|
4
5
|
|
|
5
6
|
const ARTIFACTS = [
|
|
6
7
|
'constitution.md',
|
|
@@ -12,7 +13,20 @@ const ARTIFACTS = [
|
|
|
12
13
|
'spec.md',
|
|
13
14
|
];
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
function confirm(question) {
|
|
17
|
+
const rl = readline.createInterface({
|
|
18
|
+
input: process.stdin,
|
|
19
|
+
output: process.stdout,
|
|
20
|
+
});
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
rl.question(question, (answer) => {
|
|
23
|
+
rl.close();
|
|
24
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function reset(options) {
|
|
16
30
|
const root = process.cwd();
|
|
17
31
|
const configPath = path.join(root, '.productkit', 'config.json');
|
|
18
32
|
|
|
@@ -22,24 +36,44 @@ async function reset() {
|
|
|
22
36
|
process.exit(1);
|
|
23
37
|
}
|
|
24
38
|
|
|
25
|
-
|
|
39
|
+
// Find existing artifacts
|
|
40
|
+
const existing = ARTIFACTS.filter(file =>
|
|
41
|
+
fs.existsSync(path.join(root, file))
|
|
42
|
+
);
|
|
26
43
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
removed++;
|
|
33
|
-
}
|
|
44
|
+
if (existing.length === 0) {
|
|
45
|
+
console.log();
|
|
46
|
+
console.log(chalk.green.bold('Nothing to reset — no artifacts found.'));
|
|
47
|
+
console.log();
|
|
48
|
+
return;
|
|
34
49
|
}
|
|
35
50
|
|
|
51
|
+
// Show what will be deleted
|
|
36
52
|
console.log();
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
console.log(chalk.green.bold('Nothing to reset — no artifacts found.'));
|
|
53
|
+
console.log(chalk.yellow.bold(`Found ${existing.length} artifact${existing.length === 1 ? '' : 's'}:`));
|
|
54
|
+
for (const file of existing) {
|
|
55
|
+
console.log(chalk.yellow(` ${file}`));
|
|
41
56
|
}
|
|
42
57
|
console.log();
|
|
58
|
+
|
|
59
|
+
// Confirm unless --force
|
|
60
|
+
if (!options.force) {
|
|
61
|
+
const yes = await confirm(chalk.red('Delete these artifacts? (y/N) '));
|
|
62
|
+
if (!yes) {
|
|
63
|
+
console.log('Reset cancelled.');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (const file of existing) {
|
|
70
|
+
fs.removeSync(path.join(root, file));
|
|
71
|
+
console.log(chalk.yellow(` removed ${file}`));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log();
|
|
75
|
+
console.log(chalk.green.bold(`Reset complete. ${existing.length} artifact${existing.length === 1 ? '' : 's'} removed.`));
|
|
76
|
+
console.log();
|
|
43
77
|
}
|
|
44
78
|
|
|
45
79
|
module.exports = reset;
|