@warpmetrics/coder 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/bin/init.js +91 -56
- package/defaults/agent-implement.yml +1 -0
- package/defaults/agent-revise.yml +1 -0
- package/package.json +1 -1
package/bin/init.js
CHANGED
|
@@ -19,47 +19,78 @@ function log(msg) {
|
|
|
19
19
|
console.log(msg);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
function getExistingSecrets() {
|
|
23
|
+
try {
|
|
24
|
+
execSync('gh --version', { stdio: 'ignore' });
|
|
25
|
+
} catch {
|
|
26
|
+
return null; // gh not available
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const output = execSync('gh secret list', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
|
|
30
|
+
const names = output.split('\n').map(line => line.split('\t')[0].trim()).filter(Boolean);
|
|
31
|
+
return new Set(names);
|
|
32
|
+
} catch {
|
|
33
|
+
return new Set(); // gh available but couldn't list (e.g. no repo context)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
22
37
|
async function main() {
|
|
23
38
|
log('');
|
|
24
39
|
log(' warp-coder \u2014 Agent pipeline for implementing GitHub issues');
|
|
25
40
|
log('');
|
|
26
41
|
|
|
42
|
+
const existingSecrets = getExistingSecrets();
|
|
43
|
+
const ghAvailable = existingSecrets !== null;
|
|
44
|
+
|
|
27
45
|
// 1. Anthropic API key
|
|
28
|
-
|
|
29
|
-
if (
|
|
46
|
+
let anthropicKey = null;
|
|
47
|
+
if (existingSecrets?.has('ANTHROPIC_API_KEY')) {
|
|
48
|
+
log(' \u2713 ANTHROPIC_API_KEY already set');
|
|
49
|
+
const replace = await ask(' Replace it? (y/N): ');
|
|
50
|
+
if (replace.toLowerCase() === 'y') {
|
|
51
|
+
anthropicKey = await ask(' ? Anthropic API key: ');
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
anthropicKey = await ask(' ? Anthropic API key: ');
|
|
55
|
+
}
|
|
56
|
+
if (anthropicKey && !anthropicKey.startsWith('sk-ant-')) {
|
|
30
57
|
log(' \u26a0 Warning: key doesn\'t start with sk-ant- \u2014 make sure this is a valid Anthropic API key');
|
|
31
58
|
}
|
|
32
59
|
|
|
33
60
|
// 2. WarpMetrics API key
|
|
34
|
-
|
|
35
|
-
if (
|
|
61
|
+
let wmKey = null;
|
|
62
|
+
if (existingSecrets?.has('WARPMETRICS_API_KEY')) {
|
|
63
|
+
log(' \u2713 WARPMETRICS_API_KEY already set');
|
|
64
|
+
const replace = await ask(' Replace it? (y/N): ');
|
|
65
|
+
if (replace.toLowerCase() === 'y') {
|
|
66
|
+
wmKey = await ask(' ? WarpMetrics API key (get one at warpmetrics.com/app/api-keys): ');
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
wmKey = await ask(' ? WarpMetrics API key (get one at warpmetrics.com/app/api-keys): ');
|
|
70
|
+
}
|
|
71
|
+
if (wmKey && !wmKey.startsWith('wm_')) {
|
|
36
72
|
log(' \u26a0 Warning: key doesn\'t start with wm_ \u2014 make sure this is a valid WarpMetrics API key');
|
|
37
73
|
}
|
|
38
74
|
|
|
39
75
|
log('');
|
|
40
76
|
|
|
41
77
|
// 3. Set GitHub secrets
|
|
42
|
-
let ghAvailable = false;
|
|
43
|
-
try {
|
|
44
|
-
execSync('gh --version', { stdio: 'ignore' });
|
|
45
|
-
ghAvailable = true;
|
|
46
|
-
} catch {
|
|
47
|
-
ghAvailable = false;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
78
|
if (ghAvailable) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
79
|
+
if (anthropicKey) {
|
|
80
|
+
try {
|
|
81
|
+
execSync('gh secret set ANTHROPIC_API_KEY', { input: anthropicKey, stdio: ['pipe', 'ignore', 'ignore'] });
|
|
82
|
+
log(' \u2713 ANTHROPIC_API_KEY set');
|
|
83
|
+
} catch (e) {
|
|
84
|
+
log(` \u2717 Failed to set ANTHROPIC_API_KEY: ${e.message}`);
|
|
85
|
+
}
|
|
57
86
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
87
|
+
if (wmKey) {
|
|
88
|
+
try {
|
|
89
|
+
execSync('gh secret set WARPMETRICS_API_KEY', { input: wmKey, stdio: ['pipe', 'ignore', 'ignore'] });
|
|
90
|
+
log(' \u2713 WARPMETRICS_API_KEY set');
|
|
91
|
+
} catch (e) {
|
|
92
|
+
log(` \u2717 Failed to set WARPMETRICS_API_KEY: ${e.message}`);
|
|
93
|
+
}
|
|
63
94
|
}
|
|
64
95
|
} else {
|
|
65
96
|
log(' gh (GitHub CLI) not found. Set these secrets manually:');
|
|
@@ -80,43 +111,47 @@ async function main() {
|
|
|
80
111
|
log('');
|
|
81
112
|
|
|
82
113
|
// 6. Register outcome classifications
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
114
|
+
if (wmKey) {
|
|
115
|
+
log(' Registering outcome classifications with WarpMetrics...');
|
|
116
|
+
const classifications = [
|
|
117
|
+
{ name: 'PR Created', classification: 'success' },
|
|
118
|
+
{ name: 'Fixes Applied', classification: 'success' },
|
|
119
|
+
{ name: 'Issue Understood', classification: 'success' },
|
|
120
|
+
{ name: 'Needs Clarification', classification: 'neutral' },
|
|
121
|
+
{ name: 'Needs Human', classification: 'neutral' },
|
|
122
|
+
{ name: 'Implementation Failed', classification: 'failure' },
|
|
123
|
+
{ name: 'Tests Failed', classification: 'failure' },
|
|
124
|
+
{ name: 'Revision Failed', classification: 'failure' },
|
|
125
|
+
{ name: 'Max Retries', classification: 'failure' },
|
|
126
|
+
];
|
|
127
|
+
|
|
128
|
+
let classOk = true;
|
|
129
|
+
for (const { name, classification } of classifications) {
|
|
130
|
+
try {
|
|
131
|
+
const res = await fetch(`https://api.warpmetrics.com/v1/outcomes/classifications/${encodeURIComponent(name)}`, {
|
|
132
|
+
method: 'PUT',
|
|
133
|
+
headers: {
|
|
134
|
+
Authorization: `Bearer ${wmKey}`,
|
|
135
|
+
'Content-Type': 'application/json',
|
|
136
|
+
},
|
|
137
|
+
body: JSON.stringify({ classification }),
|
|
138
|
+
});
|
|
139
|
+
if (!res.ok) {
|
|
140
|
+
classOk = false;
|
|
141
|
+
console.warn(` \u26a0 Failed to set classification ${name}: ${res.status}`);
|
|
142
|
+
}
|
|
143
|
+
} catch (e) {
|
|
108
144
|
classOk = false;
|
|
109
|
-
console.warn(` \u26a0 Failed to set classification ${name}: ${
|
|
145
|
+
console.warn(` \u26a0 Failed to set classification ${name}: ${e.message}`);
|
|
110
146
|
}
|
|
111
|
-
} catch (e) {
|
|
112
|
-
classOk = false;
|
|
113
|
-
console.warn(` \u26a0 Failed to set classification ${name}: ${e.message}`);
|
|
114
147
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
148
|
+
if (classOk) {
|
|
149
|
+
log(' \u2713 Outcomes configured');
|
|
150
|
+
} else {
|
|
151
|
+
log(' \u26a0 Some classifications failed \u2014 you can set them manually in the WarpMetrics dashboard');
|
|
152
|
+
}
|
|
118
153
|
} else {
|
|
119
|
-
log('
|
|
154
|
+
log(' Skipping outcome classifications (WarpMetrics key not provided)');
|
|
120
155
|
}
|
|
121
156
|
|
|
122
157
|
// 7. Check for warp-review
|