@warpmetrics/coder 0.2.1 → 0.2.3

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/cli.js CHANGED
@@ -49,23 +49,34 @@ if (command === 'watch') {
49
49
  // ---------------------------------------------------------------------------
50
50
 
51
51
  async function runInit() {
52
- const rl = createInterface({ input: process.stdin, output: process.stdout });
53
- const ask = q => new Promise(resolve => rl.question(q, resolve));
54
52
  const log = msg => console.log(msg);
55
53
 
54
+ log('');
55
+ log(' warp-coder — set up agent config');
56
+ log('');
57
+
58
+ // 1. Ensure gh has the right scopes (before readline takes over stdin)
59
+ log(' Ensuring GitHub CLI has required scopes (project, repo)...');
56
60
  try {
57
- log('');
58
- log(' warp-coder set up agent config');
59
- log('');
61
+ execSync('gh auth refresh -s project,repo', { stdio: 'inherit' });
62
+ log(' \u2713 GitHub CLI scopes updated');
63
+ } catch {
64
+ log(' \u26a0 Could not refresh gh scopes — run manually: gh auth refresh -s project,repo');
65
+ }
66
+ log('');
60
67
 
61
- // 1. WarpMetrics API key
68
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
69
+ const ask = q => new Promise(resolve => rl.question(q, resolve));
70
+
71
+ try {
72
+ // 2. WarpMetrics API key
62
73
  const wmKey = await ask(' ? WarpMetrics API key (get one at warpmetrics.com/app/api-keys): ');
63
74
  if (wmKey && !wmKey.startsWith('wm_')) {
64
75
  log(' \u26a0 Warning: key doesn\'t start with wm_ — make sure this is a valid WarpMetrics API key');
65
76
  }
66
77
  log('');
67
78
 
68
- // 2. Repo URL
79
+ // 3. Repo URL
69
80
  let repoDefault = '';
70
81
  try {
71
82
  repoDefault = execSync('git remote get-url origin', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
@@ -79,7 +90,7 @@ async function runInit() {
79
90
  }
80
91
  log('');
81
92
 
82
- // 3. Board provider
93
+ // 4. Board provider
83
94
  log(' Board: GitHub Projects v2');
84
95
  const projectNumber = await ask(' ? Project number: ');
85
96
  if (!projectNumber) {
@@ -96,7 +107,7 @@ async function runInit() {
96
107
  const owner = ownerInput || ownerDefault;
97
108
  log('');
98
109
 
99
- // 4. Discover field IDs and column names
110
+ // 5. Discover field IDs and column names
100
111
  let columns = { todo: 'Todo', inProgress: 'In Progress', inReview: 'In Review', done: 'Done', blocked: 'Blocked' };
101
112
  try {
102
113
  log(' Discovering project fields...');
@@ -119,7 +130,7 @@ async function runInit() {
119
130
  log('');
120
131
  }
121
132
 
122
- // 5. Build config
133
+ // 6. Build config
123
134
  const config = {
124
135
  board: {
125
136
  provider: 'github-projects',
@@ -141,13 +152,29 @@ async function runInit() {
141
152
  config.warpmetricsApiKey = wmKey;
142
153
  }
143
154
 
144
- // 6. Write config
155
+ // 7. Write config
145
156
  const configDir = '.warp-coder';
146
157
  mkdirSync(configDir, { recursive: true });
147
158
  writeFileSync(join(configDir, 'config.json'), JSON.stringify(config, null, 2) + '\n');
148
159
  log(` \u2713 ${configDir}/config.json created`);
149
160
 
150
- // 7. Register outcome classifications
161
+ // 8. Add to .gitignore
162
+ const gitignorePath = '.gitignore';
163
+ const entry = '.warp-coder/';
164
+ if (existsSync(gitignorePath)) {
165
+ const content = readFileSync(gitignorePath, 'utf-8');
166
+ if (!content.split('\n').some(line => line.trim() === entry)) {
167
+ writeFileSync(gitignorePath, content.trimEnd() + '\n' + entry + '\n');
168
+ log(` \u2713 Added ${entry} to .gitignore`);
169
+ } else {
170
+ log(` \u2713 ${entry} already in .gitignore`);
171
+ }
172
+ } else {
173
+ writeFileSync(gitignorePath, entry + '\n');
174
+ log(` \u2713 Created .gitignore with ${entry}`);
175
+ }
176
+
177
+ // 9. Register outcome classifications
151
178
  if (wmKey) {
152
179
  log(' Registering outcome classifications with WarpMetrics...');
153
180
  try {
@@ -159,13 +186,12 @@ async function runInit() {
159
186
  }
160
187
  }
161
188
 
162
- // 8. Next steps
189
+ // 10. Next steps
163
190
  log('');
164
191
  log(' Done! Next steps:');
165
- log(' 1. Add .warp-coder/config.json to .gitignore (contains API key)');
166
- log(' 2. Run: warp-coder watch');
167
- log(' 3. Add issues to the "Todo" column of your project board');
168
- log(' 4. View pipeline analytics at https://app.warpmetrics.com');
192
+ log(' 1. Run: warp-coder watch');
193
+ log(' 2. Add issues to the "Ready" column of your project board');
194
+ log(' 3. View pipeline analytics at https://app.warpmetrics.com');
169
195
  log('');
170
196
  } finally {
171
197
  rl.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warpmetrics/coder",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "Local agent loop for implementing GitHub issues with Claude Code. Powered by WarpMetrics.",
6
6
  "bin": {
package/src/claude.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { spawn } from 'child_process';
2
2
 
3
- export function run({ prompt, workdir, allowedTools = 'Bash,Read,Edit,Write,Glob,Grep', maxTurns }) {
3
+ export function run({ prompt, workdir, allowedTools = 'Bash,Read,Edit,Write,Glob,Grep', maxTurns, verbose = true }) {
4
4
  return new Promise((resolve, reject) => {
5
5
  const args = ['-p', prompt, '--output-format', 'json', '--allowedTools', allowedTools];
6
6
  if (maxTurns) args.push('--max-turns', String(maxTurns));
@@ -13,7 +13,10 @@ export function run({ prompt, workdir, allowedTools = 'Bash,Read,Edit,Write,Glob
13
13
  let stdout = '';
14
14
  let stderr = '';
15
15
  proc.stdout.on('data', d => { stdout += d; });
16
- proc.stderr.on('data', d => { stderr += d; });
16
+ proc.stderr.on('data', d => {
17
+ stderr += d;
18
+ if (verbose) process.stderr.write(d);
19
+ });
17
20
 
18
21
  proc.on('close', code => {
19
22
  if (code !== 0) {
package/src/reflect.js CHANGED
@@ -65,6 +65,7 @@ export async function reflect({ configDir, step, issue, prNumber, success, error
65
65
  workdir: process.cwd(),
66
66
  allowedTools: '',
67
67
  maxTurns: 1,
68
+ verbose: false,
68
69
  });
69
70
 
70
71
  const content = typeof result.result === 'string' ? result.result : JSON.stringify(result.result);