watchfix 0.2.2 → 0.4.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/dist/cli/commands/fix.js +2 -2
- package/dist/cli/commands/init.js +13 -0
- package/dist/cli/commands/show.js +7 -0
- package/dist/cli/commands/status.js +15 -1
- package/dist/cli/commands/stop.js +1 -1
- package/dist/cli/commands/watch.js +1 -1
- package/dist/config/schema.d.ts +232 -36
- package/dist/config/schema.js +19 -2
- package/dist/db/queries.d.ts +1 -1
- package/dist/fixer/context.d.ts +24 -1
- package/dist/fixer/context.js +117 -18
- package/dist/fixer/index.d.ts +23 -0
- package/dist/fixer/index.js +97 -7
- package/dist/fixer/output.d.ts +15 -1
- package/dist/fixer/output.js +43 -0
- package/dist/utils/errors.d.ts +1 -1
- package/dist/utils/process.d.ts +1 -1
- package/dist/utils/process.js +3 -2
- package/dist/watcher/index.js +31 -5
- package/dist/watcher/sources/file.d.ts +3 -0
- package/dist/watcher/sources/file.js +34 -1
- package/dist/watcher/sources/ndjson.d.ts +16 -0
- package/dist/watcher/sources/ndjson.js +108 -0
- package/dist/watcher/sources/types.d.ts +8 -0
- package/package.json +1 -1
package/dist/cli/commands/fix.js
CHANGED
|
@@ -152,7 +152,7 @@ const formatStatusLine = (result, maxAttempts) => {
|
|
|
152
152
|
return 'Status: resolved (issue already fixed)';
|
|
153
153
|
}
|
|
154
154
|
const retryInfo = result.attempts < maxAttempts ? ', will retry' : ', max attempts reached';
|
|
155
|
-
return `Status: ${result.status} (attempt ${result.attempts} of ${maxAttempts}${retryInfo})`;
|
|
155
|
+
return `Status: ${result.status} (attempt ${result.attempts + 1} of ${maxAttempts}${retryInfo})`;
|
|
156
156
|
};
|
|
157
157
|
const formatFixOutcome = (result, verbosity, maxAttempts) => {
|
|
158
158
|
if (verbosity === 'quiet') {
|
|
@@ -211,7 +211,7 @@ const checkDaemonConflict = (db, logger) => {
|
|
|
211
211
|
if (!state) {
|
|
212
212
|
return true;
|
|
213
213
|
}
|
|
214
|
-
if (!isOurProcess(state.pid
|
|
214
|
+
if (!isOurProcess(state.pid)) {
|
|
215
215
|
clearWatcherState(db);
|
|
216
216
|
return true;
|
|
217
217
|
}
|
|
@@ -27,6 +27,19 @@ logs:
|
|
|
27
27
|
type: file
|
|
28
28
|
path: ./logs/app.log
|
|
29
29
|
|
|
30
|
+
# Example NDJSON source (for structured JSON logs like Pino, Bunyan, Winston):
|
|
31
|
+
# - name: app-json
|
|
32
|
+
# type: file
|
|
33
|
+
# path: ./logs/app.ndjson
|
|
34
|
+
# format: ndjson
|
|
35
|
+
# ndjson:
|
|
36
|
+
# messageField: msg # Required: field containing log message
|
|
37
|
+
# timestampField: time # Optional: field with timestamp
|
|
38
|
+
# levelField: level # Optional: field with log level
|
|
39
|
+
# levelFilter: # Optional: only process these levels
|
|
40
|
+
# - error
|
|
41
|
+
# - fatal
|
|
42
|
+
|
|
30
43
|
# Example docker source:
|
|
31
44
|
# - name: api
|
|
32
45
|
# type: docker
|
|
@@ -56,6 +56,9 @@ const formatAnalysis = (analysis) => {
|
|
|
56
56
|
return ['Analysis (raw):', ` ${analysis}`];
|
|
57
57
|
}
|
|
58
58
|
const lines = ['Analysis:'];
|
|
59
|
+
if (analysis.category) {
|
|
60
|
+
lines.push(` Category: ${analysis.category}`);
|
|
61
|
+
}
|
|
59
62
|
if (analysis.summary) {
|
|
60
63
|
lines.push(` Summary: ${analysis.summary}`);
|
|
61
64
|
}
|
|
@@ -73,6 +76,10 @@ const formatAnalysis = (analysis) => {
|
|
|
73
76
|
lines.push(` - ${file}`);
|
|
74
77
|
}
|
|
75
78
|
}
|
|
79
|
+
if (analysis.remediation_guidance) {
|
|
80
|
+
lines.push(' Remediation guidance:');
|
|
81
|
+
lines.push(...analysis.remediation_guidance.split('\n').map((line) => ` ${line}`));
|
|
82
|
+
}
|
|
76
83
|
if (analysis.confidence) {
|
|
77
84
|
lines.push(` Confidence: ${analysis.confidence}`);
|
|
78
85
|
}
|
|
@@ -13,6 +13,7 @@ const STATUS_ORDER = [
|
|
|
13
13
|
'fixed',
|
|
14
14
|
'failed',
|
|
15
15
|
'ignored',
|
|
16
|
+
'deferred',
|
|
16
17
|
];
|
|
17
18
|
const buildDatabasePath = (rootDir) => path.join(rootDir, '.watchfix', 'errors.db');
|
|
18
19
|
const getWatcherState = (db) => db.get('SELECT pid, started_at, autonomous, project_root, command_line FROM watcher_state WHERE id = 1');
|
|
@@ -62,6 +63,16 @@ const formatActionableErrors = (errors) => {
|
|
|
62
63
|
}
|
|
63
64
|
return lines;
|
|
64
65
|
};
|
|
66
|
+
const formatDeferredErrors = (errors) => {
|
|
67
|
+
if (errors.length === 0) {
|
|
68
|
+
return ['Deferred errors: none'];
|
|
69
|
+
}
|
|
70
|
+
const lines = ['Deferred errors (manual action required):'];
|
|
71
|
+
for (const error of errors) {
|
|
72
|
+
lines.push(` #${error.id} ${error.errorType} (${error.source}): ${error.message}`);
|
|
73
|
+
}
|
|
74
|
+
return lines;
|
|
75
|
+
};
|
|
65
76
|
export const statusCommand = async (options) => {
|
|
66
77
|
const config = loadConfig(options.config);
|
|
67
78
|
const dbPath = buildDatabasePath(config.project.root);
|
|
@@ -71,6 +82,7 @@ export const statusCommand = async (options) => {
|
|
|
71
82
|
'Errors:',
|
|
72
83
|
...STATUS_ORDER.map((status) => ` ${status}: 0`),
|
|
73
84
|
'Actionable errors: none',
|
|
85
|
+
'Deferred errors: none',
|
|
74
86
|
];
|
|
75
87
|
process.stdout.write(`${lines.join('\n')}\n`);
|
|
76
88
|
return;
|
|
@@ -81,7 +93,7 @@ export const statusCommand = async (options) => {
|
|
|
81
93
|
checkSchemaVersion(db);
|
|
82
94
|
const lines = [];
|
|
83
95
|
const state = getWatcherState(db);
|
|
84
|
-
if (state && isOurProcess(state.pid
|
|
96
|
+
if (state && isOurProcess(state.pid)) {
|
|
85
97
|
const mode = state.autonomous ? 'autonomous' : 'manual';
|
|
86
98
|
const uptime = formatUptime(state.started_at);
|
|
87
99
|
lines.push(`Watcher: running (pid ${state.pid}, ${mode} mode, uptime ${uptime}).`);
|
|
@@ -102,6 +114,8 @@ export const statusCommand = async (options) => {
|
|
|
102
114
|
}
|
|
103
115
|
const actionable = getErrorsByStatus(db, ['pending', 'suggested']);
|
|
104
116
|
lines.push(...formatActionableErrors(actionable));
|
|
117
|
+
const deferred = getErrorsByStatus(db, ['deferred']);
|
|
118
|
+
lines.push(...formatDeferredErrors(deferred));
|
|
105
119
|
process.stdout.write(`${lines.join('\n')}\n`);
|
|
106
120
|
}
|
|
107
121
|
finally {
|
|
@@ -58,7 +58,7 @@ export const stopCommand = async (options) => {
|
|
|
58
58
|
process.exitCode = EXIT_CODES.WATCHER_CONFLICT;
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
|
-
if (!isOurProcess(state.pid
|
|
61
|
+
if (!isOurProcess(state.pid)) {
|
|
62
62
|
process.stdout.write('Stale watcher state (process no longer exists).\n');
|
|
63
63
|
clearWatcherState(db);
|
|
64
64
|
process.exitCode = EXIT_CODES.WATCHER_CONFLICT;
|
|
@@ -31,7 +31,7 @@ const ensureWatcherAvailable = (db, projectRoot, logger) => {
|
|
|
31
31
|
if (!existing) {
|
|
32
32
|
return true;
|
|
33
33
|
}
|
|
34
|
-
if (isOurProcess(existing.pid
|
|
34
|
+
if (isOurProcess(existing.pid)) {
|
|
35
35
|
const mode = existing.autonomous ? 'autonomous' : 'manual';
|
|
36
36
|
const message = `Watcher already running (pid ${existing.pid}, ${mode} mode). Use 'watchfix stop'.`;
|
|
37
37
|
if (logger) {
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -1,29 +1,76 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
declare const durationSchema: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
3
|
+
declare const ndjsonConfigSchema: z.ZodObject<{
|
|
4
|
+
messageField: z.ZodString;
|
|
5
|
+
timestampField: z.ZodOptional<z.ZodString>;
|
|
6
|
+
levelField: z.ZodOptional<z.ZodString>;
|
|
7
|
+
levelFilter: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
messageField: string;
|
|
10
|
+
timestampField?: string | undefined;
|
|
11
|
+
levelField?: string | undefined;
|
|
12
|
+
levelFilter?: string[] | undefined;
|
|
13
|
+
}, {
|
|
14
|
+
messageField: string;
|
|
15
|
+
timestampField?: string | undefined;
|
|
16
|
+
levelField?: string | undefined;
|
|
17
|
+
levelFilter?: string[] | undefined;
|
|
18
|
+
}>;
|
|
3
19
|
declare const fileSourceSchema: z.ZodObject<{
|
|
4
20
|
name: z.ZodString;
|
|
5
21
|
type: z.ZodLiteral<"file">;
|
|
6
22
|
path: z.ZodString;
|
|
23
|
+
format: z.ZodOptional<z.ZodEnum<["text", "ndjson"]>>;
|
|
24
|
+
ndjson: z.ZodOptional<z.ZodObject<{
|
|
25
|
+
messageField: z.ZodString;
|
|
26
|
+
timestampField: z.ZodOptional<z.ZodString>;
|
|
27
|
+
levelField: z.ZodOptional<z.ZodString>;
|
|
28
|
+
levelFilter: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
29
|
+
}, "strip", z.ZodTypeAny, {
|
|
30
|
+
messageField: string;
|
|
31
|
+
timestampField?: string | undefined;
|
|
32
|
+
levelField?: string | undefined;
|
|
33
|
+
levelFilter?: string[] | undefined;
|
|
34
|
+
}, {
|
|
35
|
+
messageField: string;
|
|
36
|
+
timestampField?: string | undefined;
|
|
37
|
+
levelField?: string | undefined;
|
|
38
|
+
levelFilter?: string[] | undefined;
|
|
39
|
+
}>>;
|
|
7
40
|
}, "strip", z.ZodTypeAny, {
|
|
8
41
|
path: string;
|
|
9
|
-
name: string;
|
|
10
42
|
type: "file";
|
|
43
|
+
name: string;
|
|
44
|
+
ndjson?: {
|
|
45
|
+
messageField: string;
|
|
46
|
+
timestampField?: string | undefined;
|
|
47
|
+
levelField?: string | undefined;
|
|
48
|
+
levelFilter?: string[] | undefined;
|
|
49
|
+
} | undefined;
|
|
50
|
+
format?: "text" | "ndjson" | undefined;
|
|
11
51
|
}, {
|
|
12
52
|
path: string;
|
|
13
|
-
name: string;
|
|
14
53
|
type: "file";
|
|
54
|
+
name: string;
|
|
55
|
+
ndjson?: {
|
|
56
|
+
messageField: string;
|
|
57
|
+
timestampField?: string | undefined;
|
|
58
|
+
levelField?: string | undefined;
|
|
59
|
+
levelFilter?: string[] | undefined;
|
|
60
|
+
} | undefined;
|
|
61
|
+
format?: "text" | "ndjson" | undefined;
|
|
15
62
|
}>;
|
|
16
63
|
declare const dockerSourceSchema: z.ZodObject<{
|
|
17
64
|
name: z.ZodString;
|
|
18
65
|
type: z.ZodLiteral<"docker">;
|
|
19
66
|
container: z.ZodString;
|
|
20
67
|
}, "strip", z.ZodTypeAny, {
|
|
21
|
-
name: string;
|
|
22
68
|
type: "docker";
|
|
69
|
+
name: string;
|
|
23
70
|
container: string;
|
|
24
71
|
}, {
|
|
25
|
-
name: string;
|
|
26
72
|
type: "docker";
|
|
73
|
+
name: string;
|
|
27
74
|
container: string;
|
|
28
75
|
}>;
|
|
29
76
|
declare const commandSourceSchema: z.ZodObject<{
|
|
@@ -32,13 +79,13 @@ declare const commandSourceSchema: z.ZodObject<{
|
|
|
32
79
|
run: z.ZodString;
|
|
33
80
|
interval: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
34
81
|
}, "strip", z.ZodTypeAny, {
|
|
35
|
-
name: string;
|
|
36
82
|
type: "command";
|
|
83
|
+
name: string;
|
|
37
84
|
run: string;
|
|
38
85
|
interval: string;
|
|
39
86
|
}, {
|
|
40
|
-
name: string;
|
|
41
87
|
type: "command";
|
|
88
|
+
name: string;
|
|
42
89
|
run: string;
|
|
43
90
|
interval: string;
|
|
44
91
|
}>;
|
|
@@ -46,25 +93,56 @@ declare const logSourceSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
46
93
|
name: z.ZodString;
|
|
47
94
|
type: z.ZodLiteral<"file">;
|
|
48
95
|
path: z.ZodString;
|
|
96
|
+
format: z.ZodOptional<z.ZodEnum<["text", "ndjson"]>>;
|
|
97
|
+
ndjson: z.ZodOptional<z.ZodObject<{
|
|
98
|
+
messageField: z.ZodString;
|
|
99
|
+
timestampField: z.ZodOptional<z.ZodString>;
|
|
100
|
+
levelField: z.ZodOptional<z.ZodString>;
|
|
101
|
+
levelFilter: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
102
|
+
}, "strip", z.ZodTypeAny, {
|
|
103
|
+
messageField: string;
|
|
104
|
+
timestampField?: string | undefined;
|
|
105
|
+
levelField?: string | undefined;
|
|
106
|
+
levelFilter?: string[] | undefined;
|
|
107
|
+
}, {
|
|
108
|
+
messageField: string;
|
|
109
|
+
timestampField?: string | undefined;
|
|
110
|
+
levelField?: string | undefined;
|
|
111
|
+
levelFilter?: string[] | undefined;
|
|
112
|
+
}>>;
|
|
49
113
|
}, "strip", z.ZodTypeAny, {
|
|
50
114
|
path: string;
|
|
51
|
-
name: string;
|
|
52
115
|
type: "file";
|
|
116
|
+
name: string;
|
|
117
|
+
ndjson?: {
|
|
118
|
+
messageField: string;
|
|
119
|
+
timestampField?: string | undefined;
|
|
120
|
+
levelField?: string | undefined;
|
|
121
|
+
levelFilter?: string[] | undefined;
|
|
122
|
+
} | undefined;
|
|
123
|
+
format?: "text" | "ndjson" | undefined;
|
|
53
124
|
}, {
|
|
54
125
|
path: string;
|
|
55
|
-
name: string;
|
|
56
126
|
type: "file";
|
|
127
|
+
name: string;
|
|
128
|
+
ndjson?: {
|
|
129
|
+
messageField: string;
|
|
130
|
+
timestampField?: string | undefined;
|
|
131
|
+
levelField?: string | undefined;
|
|
132
|
+
levelFilter?: string[] | undefined;
|
|
133
|
+
} | undefined;
|
|
134
|
+
format?: "text" | "ndjson" | undefined;
|
|
57
135
|
}>, z.ZodObject<{
|
|
58
136
|
name: z.ZodString;
|
|
59
137
|
type: z.ZodLiteral<"docker">;
|
|
60
138
|
container: z.ZodString;
|
|
61
139
|
}, "strip", z.ZodTypeAny, {
|
|
62
|
-
name: string;
|
|
63
140
|
type: "docker";
|
|
141
|
+
name: string;
|
|
64
142
|
container: string;
|
|
65
143
|
}, {
|
|
66
|
-
name: string;
|
|
67
144
|
type: "docker";
|
|
145
|
+
name: string;
|
|
68
146
|
container: string;
|
|
69
147
|
}>, z.ZodObject<{
|
|
70
148
|
name: z.ZodString;
|
|
@@ -72,13 +150,13 @@ declare const logSourceSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
72
150
|
run: z.ZodString;
|
|
73
151
|
interval: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
74
152
|
}, "strip", z.ZodTypeAny, {
|
|
75
|
-
name: string;
|
|
76
153
|
type: "command";
|
|
154
|
+
name: string;
|
|
77
155
|
run: string;
|
|
78
156
|
interval: string;
|
|
79
157
|
}, {
|
|
80
|
-
name: string;
|
|
81
158
|
type: "command";
|
|
159
|
+
name: string;
|
|
82
160
|
run: string;
|
|
83
161
|
interval: string;
|
|
84
162
|
}>]>;
|
|
@@ -117,29 +195,60 @@ declare const configSchema: z.ZodObject<{
|
|
|
117
195
|
stderr_is_progress?: boolean | undefined;
|
|
118
196
|
}>;
|
|
119
197
|
logs: z.ZodObject<{
|
|
120
|
-
sources: z.ZodEffects<z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
198
|
+
sources: z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
121
199
|
name: z.ZodString;
|
|
122
200
|
type: z.ZodLiteral<"file">;
|
|
123
201
|
path: z.ZodString;
|
|
202
|
+
format: z.ZodOptional<z.ZodEnum<["text", "ndjson"]>>;
|
|
203
|
+
ndjson: z.ZodOptional<z.ZodObject<{
|
|
204
|
+
messageField: z.ZodString;
|
|
205
|
+
timestampField: z.ZodOptional<z.ZodString>;
|
|
206
|
+
levelField: z.ZodOptional<z.ZodString>;
|
|
207
|
+
levelFilter: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
208
|
+
}, "strip", z.ZodTypeAny, {
|
|
209
|
+
messageField: string;
|
|
210
|
+
timestampField?: string | undefined;
|
|
211
|
+
levelField?: string | undefined;
|
|
212
|
+
levelFilter?: string[] | undefined;
|
|
213
|
+
}, {
|
|
214
|
+
messageField: string;
|
|
215
|
+
timestampField?: string | undefined;
|
|
216
|
+
levelField?: string | undefined;
|
|
217
|
+
levelFilter?: string[] | undefined;
|
|
218
|
+
}>>;
|
|
124
219
|
}, "strip", z.ZodTypeAny, {
|
|
125
220
|
path: string;
|
|
126
|
-
name: string;
|
|
127
221
|
type: "file";
|
|
222
|
+
name: string;
|
|
223
|
+
ndjson?: {
|
|
224
|
+
messageField: string;
|
|
225
|
+
timestampField?: string | undefined;
|
|
226
|
+
levelField?: string | undefined;
|
|
227
|
+
levelFilter?: string[] | undefined;
|
|
228
|
+
} | undefined;
|
|
229
|
+
format?: "text" | "ndjson" | undefined;
|
|
128
230
|
}, {
|
|
129
231
|
path: string;
|
|
130
|
-
name: string;
|
|
131
232
|
type: "file";
|
|
233
|
+
name: string;
|
|
234
|
+
ndjson?: {
|
|
235
|
+
messageField: string;
|
|
236
|
+
timestampField?: string | undefined;
|
|
237
|
+
levelField?: string | undefined;
|
|
238
|
+
levelFilter?: string[] | undefined;
|
|
239
|
+
} | undefined;
|
|
240
|
+
format?: "text" | "ndjson" | undefined;
|
|
132
241
|
}>, z.ZodObject<{
|
|
133
242
|
name: z.ZodString;
|
|
134
243
|
type: z.ZodLiteral<"docker">;
|
|
135
244
|
container: z.ZodString;
|
|
136
245
|
}, "strip", z.ZodTypeAny, {
|
|
137
|
-
name: string;
|
|
138
246
|
type: "docker";
|
|
247
|
+
name: string;
|
|
139
248
|
container: string;
|
|
140
249
|
}, {
|
|
141
|
-
name: string;
|
|
142
250
|
type: "docker";
|
|
251
|
+
name: string;
|
|
143
252
|
container: string;
|
|
144
253
|
}>, z.ZodObject<{
|
|
145
254
|
name: z.ZodString;
|
|
@@ -147,39 +256,93 @@ declare const configSchema: z.ZodObject<{
|
|
|
147
256
|
run: z.ZodString;
|
|
148
257
|
interval: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
149
258
|
}, "strip", z.ZodTypeAny, {
|
|
150
|
-
name: string;
|
|
151
259
|
type: "command";
|
|
260
|
+
name: string;
|
|
152
261
|
run: string;
|
|
153
262
|
interval: string;
|
|
154
263
|
}, {
|
|
155
|
-
name: string;
|
|
156
264
|
type: "command";
|
|
265
|
+
name: string;
|
|
157
266
|
run: string;
|
|
158
267
|
interval: string;
|
|
159
268
|
}>]>, "many">, ({
|
|
160
269
|
path: string;
|
|
161
|
-
name: string;
|
|
162
270
|
type: "file";
|
|
163
|
-
} | {
|
|
164
271
|
name: string;
|
|
272
|
+
ndjson?: {
|
|
273
|
+
messageField: string;
|
|
274
|
+
timestampField?: string | undefined;
|
|
275
|
+
levelField?: string | undefined;
|
|
276
|
+
levelFilter?: string[] | undefined;
|
|
277
|
+
} | undefined;
|
|
278
|
+
format?: "text" | "ndjson" | undefined;
|
|
279
|
+
} | {
|
|
165
280
|
type: "docker";
|
|
281
|
+
name: string;
|
|
166
282
|
container: string;
|
|
167
283
|
} | {
|
|
168
|
-
name: string;
|
|
169
284
|
type: "command";
|
|
285
|
+
name: string;
|
|
170
286
|
run: string;
|
|
171
287
|
interval: string;
|
|
172
288
|
})[], ({
|
|
173
289
|
path: string;
|
|
174
|
-
name: string;
|
|
175
290
|
type: "file";
|
|
291
|
+
name: string;
|
|
292
|
+
ndjson?: {
|
|
293
|
+
messageField: string;
|
|
294
|
+
timestampField?: string | undefined;
|
|
295
|
+
levelField?: string | undefined;
|
|
296
|
+
levelFilter?: string[] | undefined;
|
|
297
|
+
} | undefined;
|
|
298
|
+
format?: "text" | "ndjson" | undefined;
|
|
299
|
+
} | {
|
|
300
|
+
type: "docker";
|
|
301
|
+
name: string;
|
|
302
|
+
container: string;
|
|
176
303
|
} | {
|
|
304
|
+
type: "command";
|
|
305
|
+
name: string;
|
|
306
|
+
run: string;
|
|
307
|
+
interval: string;
|
|
308
|
+
})[]>, ({
|
|
309
|
+
path: string;
|
|
310
|
+
type: "file";
|
|
177
311
|
name: string;
|
|
312
|
+
ndjson?: {
|
|
313
|
+
messageField: string;
|
|
314
|
+
timestampField?: string | undefined;
|
|
315
|
+
levelField?: string | undefined;
|
|
316
|
+
levelFilter?: string[] | undefined;
|
|
317
|
+
} | undefined;
|
|
318
|
+
format?: "text" | "ndjson" | undefined;
|
|
319
|
+
} | {
|
|
178
320
|
type: "docker";
|
|
321
|
+
name: string;
|
|
179
322
|
container: string;
|
|
180
323
|
} | {
|
|
324
|
+
type: "command";
|
|
181
325
|
name: string;
|
|
326
|
+
run: string;
|
|
327
|
+
interval: string;
|
|
328
|
+
})[], ({
|
|
329
|
+
path: string;
|
|
330
|
+
type: "file";
|
|
331
|
+
name: string;
|
|
332
|
+
ndjson?: {
|
|
333
|
+
messageField: string;
|
|
334
|
+
timestampField?: string | undefined;
|
|
335
|
+
levelField?: string | undefined;
|
|
336
|
+
levelFilter?: string[] | undefined;
|
|
337
|
+
} | undefined;
|
|
338
|
+
format?: "text" | "ndjson" | undefined;
|
|
339
|
+
} | {
|
|
340
|
+
type: "docker";
|
|
341
|
+
name: string;
|
|
342
|
+
container: string;
|
|
343
|
+
} | {
|
|
182
344
|
type: "command";
|
|
345
|
+
name: string;
|
|
183
346
|
run: string;
|
|
184
347
|
interval: string;
|
|
185
348
|
})[]>;
|
|
@@ -189,15 +352,22 @@ declare const configSchema: z.ZodObject<{
|
|
|
189
352
|
}, "strip", z.ZodTypeAny, {
|
|
190
353
|
sources: ({
|
|
191
354
|
path: string;
|
|
192
|
-
name: string;
|
|
193
355
|
type: "file";
|
|
194
|
-
} | {
|
|
195
356
|
name: string;
|
|
357
|
+
ndjson?: {
|
|
358
|
+
messageField: string;
|
|
359
|
+
timestampField?: string | undefined;
|
|
360
|
+
levelField?: string | undefined;
|
|
361
|
+
levelFilter?: string[] | undefined;
|
|
362
|
+
} | undefined;
|
|
363
|
+
format?: "text" | "ndjson" | undefined;
|
|
364
|
+
} | {
|
|
196
365
|
type: "docker";
|
|
366
|
+
name: string;
|
|
197
367
|
container: string;
|
|
198
368
|
} | {
|
|
199
|
-
name: string;
|
|
200
369
|
type: "command";
|
|
370
|
+
name: string;
|
|
201
371
|
run: string;
|
|
202
372
|
interval: string;
|
|
203
373
|
})[];
|
|
@@ -207,15 +377,22 @@ declare const configSchema: z.ZodObject<{
|
|
|
207
377
|
}, {
|
|
208
378
|
sources: ({
|
|
209
379
|
path: string;
|
|
210
|
-
name: string;
|
|
211
380
|
type: "file";
|
|
212
|
-
} | {
|
|
213
381
|
name: string;
|
|
382
|
+
ndjson?: {
|
|
383
|
+
messageField: string;
|
|
384
|
+
timestampField?: string | undefined;
|
|
385
|
+
levelField?: string | undefined;
|
|
386
|
+
levelFilter?: string[] | undefined;
|
|
387
|
+
} | undefined;
|
|
388
|
+
format?: "text" | "ndjson" | undefined;
|
|
389
|
+
} | {
|
|
214
390
|
type: "docker";
|
|
391
|
+
name: string;
|
|
215
392
|
container: string;
|
|
216
393
|
} | {
|
|
217
|
-
name: string;
|
|
218
394
|
type: "command";
|
|
395
|
+
name: string;
|
|
219
396
|
run: string;
|
|
220
397
|
interval: string;
|
|
221
398
|
})[];
|
|
@@ -261,10 +438,13 @@ declare const configSchema: z.ZodObject<{
|
|
|
261
438
|
}>>;
|
|
262
439
|
deduplication: z.ZodDefault<z.ZodObject<{
|
|
263
440
|
fixed_grace_period: z.ZodDefault<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
441
|
+
deferred_grace_period: z.ZodDefault<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
264
442
|
}, "strip", z.ZodTypeAny, {
|
|
265
443
|
fixed_grace_period: string;
|
|
444
|
+
deferred_grace_period: string;
|
|
266
445
|
}, {
|
|
267
446
|
fixed_grace_period?: string | undefined;
|
|
447
|
+
deferred_grace_period?: string | undefined;
|
|
268
448
|
}>>;
|
|
269
449
|
patterns: z.ZodDefault<z.ZodObject<{
|
|
270
450
|
match: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
@@ -292,15 +472,22 @@ declare const configSchema: z.ZodObject<{
|
|
|
292
472
|
logs: {
|
|
293
473
|
sources: ({
|
|
294
474
|
path: string;
|
|
295
|
-
name: string;
|
|
296
475
|
type: "file";
|
|
297
|
-
} | {
|
|
298
476
|
name: string;
|
|
477
|
+
ndjson?: {
|
|
478
|
+
messageField: string;
|
|
479
|
+
timestampField?: string | undefined;
|
|
480
|
+
levelField?: string | undefined;
|
|
481
|
+
levelFilter?: string[] | undefined;
|
|
482
|
+
} | undefined;
|
|
483
|
+
format?: "text" | "ndjson" | undefined;
|
|
484
|
+
} | {
|
|
299
485
|
type: "docker";
|
|
486
|
+
name: string;
|
|
300
487
|
container: string;
|
|
301
488
|
} | {
|
|
302
|
-
name: string;
|
|
303
489
|
type: "command";
|
|
490
|
+
name: string;
|
|
304
491
|
run: string;
|
|
305
492
|
interval: string;
|
|
306
493
|
})[];
|
|
@@ -324,6 +511,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
324
511
|
};
|
|
325
512
|
deduplication: {
|
|
326
513
|
fixed_grace_period: string;
|
|
514
|
+
deferred_grace_period: string;
|
|
327
515
|
};
|
|
328
516
|
patterns: {
|
|
329
517
|
ignore: string[];
|
|
@@ -345,15 +533,22 @@ declare const configSchema: z.ZodObject<{
|
|
|
345
533
|
logs: {
|
|
346
534
|
sources: ({
|
|
347
535
|
path: string;
|
|
348
|
-
name: string;
|
|
349
536
|
type: "file";
|
|
350
|
-
} | {
|
|
351
537
|
name: string;
|
|
538
|
+
ndjson?: {
|
|
539
|
+
messageField: string;
|
|
540
|
+
timestampField?: string | undefined;
|
|
541
|
+
levelField?: string | undefined;
|
|
542
|
+
levelFilter?: string[] | undefined;
|
|
543
|
+
} | undefined;
|
|
544
|
+
format?: "text" | "ndjson" | undefined;
|
|
545
|
+
} | {
|
|
352
546
|
type: "docker";
|
|
547
|
+
name: string;
|
|
353
548
|
container: string;
|
|
354
549
|
} | {
|
|
355
|
-
name: string;
|
|
356
550
|
type: "command";
|
|
551
|
+
name: string;
|
|
357
552
|
run: string;
|
|
358
553
|
interval: string;
|
|
359
554
|
})[];
|
|
@@ -377,6 +572,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
377
572
|
} | undefined;
|
|
378
573
|
deduplication?: {
|
|
379
574
|
fixed_grace_period?: string | undefined;
|
|
575
|
+
deferred_grace_period?: string | undefined;
|
|
380
576
|
} | undefined;
|
|
381
577
|
patterns?: {
|
|
382
578
|
ignore?: string[] | undefined;
|
|
@@ -384,5 +580,5 @@ declare const configSchema: z.ZodObject<{
|
|
|
384
580
|
} | undefined;
|
|
385
581
|
}>;
|
|
386
582
|
type Config = z.infer<typeof configSchema>;
|
|
387
|
-
export { commandSourceSchema, configSchema, dockerSourceSchema, durationSchema, fileSourceSchema, logSourceSchema, patternSchema, };
|
|
583
|
+
export { commandSourceSchema, configSchema, dockerSourceSchema, durationSchema, fileSourceSchema, logSourceSchema, ndjsonConfigSchema, patternSchema, };
|
|
388
584
|
export type { Config };
|
package/dist/config/schema.js
CHANGED
|
@@ -17,10 +17,18 @@ const durationSchema = z
|
|
|
17
17
|
};
|
|
18
18
|
return amount * msByUnit[unit] <= MAX_DURATION_MS;
|
|
19
19
|
}, 'Duration cannot exceed 24 hours');
|
|
20
|
+
const ndjsonConfigSchema = z.object({
|
|
21
|
+
messageField: z.string().min(1),
|
|
22
|
+
timestampField: z.string().min(1).optional(),
|
|
23
|
+
levelField: z.string().min(1).optional(),
|
|
24
|
+
levelFilter: z.array(z.string().min(1)).optional(),
|
|
25
|
+
});
|
|
20
26
|
const fileSourceSchema = z.object({
|
|
21
27
|
name: z.string().min(1),
|
|
22
28
|
type: z.literal('file'),
|
|
23
29
|
path: z.string().min(1),
|
|
30
|
+
format: z.enum(['text', 'ndjson']).optional(),
|
|
31
|
+
ndjson: ndjsonConfigSchema.optional(),
|
|
24
32
|
});
|
|
25
33
|
const dockerSourceSchema = z.object({
|
|
26
34
|
name: z.string().min(1),
|
|
@@ -59,7 +67,15 @@ const configSchema = z.object({
|
|
|
59
67
|
.refine((sources) => {
|
|
60
68
|
const names = sources.map((source) => source.name);
|
|
61
69
|
return names.length === new Set(names).size;
|
|
62
|
-
}, { message: 'Log source names must be unique' })
|
|
70
|
+
}, { message: 'Log source names must be unique' })
|
|
71
|
+
.refine((sources) => {
|
|
72
|
+
return sources.every((source) => {
|
|
73
|
+
if (source.type === 'file' && source.format === 'ndjson') {
|
|
74
|
+
return source.ndjson !== undefined;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
});
|
|
78
|
+
}, { message: 'ndjson config is required when format is "ndjson"' }),
|
|
63
79
|
context_lines_before: z.number().int().min(0).default(10),
|
|
64
80
|
context_lines_after: z.number().int().min(0).default(5),
|
|
65
81
|
max_line_buffer: z.number().int().min(100).default(10000),
|
|
@@ -92,6 +108,7 @@ const configSchema = z.object({
|
|
|
92
108
|
deduplication: z
|
|
93
109
|
.object({
|
|
94
110
|
fixed_grace_period: durationSchema.default('10m'),
|
|
111
|
+
deferred_grace_period: durationSchema.default('1h'),
|
|
95
112
|
})
|
|
96
113
|
.default({}),
|
|
97
114
|
patterns: z
|
|
@@ -101,4 +118,4 @@ const configSchema = z.object({
|
|
|
101
118
|
})
|
|
102
119
|
.default({}),
|
|
103
120
|
});
|
|
104
|
-
export { commandSourceSchema, configSchema, dockerSourceSchema, durationSchema, fileSourceSchema, logSourceSchema, patternSchema, };
|
|
121
|
+
export { commandSourceSchema, configSchema, dockerSourceSchema, durationSchema, fileSourceSchema, logSourceSchema, ndjsonConfigSchema, patternSchema, };
|
package/dist/db/queries.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export type ErrorInsert = {
|
|
|
35
35
|
createdAt?: string;
|
|
36
36
|
updatedAt?: string;
|
|
37
37
|
};
|
|
38
|
-
export type ActivityAction = 'watcher_start' | 'watcher_stop' | 'error_detected' | 'error_deduplicated' | 'analysis_start' | 'analysis_complete' | 'analysis_failed' | 'analysis_timeout' | 'already_fixed_detected' | 'fix_start' | 'fix_complete' | 'fix_failed' | 'fix_timeout' | 'verification_start' | 'verification_pass' | 'verification_fail' | 'error_ignored' | 'lock_acquired' | 'lock_released' | 'lock_expired' | 'stale_recovery';
|
|
38
|
+
export type ActivityAction = 'watcher_start' | 'watcher_stop' | 'error_detected' | 'error_deduplicated' | 'analysis_start' | 'analysis_complete' | 'analysis_failed' | 'analysis_timeout' | 'already_fixed_detected' | 'error_deferred' | 'deferred_reanalyzed' | 'fix_start' | 'fix_complete' | 'fix_failed' | 'fix_timeout' | 'verification_start' | 'verification_pass' | 'verification_fail' | 'error_ignored' | 'lock_acquired' | 'lock_released' | 'lock_expired' | 'stale_recovery';
|
|
39
39
|
export declare function insertError(db: Database, error: ErrorInsert): number;
|
|
40
40
|
export declare function getError(db: Database, id: number): ErrorRecord | null;
|
|
41
41
|
export declare function getErrorByHash(db: Database, hash: string): ErrorRecord | null;
|