watchfix 0.2.0 → 0.2.1
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 +17 -1
- package/dist/cli/commands/fix.js +8 -0
- package/dist/fixer/index.d.ts +1 -0
- package/dist/fixer/index.js +2 -0
- package/dist/watcher/parser.js +23 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -64,12 +64,28 @@ watchfix watch
|
|
|
64
64
|
watchfix fix <error-id>
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
## Autonomous Mode
|
|
68
|
+
|
|
69
|
+
For fully automated error fixing without manual approval:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
watchfix watch --autonomous
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
In autonomous mode, watchfix automatically dispatches AI agents to fix detected errors. Combine with daemon mode for background operation (Linux/macOS):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
watchfix watch --daemon --autonomous
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Note:** Manual `watchfix fix` commands are blocked while running in autonomous mode.
|
|
82
|
+
|
|
67
83
|
## CLI Commands
|
|
68
84
|
|
|
69
85
|
| Command | Description |
|
|
70
86
|
|---------|-------------|
|
|
71
87
|
| `watchfix init` | Create `watchfix.yaml` in current directory |
|
|
72
|
-
| `watchfix watch` | Watch logs in foreground (use `--daemon` for background) |
|
|
88
|
+
| `watchfix watch` | Watch logs in foreground (use `--daemon` for background, `--autonomous` for auto-fix) |
|
|
73
89
|
| `watchfix fix [id]` | Analyze and fix a specific error (or `--all` for all pending) |
|
|
74
90
|
| `watchfix show <id>` | Show full error details and analysis |
|
|
75
91
|
| `watchfix status` | Show watcher state and pending errors |
|
package/dist/cli/commands/fix.js
CHANGED
|
@@ -175,6 +175,14 @@ const formatFixOutcome = (result, verbosity, maxAttempts) => {
|
|
|
175
175
|
}
|
|
176
176
|
else if (!result.fix?.success) {
|
|
177
177
|
lines.push(`Error #${result.errorId}: Agent could not apply fix`);
|
|
178
|
+
if (result.diagnostic) {
|
|
179
|
+
// Extract key info from diagnostic
|
|
180
|
+
const diagLines = result.diagnostic.split('\n');
|
|
181
|
+
const reason = diagLines.find(l => l.includes('timed out') || l.includes('Exit code'));
|
|
182
|
+
if (reason) {
|
|
183
|
+
lines.push(` Reason: ${reason.trim()}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
178
186
|
}
|
|
179
187
|
else {
|
|
180
188
|
lines.push(`Error #${result.errorId}: Fix attempt completed`);
|
package/dist/fixer/index.d.ts
CHANGED
package/dist/fixer/index.js
CHANGED
|
@@ -246,6 +246,7 @@ export class FixOrchestrator {
|
|
|
246
246
|
lockAcquired: true,
|
|
247
247
|
attempts,
|
|
248
248
|
message: 'Analysis failed',
|
|
249
|
+
diagnostic: analysisResult.diagnostic,
|
|
249
250
|
};
|
|
250
251
|
}
|
|
251
252
|
}
|
|
@@ -348,6 +349,7 @@ export class FixOrchestrator {
|
|
|
348
349
|
attempts,
|
|
349
350
|
analysis: analysisOutput,
|
|
350
351
|
message: 'Fix failed',
|
|
352
|
+
diagnostic: fixResult.diagnostic,
|
|
351
353
|
};
|
|
352
354
|
}
|
|
353
355
|
logActivity(this.db, 'verification_start', errorId, JSON.stringify({ attempt: attempts }));
|
package/dist/watcher/parser.js
CHANGED
|
@@ -11,6 +11,14 @@ const CONTINUATION_PATTERNS = [
|
|
|
11
11
|
/^\s+\.\.\./,
|
|
12
12
|
];
|
|
13
13
|
const isContinuationLine = (line) => CONTINUATION_PATTERNS.some((pattern) => pattern.test(line));
|
|
14
|
+
const extractCoreMessage = (line) => {
|
|
15
|
+
// "TypeError: Cannot read..." → "Cannot read..."
|
|
16
|
+
const colonIndex = line.indexOf(': ');
|
|
17
|
+
if (colonIndex > 0 && colonIndex < 30) {
|
|
18
|
+
return line.slice(colonIndex + 2).trim();
|
|
19
|
+
}
|
|
20
|
+
return line.trim();
|
|
21
|
+
};
|
|
14
22
|
const truncateLine = (line) => {
|
|
15
23
|
if (line.length <= MAX_LINE_LENGTH) {
|
|
16
24
|
return line;
|
|
@@ -58,6 +66,21 @@ export class ErrorParser {
|
|
|
58
66
|
return;
|
|
59
67
|
}
|
|
60
68
|
if (isError) {
|
|
69
|
+
// Check if this is the same error with a more specific type
|
|
70
|
+
if (this.current && this.current.stackLines.length === 0) {
|
|
71
|
+
const currentCore = extractCoreMessage(this.current.message);
|
|
72
|
+
const newCore = extractCoreMessage(line);
|
|
73
|
+
if (currentCore === newCore) {
|
|
74
|
+
// Same error - discard shallow entry, use the more detailed one
|
|
75
|
+
if (this.flushTimer) {
|
|
76
|
+
clearTimeout(this.flushTimer);
|
|
77
|
+
this.flushTimer = undefined;
|
|
78
|
+
}
|
|
79
|
+
this.current = undefined;
|
|
80
|
+
this.startError(event, line);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
61
84
|
await this.flushCurrent('new_error');
|
|
62
85
|
this.startError(event, line);
|
|
63
86
|
return;
|