@damper/cli 0.1.2 → 0.1.4
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 +36 -0
- package/dist/commands/setup.d.ts +4 -1
- package/dist/commands/setup.js +58 -7
- package/dist/index.js +8 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -17,8 +17,12 @@ Claude then handles the task lifecycle via Damper MCP - logging commits, adding
|
|
|
17
17
|
# Run directly with npx (recommended)
|
|
18
18
|
npx @damper/cli
|
|
19
19
|
|
|
20
|
+
# Alternative: use the 'damper' command name
|
|
21
|
+
npx damper
|
|
22
|
+
|
|
20
23
|
# Or install globally
|
|
21
24
|
npm install -g @damper/cli
|
|
25
|
+
damper
|
|
22
26
|
```
|
|
23
27
|
|
|
24
28
|
### Prerequisites
|
|
@@ -59,6 +63,11 @@ Configure Damper MCP in Claude Code. Run this first if you haven't set up MCP ye
|
|
|
59
63
|
- Configures `~/.claude/settings.json` with Damper MCP
|
|
60
64
|
- Prompts for API key if not in environment
|
|
61
65
|
|
|
66
|
+
```bash
|
|
67
|
+
npx @damper/cli setup # First-time setup
|
|
68
|
+
npx @damper/cli setup --reconfigure # Change API key
|
|
69
|
+
```
|
|
70
|
+
|
|
62
71
|
### `npx @damper/cli status`
|
|
63
72
|
|
|
64
73
|
Show all tracked worktrees and their task status.
|
|
@@ -148,6 +157,33 @@ Once Claude is running, it handles:
|
|
|
148
157
|
| `DAMPER_API_KEY` | Your Damper API key (or configure via `setup`) |
|
|
149
158
|
| `DAMPER_API_URL` | API URL override (default: `https://api.usedamper.com`) |
|
|
150
159
|
|
|
160
|
+
### Per-Project API Keys
|
|
161
|
+
|
|
162
|
+
Damper API keys are project-scoped. If you work with multiple Damper projects, you can use different keys:
|
|
163
|
+
|
|
164
|
+
**Option 1: Environment variable (recommended)**
|
|
165
|
+
```bash
|
|
166
|
+
# Set in your shell or project's .env file
|
|
167
|
+
export DAMPER_API_KEY=your-project-specific-key
|
|
168
|
+
npx @damper/cli
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Option 2: Use direnv for automatic switching**
|
|
172
|
+
```bash
|
|
173
|
+
# In each project directory, create .envrc:
|
|
174
|
+
echo 'export DAMPER_API_KEY=your-key-here' > .envrc
|
|
175
|
+
direnv allow
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Option 3: Reconfigure when switching projects**
|
|
179
|
+
```bash
|
|
180
|
+
npx @damper/cli setup --reconfigure
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The CLI checks for keys in this order:
|
|
184
|
+
1. `DAMPER_API_KEY` environment variable
|
|
185
|
+
2. `~/.claude/settings.json` (configured via `setup`)
|
|
186
|
+
|
|
151
187
|
## How it Works
|
|
152
188
|
|
|
153
189
|
### Worktree Isolation
|
package/dist/commands/setup.d.ts
CHANGED
package/dist/commands/setup.js
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
import { confirm } from '@inquirer/prompts';
|
|
1
2
|
import pc from 'picocolors';
|
|
2
|
-
import { isDamperMcpConfigured, getConfiguredApiKey, setupDamperMcp, isClaudeInstalled, } from '../services/claude.js';
|
|
3
|
+
import { isDamperMcpConfigured, getConfiguredApiKey, setupDamperMcp, configureDamperMcp, isClaudeInstalled, } from '../services/claude.js';
|
|
3
4
|
import { createDamperApi } from '../services/damper-api.js';
|
|
4
|
-
|
|
5
|
+
async function promptForNewApiKey() {
|
|
6
|
+
const { password } = await import('@inquirer/prompts');
|
|
7
|
+
console.log(pc.dim('\nGet your API key from: https://usedamper.com → Settings → API Keys\n'));
|
|
8
|
+
const apiKey = await password({
|
|
9
|
+
message: 'Enter your new Damper API key:',
|
|
10
|
+
mask: '*',
|
|
11
|
+
validate: (value) => {
|
|
12
|
+
if (!value || value.trim().length === 0) {
|
|
13
|
+
return 'API key is required';
|
|
14
|
+
}
|
|
15
|
+
if (value.length < 10) {
|
|
16
|
+
return 'API key seems too short';
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
return apiKey.trim();
|
|
22
|
+
}
|
|
23
|
+
export async function setupCommand(options = {}) {
|
|
5
24
|
console.log(pc.bold('\n@damper/cli Setup\n'));
|
|
6
25
|
// Check Claude CLI
|
|
7
26
|
const claudeInstalled = await isClaudeInstalled();
|
|
@@ -18,6 +37,30 @@ export async function setupCommand() {
|
|
|
18
37
|
if (mcpConfigured && apiKey) {
|
|
19
38
|
console.log(pc.green('✓ Damper MCP configured'));
|
|
20
39
|
console.log(pc.dim(` API key: ${'*'.repeat(12)} (${apiKey.length} chars)`));
|
|
40
|
+
// If reconfigure flag is set, prompt for new key
|
|
41
|
+
if (options.reconfigure) {
|
|
42
|
+
console.log(pc.yellow('\nReconfiguring API key...'));
|
|
43
|
+
const newKey = await promptForNewApiKey();
|
|
44
|
+
if (newKey) {
|
|
45
|
+
// Verify before saving
|
|
46
|
+
console.log(pc.dim('\nVerifying new API key...'));
|
|
47
|
+
try {
|
|
48
|
+
const api = createDamperApi(newKey);
|
|
49
|
+
const { project } = await api.listTasks({ limit: 1 });
|
|
50
|
+
console.log(pc.green(`✓ Connected to project: ${project}`));
|
|
51
|
+
// Save the new key
|
|
52
|
+
configureDamperMcp(newKey);
|
|
53
|
+
process.env.DAMPER_API_KEY = newKey;
|
|
54
|
+
console.log(pc.green('\n✓ API key updated successfully!\n'));
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const error = err;
|
|
58
|
+
console.log(pc.red(`✗ API key verification failed: ${error.message}`));
|
|
59
|
+
console.log(pc.dim(' API key was NOT updated.\n'));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
21
64
|
// Verify the API key works
|
|
22
65
|
console.log(pc.dim('\nVerifying API key...'));
|
|
23
66
|
try {
|
|
@@ -28,16 +71,24 @@ export async function setupCommand() {
|
|
|
28
71
|
catch (err) {
|
|
29
72
|
const error = err;
|
|
30
73
|
console.log(pc.red(`✗ API key verification failed: ${error.message}`));
|
|
31
|
-
console.log(pc.dim(' You may need to reconfigure with a valid key.\n'));
|
|
32
74
|
// Offer to reconfigure
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
75
|
+
const shouldReconfigure = await confirm({
|
|
76
|
+
message: 'Would you like to enter a new API key?',
|
|
77
|
+
default: true,
|
|
78
|
+
});
|
|
79
|
+
if (shouldReconfigure) {
|
|
80
|
+
const newKey = await promptForNewApiKey();
|
|
81
|
+
if (newKey) {
|
|
82
|
+
configureDamperMcp(newKey);
|
|
83
|
+
process.env.DAMPER_API_KEY = newKey;
|
|
84
|
+
console.log(pc.green('\n✓ API key updated!\n'));
|
|
85
|
+
}
|
|
36
86
|
}
|
|
37
87
|
return;
|
|
38
88
|
}
|
|
39
89
|
console.log(pc.green('\n✓ All checks passed! You\'re ready to use @damper/cli.\n'));
|
|
40
|
-
console.log(pc.dim('Run `npx @damper/cli` to start working on a task
|
|
90
|
+
console.log(pc.dim('Run `npx @damper/cli` to start working on a task.'));
|
|
91
|
+
console.log(pc.dim('Run `npx @damper/cli setup --reconfigure` to change API key.\n'));
|
|
41
92
|
return;
|
|
42
93
|
}
|
|
43
94
|
// Not configured - run setup
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { startCommand } from './commands/start.js';
|
|
|
4
4
|
import { statusCommand } from './commands/status.js';
|
|
5
5
|
import { cleanupCommand } from './commands/cleanup.js';
|
|
6
6
|
import { setupCommand } from './commands/setup.js';
|
|
7
|
-
const VERSION = '0.1.
|
|
7
|
+
const VERSION = '0.1.4';
|
|
8
8
|
function showHelp() {
|
|
9
9
|
console.log(`
|
|
10
10
|
${pc.bold('@damper/cli')} - Agent orchestration for Damper tasks
|
|
@@ -19,6 +19,7 @@ ${pc.bold('Options:')}
|
|
|
19
19
|
--task <id> Work on a specific task
|
|
20
20
|
--type <type> Filter by type: bug, feature, improvement, task
|
|
21
21
|
--status <status> Filter by status: planned, in_progress, done, all
|
|
22
|
+
--reconfigure Change API key (use with setup command)
|
|
22
23
|
-h, --help Show this help message
|
|
23
24
|
-v, --version Show version
|
|
24
25
|
|
|
@@ -49,6 +50,7 @@ function showVersion() {
|
|
|
49
50
|
function parseArgs(args) {
|
|
50
51
|
const result = {
|
|
51
52
|
options: {},
|
|
53
|
+
setupOptions: {},
|
|
52
54
|
help: false,
|
|
53
55
|
version: false,
|
|
54
56
|
};
|
|
@@ -75,6 +77,9 @@ function parseArgs(args) {
|
|
|
75
77
|
result.options.status = status;
|
|
76
78
|
}
|
|
77
79
|
}
|
|
80
|
+
else if (arg === '--reconfigure') {
|
|
81
|
+
result.setupOptions.reconfigure = true;
|
|
82
|
+
}
|
|
78
83
|
else if (!arg.startsWith('-') && !result.command) {
|
|
79
84
|
result.command = arg;
|
|
80
85
|
}
|
|
@@ -83,7 +88,7 @@ function parseArgs(args) {
|
|
|
83
88
|
}
|
|
84
89
|
async function main() {
|
|
85
90
|
const args = process.argv.slice(2);
|
|
86
|
-
const { command, options, help, version } = parseArgs(args);
|
|
91
|
+
const { command, options, setupOptions, help, version } = parseArgs(args);
|
|
87
92
|
if (version) {
|
|
88
93
|
showVersion();
|
|
89
94
|
return;
|
|
@@ -95,7 +100,7 @@ async function main() {
|
|
|
95
100
|
try {
|
|
96
101
|
switch (command) {
|
|
97
102
|
case 'setup':
|
|
98
|
-
await setupCommand();
|
|
103
|
+
await setupCommand(setupOptions);
|
|
99
104
|
break;
|
|
100
105
|
case 'status':
|
|
101
106
|
await statusCommand();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@damper/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "CLI tool for orchestrating Damper task workflows with Claude Code",
|
|
5
5
|
"author": "Damper <hello@usedamper.com>",
|
|
6
6
|
"repository": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"homepage": "https://usedamper.com",
|
|
12
12
|
"type": "module",
|
|
13
13
|
"bin": {
|
|
14
|
+
"damper": "./dist/index.js",
|
|
14
15
|
"damper-cli": "./dist/index.js"
|
|
15
16
|
},
|
|
16
17
|
"main": "./dist/index.js",
|