@ironbee-ai/cli 0.5.2 → 0.6.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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/analysis/cross-session.d.ts +1 -1
- package/dist/analysis/cross-session.js +1 -1
- package/dist/analysis/cross-session.js.map +1 -1
- package/dist/analysis/time-analysis.js +3 -3
- package/dist/analysis/time-analysis.js.map +1 -1
- package/dist/analysis/verdict-details.d.ts +1 -1
- package/dist/clients/claude/hooks/clear-verdict.d.ts.map +1 -1
- package/dist/clients/claude/hooks/clear-verdict.js +17 -9
- package/dist/clients/claude/hooks/clear-verdict.js.map +1 -1
- package/dist/clients/claude/hooks/require-verification.d.ts.map +1 -1
- package/dist/clients/claude/hooks/require-verification.js +31 -4
- package/dist/clients/claude/hooks/require-verification.js.map +1 -1
- package/dist/clients/claude/hooks/session-end.d.ts.map +1 -1
- package/dist/clients/claude/hooks/session-end.js +6 -1
- package/dist/clients/claude/hooks/session-end.js.map +1 -1
- package/dist/clients/claude/hooks/session-start.d.ts.map +1 -1
- package/dist/clients/claude/hooks/session-start.js +9 -3
- package/dist/clients/claude/hooks/session-start.js.map +1 -1
- package/dist/clients/claude/hooks/track-action.d.ts +25 -4
- package/dist/clients/claude/hooks/track-action.d.ts.map +1 -1
- package/dist/clients/claude/hooks/track-action.js +160 -29
- package/dist/clients/claude/hooks/track-action.js.map +1 -1
- package/dist/clients/claude/hooks/verify-gate.d.ts.map +1 -1
- package/dist/clients/claude/hooks/verify-gate.js +5 -0
- package/dist/clients/claude/hooks/verify-gate.js.map +1 -1
- package/dist/clients/claude/index.d.ts.map +1 -1
- package/dist/clients/claude/index.js +18 -1
- package/dist/clients/claude/index.js.map +1 -1
- package/dist/clients/claude/util.d.ts +74 -0
- package/dist/clients/claude/util.d.ts.map +1 -0
- package/dist/clients/claude/util.js +352 -0
- package/dist/clients/claude/util.js.map +1 -0
- package/dist/clients/cursor/hooks/clear-verdict.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/clear-verdict.js +19 -10
- package/dist/clients/cursor/hooks/clear-verdict.js.map +1 -1
- package/dist/clients/cursor/hooks/require-verification.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/require-verification.js +28 -4
- package/dist/clients/cursor/hooks/require-verification.js.map +1 -1
- package/dist/clients/cursor/hooks/session-end.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/session-end.js +6 -1
- package/dist/clients/cursor/hooks/session-end.js.map +1 -1
- package/dist/clients/cursor/hooks/session-start.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/session-start.js +7 -2
- package/dist/clients/cursor/hooks/session-start.js.map +1 -1
- package/dist/clients/cursor/hooks/track-action.d.ts +30 -8
- package/dist/clients/cursor/hooks/track-action.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/track-action.js +192 -54
- package/dist/clients/cursor/hooks/track-action.js.map +1 -1
- package/dist/clients/cursor/hooks/verify-gate.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/verify-gate.js +4 -0
- package/dist/clients/cursor/hooks/verify-gate.js.map +1 -1
- package/dist/clients/cursor/index.d.ts.map +1 -1
- package/dist/clients/cursor/index.js +13 -2
- package/dist/clients/cursor/index.js.map +1 -1
- package/dist/clients/cursor/util.d.ts +52 -0
- package/dist/clients/cursor/util.d.ts.map +1 -0
- package/dist/clients/cursor/util.js +264 -0
- package/dist/clients/cursor/util.js.map +1 -0
- package/dist/commands/analyze.js +3 -3
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/hook.js +1 -2
- package/dist/commands/hook.js.map +1 -1
- package/dist/commands/process-job-file.d.ts +10 -0
- package/dist/commands/process-job-file.d.ts.map +1 -0
- package/dist/commands/process-job-file.js +19 -0
- package/dist/commands/process-job-file.js.map +1 -0
- package/dist/commands/queue.d.ts +12 -0
- package/dist/commands/queue.d.ts.map +1 -0
- package/dist/commands/queue.js +495 -0
- package/dist/commands/queue.js.map +1 -0
- package/dist/hooks/core/actions.d.ts +168 -27
- package/dist/hooks/core/actions.d.ts.map +1 -1
- package/dist/hooks/core/actions.js +81 -4
- package/dist/hooks/core/actions.js.map +1 -1
- package/dist/hooks/core/activity.d.ts.map +1 -1
- package/dist/hooks/core/activity.js +13 -6
- package/dist/hooks/core/activity.js.map +1 -1
- package/dist/hooks/core/session-state.d.ts +19 -7
- package/dist/hooks/core/session-state.d.ts.map +1 -1
- package/dist/hooks/core/session-state.js +66 -12
- package/dist/hooks/core/session-state.js.map +1 -1
- package/dist/hooks/core/submit-verdict.d.ts.map +1 -1
- package/dist/hooks/core/submit-verdict.js +13 -4
- package/dist/hooks/core/submit-verdict.js.map +1 -1
- package/dist/hooks/core/verification-lifecycle.d.ts.map +1 -1
- package/dist/hooks/core/verification-lifecycle.js +14 -4
- package/dist/hooks/core/verification-lifecycle.js.map +1 -1
- package/dist/hooks/core/verify-gate.d.ts.map +1 -1
- package/dist/hooks/core/verify-gate.js +31 -19
- package/dist/hooks/core/verify-gate.js.map +1 -1
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/collector.d.ts +64 -5
- package/dist/lib/collector.d.ts.map +1 -1
- package/dist/lib/collector.js +107 -44
- package/dist/lib/collector.js.map +1 -1
- package/dist/lib/config.d.ts +72 -8
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +40 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/queue/dead-letter.d.ts +26 -0
- package/dist/queue/dead-letter.d.ts.map +1 -0
- package/dist/queue/dead-letter.js +233 -0
- package/dist/queue/dead-letter.js.map +1 -0
- package/dist/queue/drain.d.ts +36 -0
- package/dist/queue/drain.d.ts.map +1 -0
- package/dist/queue/drain.js +170 -0
- package/dist/queue/drain.js.map +1 -0
- package/dist/queue/flush.d.ts +64 -0
- package/dist/queue/flush.d.ts.map +1 -0
- package/dist/queue/flush.js +119 -0
- package/dist/queue/flush.js.map +1 -0
- package/dist/queue/handlers/send-event.d.ts +23 -0
- package/dist/queue/handlers/send-event.d.ts.map +1 -0
- package/dist/queue/handlers/send-event.js +131 -0
- package/dist/queue/handlers/send-event.js.map +1 -0
- package/dist/queue/index.d.ts +30 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +71 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/paths.d.ts +40 -0
- package/dist/queue/paths.d.ts.map +1 -0
- package/dist/queue/paths.js +107 -0
- package/dist/queue/paths.js.map +1 -0
- package/dist/queue/process-file.d.ts +22 -0
- package/dist/queue/process-file.d.ts.map +1 -0
- package/dist/queue/process-file.js +257 -0
- package/dist/queue/process-file.js.map +1 -0
- package/dist/queue/register-handlers.d.ts +26 -0
- package/dist/queue/register-handlers.d.ts.map +1 -0
- package/dist/queue/register-handlers.js +36 -0
- package/dist/queue/register-handlers.js.map +1 -0
- package/dist/queue/registry.d.ts +42 -0
- package/dist/queue/registry.d.ts.map +1 -0
- package/dist/queue/registry.js +36 -0
- package/dist/queue/registry.js.map +1 -0
- package/dist/queue/snapshot.d.ts +16 -0
- package/dist/queue/snapshot.d.ts.map +1 -0
- package/dist/queue/snapshot.js +39 -0
- package/dist/queue/snapshot.js.map +1 -0
- package/dist/queue/spawn.d.ts +15 -0
- package/dist/queue/spawn.d.ts.map +1 -0
- package/dist/queue/spawn.js +45 -0
- package/dist/queue/spawn.js.map +1 -0
- package/dist/queue/submit.d.ts +19 -0
- package/dist/queue/submit.d.ts.map +1 -0
- package/dist/queue/submit.js +94 -0
- package/dist/queue/submit.js.map +1 -0
- package/dist/queue/types.d.ts +77 -0
- package/dist/queue/types.d.ts.map +1 -0
- package/dist/queue/types.js +83 -0
- package/dist/queue/types.js.map +1 -0
- package/dist/queue/worker-log.d.ts +21 -0
- package/dist/queue/worker-log.d.ts.map +1 -0
- package/dist/queue/worker-log.js +140 -0
- package/dist/queue/worker-log.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* IronBee CLI — Dead Letter Writer + Rotation
|
|
4
|
+
*
|
|
5
|
+
* See docs/job-queue.md §6.1 (entry shape), §6.2 (rotation + retention).
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.deadLetterParsed = deadLetterParsed;
|
|
9
|
+
exports.deadLetterParseError = deadLetterParseError;
|
|
10
|
+
exports.readDeadLetterEntries = readDeadLetterEntries;
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
const crypto_1 = require("crypto");
|
|
14
|
+
const logger_1 = require("../lib/logger");
|
|
15
|
+
const types_1 = require("./types");
|
|
16
|
+
const paths_1 = require("./paths");
|
|
17
|
+
/**
|
|
18
|
+
* Append a parsed-job dead-letter entry. Enforces the 4 KB line ceiling via a
|
|
19
|
+
* cascade of three truncation fallbacks. The last fallback always fits — it
|
|
20
|
+
* replaces the entire entry with a minimal overflow marker — so the atomic
|
|
21
|
+
* append invariant (§6.1) always holds.
|
|
22
|
+
*/
|
|
23
|
+
function deadLetterParsed(input, job, category) {
|
|
24
|
+
const filename = (0, path_1.basename)(input.sourceFile);
|
|
25
|
+
const receivedAt = new Date().toISOString();
|
|
26
|
+
const entryId = (0, crypto_1.randomUUID)();
|
|
27
|
+
// Fallback 0: the happy case — full entry.
|
|
28
|
+
let entry = {
|
|
29
|
+
id: entryId,
|
|
30
|
+
received_at: receivedAt,
|
|
31
|
+
source_file: filename,
|
|
32
|
+
category,
|
|
33
|
+
original: job,
|
|
34
|
+
};
|
|
35
|
+
let line = JSON.stringify(entry) + "\n";
|
|
36
|
+
if (Buffer.byteLength(line, "utf-8") > types_1.MAX_LINE_BYTES) {
|
|
37
|
+
// Fallback 1: drop `original.data`.
|
|
38
|
+
entry = {
|
|
39
|
+
...entry,
|
|
40
|
+
original: {
|
|
41
|
+
id: job.id,
|
|
42
|
+
type: job.type,
|
|
43
|
+
created_at: job.created_at,
|
|
44
|
+
data: { __truncated__: true },
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
line = JSON.stringify(entry) + "\n";
|
|
48
|
+
}
|
|
49
|
+
if (Buffer.byteLength(line, "utf-8") > types_1.MAX_LINE_BYTES) {
|
|
50
|
+
// Fallback 2: also truncate the category string.
|
|
51
|
+
entry = {
|
|
52
|
+
...entry,
|
|
53
|
+
category: truncateString(category, 256),
|
|
54
|
+
};
|
|
55
|
+
line = JSON.stringify(entry) + "\n";
|
|
56
|
+
}
|
|
57
|
+
if (Buffer.byteLength(line, "utf-8") > types_1.MAX_LINE_BYTES) {
|
|
58
|
+
// Fallback 3: minimal overflow marker. Preserves identity + triage
|
|
59
|
+
// pointer (job id, source_file) but drops everything else.
|
|
60
|
+
const minimal = {
|
|
61
|
+
id: entryId,
|
|
62
|
+
received_at: receivedAt,
|
|
63
|
+
source_file: truncateString(filename, 128),
|
|
64
|
+
category: "overflow",
|
|
65
|
+
original: { id: job.id, type: truncateString(job.type, 64) },
|
|
66
|
+
__truncated__: true,
|
|
67
|
+
};
|
|
68
|
+
line = JSON.stringify(minimal) + "\n";
|
|
69
|
+
// Absolute last resort — if even this exceeds 4 KB (which would
|
|
70
|
+
// require a pathologically long source_file name the OS likely
|
|
71
|
+
// rejected anyway), hard-truncate the byte array and append a "\n".
|
|
72
|
+
if (Buffer.byteLength(line, "utf-8") > types_1.MAX_LINE_BYTES) {
|
|
73
|
+
const raw = Buffer.from(line, "utf-8").subarray(0, types_1.MAX_LINE_BYTES - 1);
|
|
74
|
+
line = raw.toString("utf-8") + "\n";
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
writeDeadLetterLine(input.projectDir, input.sessionId, line);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Append a parse-error dead-letter entry. The raw line is truncated to 512
|
|
81
|
+
* chars and ASCII control chars are escaped.
|
|
82
|
+
*/
|
|
83
|
+
function deadLetterParseError(input, raw, category) {
|
|
84
|
+
const filename = (0, path_1.basename)(input.sourceFile);
|
|
85
|
+
const sanitized = escapeControls(raw).slice(0, types_1.DEAD_LETTER_RAW_MAX);
|
|
86
|
+
const entry = {
|
|
87
|
+
id: (0, crypto_1.randomUUID)(),
|
|
88
|
+
received_at: new Date().toISOString(),
|
|
89
|
+
source_file: filename,
|
|
90
|
+
category,
|
|
91
|
+
raw: sanitized,
|
|
92
|
+
};
|
|
93
|
+
const line = JSON.stringify(entry) + "\n";
|
|
94
|
+
writeDeadLetterLine(input.projectDir, input.sessionId, line);
|
|
95
|
+
}
|
|
96
|
+
function writeDeadLetterLine(projectDir, sessionId, line) {
|
|
97
|
+
const dir = (0, paths_1.queueDir)(projectDir, sessionId);
|
|
98
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true, mode: 0o700 });
|
|
99
|
+
const path = (0, paths_1.deadLetterFile)(projectDir, sessionId);
|
|
100
|
+
const flags = fs_1.constants.O_CREAT
|
|
101
|
+
| fs_1.constants.O_WRONLY
|
|
102
|
+
| fs_1.constants.O_APPEND
|
|
103
|
+
| (typeof fs_1.constants.O_NOFOLLOW === "number" ? fs_1.constants.O_NOFOLLOW : 0);
|
|
104
|
+
const fd = (0, fs_1.openSync)(path, flags, 0o600);
|
|
105
|
+
try {
|
|
106
|
+
const bytes = Buffer.from(line, "utf-8");
|
|
107
|
+
(0, fs_1.writeSync)(fd, bytes, 0, bytes.length);
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
try {
|
|
111
|
+
(0, fs_1.closeSync)(fd);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// ignore
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
rotateIfNeeded(projectDir, sessionId);
|
|
118
|
+
}
|
|
119
|
+
function rotateIfNeeded(projectDir, sessionId) {
|
|
120
|
+
// Size-only rotation — `stat()` is O(1), appends stay sub-ms even with a
|
|
121
|
+
// near-threshold file. A line-count check would require reading the whole
|
|
122
|
+
// file on every append, which defeats the purpose of append-only writes.
|
|
123
|
+
// Practical dead-letter entries are 400–1500 bytes, so 10 MB naturally
|
|
124
|
+
// bounds line count to ~7k–25k.
|
|
125
|
+
const path = (0, paths_1.deadLetterFile)(projectDir, sessionId);
|
|
126
|
+
let size;
|
|
127
|
+
try {
|
|
128
|
+
size = (0, fs_1.statSync)(path).size;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (size <= types_1.DEAD_LETTER_ROTATE_BYTES) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const dir = (0, paths_1.queueDir)(projectDir, sessionId);
|
|
137
|
+
const rotated = (0, path_1.join)(dir, `dead-letter-${(0, crypto_1.randomUUID)()}.jsonl`);
|
|
138
|
+
try {
|
|
139
|
+
(0, fs_1.renameSync)(path, rotated);
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
const err = e;
|
|
143
|
+
if (err.code === "ENOENT") {
|
|
144
|
+
// another worker already rotated; nothing to do
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// Keep the writer robust — non-ENOENT failure (EACCES, EIO, EXDEV, …)
|
|
148
|
+
// means the dead-letter file keeps growing past the 10 MB target
|
|
149
|
+
// until the cause is fixed. Surface via debug so the operator has a
|
|
150
|
+
// trace to follow instead of a silent slow-grow.
|
|
151
|
+
logger_1.logger.debug(`dead-letter rotation failed on ${path}: ${err.code ?? err.message}`);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
enforceRetention(projectDir, sessionId);
|
|
155
|
+
}
|
|
156
|
+
function enforceRetention(projectDir, sessionId) {
|
|
157
|
+
const dir = (0, paths_1.queueDir)(projectDir, sessionId);
|
|
158
|
+
let entries;
|
|
159
|
+
try {
|
|
160
|
+
entries = (0, fs_1.readdirSync)(dir);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const rotated = [];
|
|
166
|
+
for (const name of entries) {
|
|
167
|
+
if (!paths_1.DEAD_LETTER_ROTATED_REGEX.test(name)) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const full = (0, path_1.join)(dir, name);
|
|
171
|
+
try {
|
|
172
|
+
const st = (0, fs_1.statSync)(full);
|
|
173
|
+
rotated.push({ path: full, mtimeMs: st.mtimeMs });
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// ignore
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (rotated.length <= types_1.DEAD_LETTER_RETAIN_COUNT) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// sort newest first; unlink anything past the keep count
|
|
183
|
+
rotated.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
184
|
+
for (let i = types_1.DEAD_LETTER_RETAIN_COUNT; i < rotated.length; i++) {
|
|
185
|
+
try {
|
|
186
|
+
(0, fs_1.unlinkSync)(rotated[i].path);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// ignore — best-effort
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function escapeControls(s) {
|
|
194
|
+
let out = "";
|
|
195
|
+
for (let i = 0; i < s.length; i++) {
|
|
196
|
+
const code = s.charCodeAt(i);
|
|
197
|
+
if (code < 0x20 || code === 0x7f) {
|
|
198
|
+
out += `\\x${code.toString(16).padStart(2, "0")}`;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
out += s[i];
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return out;
|
|
205
|
+
}
|
|
206
|
+
function truncateString(s, max) {
|
|
207
|
+
return s.length <= max ? s : s.slice(0, max) + "…";
|
|
208
|
+
}
|
|
209
|
+
/** Exposed for tests and CLI tooling. */
|
|
210
|
+
function readDeadLetterEntries(projectDir, sessionId) {
|
|
211
|
+
const path = (0, paths_1.deadLetterFile)(projectDir, sessionId);
|
|
212
|
+
let content;
|
|
213
|
+
try {
|
|
214
|
+
content = (0, fs_1.readFileSync)(path, "utf-8");
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
const out = [];
|
|
220
|
+
for (const line of content.split("\n")) {
|
|
221
|
+
if (line.length === 0) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
out.push(JSON.parse(line));
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// skip unparseable dead-letter lines — shouldn't happen in practice
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return out;
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=dead-letter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dead-letter.js","sourceRoot":"","sources":["../../src/queue/dead-letter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IronBee CLI — Queue drain()
|
|
3
|
+
*
|
|
4
|
+
* See docs/job-queue.md §5.4. Synchronous per-session final-flush.
|
|
5
|
+
* Cleanup touches ONLY the queue/ subdir — never the parent session dir,
|
|
6
|
+
* which is owned by the consumer (actions.jsonl, verdict.json, …).
|
|
7
|
+
*/
|
|
8
|
+
import { HandlerRegistry } from "./registry";
|
|
9
|
+
export interface DrainOptions {
|
|
10
|
+
registry?: HandlerRegistry;
|
|
11
|
+
/**
|
|
12
|
+
* Skip snapshot files whose mtime is within the last `skipRecentMs`
|
|
13
|
+
* milliseconds. Used by `flushSynchronously` at SessionEnd to avoid
|
|
14
|
+
* racing with a detached worker that was just spawned by a Stop-class
|
|
15
|
+
* hook (§7.3). Operator-facing `ironbee queue drain` leaves this at 0
|
|
16
|
+
* so it catches every snapshot, including those from a just-crashed
|
|
17
|
+
* worker. Default 0.
|
|
18
|
+
*/
|
|
19
|
+
skipRecentMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface DrainResult {
|
|
22
|
+
snapshotsProcessed: number;
|
|
23
|
+
snapshotsRemaining: number;
|
|
24
|
+
cleanedQueueDir: boolean;
|
|
25
|
+
/** Snapshots that were skipped because they are too recent (see DrainOptions.skipRecentMs). */
|
|
26
|
+
snapshotsSkippedRecent: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Drain one session synchronously:
|
|
30
|
+
* 1. Roll the live file (if any) into a snapshot.
|
|
31
|
+
* 2. Process every snapshot in sorted order.
|
|
32
|
+
* 3. Best-effort cleanup of the queue/ dir if fully empty of undelivered
|
|
33
|
+
* work and triage records.
|
|
34
|
+
*/
|
|
35
|
+
export declare function drain(projectDir: string, sessionId: string, opts?: DrainOptions): Promise<DrainResult>;
|
|
36
|
+
//# sourceMappingURL=drain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drain.d.ts","sourceRoot":"","sources":["../../src/queue/drain.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;IACzB,+FAA+F;IAC/F,sBAAsB,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA2C5G"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* IronBee CLI — Queue drain()
|
|
4
|
+
*
|
|
5
|
+
* See docs/job-queue.md §5.4. Synchronous per-session final-flush.
|
|
6
|
+
* Cleanup touches ONLY the queue/ subdir — never the parent session dir,
|
|
7
|
+
* which is owned by the consumer (actions.jsonl, verdict.json, …).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.drain = drain;
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
const snapshot_1 = require("./snapshot");
|
|
14
|
+
const process_file_1 = require("./process-file");
|
|
15
|
+
const paths_1 = require("./paths");
|
|
16
|
+
/**
|
|
17
|
+
* Drain one session synchronously:
|
|
18
|
+
* 1. Roll the live file (if any) into a snapshot.
|
|
19
|
+
* 2. Process every snapshot in sorted order.
|
|
20
|
+
* 3. Best-effort cleanup of the queue/ dir if fully empty of undelivered
|
|
21
|
+
* work and triage records.
|
|
22
|
+
*/
|
|
23
|
+
async function drain(projectDir, sessionId, opts) {
|
|
24
|
+
(0, paths_1.validateSessionId)(sessionId);
|
|
25
|
+
const dir = (0, paths_1.queueDir)(projectDir, sessionId);
|
|
26
|
+
const result = {
|
|
27
|
+
snapshotsProcessed: 0,
|
|
28
|
+
snapshotsRemaining: 0,
|
|
29
|
+
cleanedQueueDir: false,
|
|
30
|
+
snapshotsSkippedRecent: 0,
|
|
31
|
+
};
|
|
32
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
const skipRecentMs = opts?.skipRecentMs ?? 0;
|
|
36
|
+
// Step 3 of §5.4: roll live file into a snapshot if it exists. This
|
|
37
|
+
// freshly-renamed snapshot has a brand-new mtime, so skipRecentMs would
|
|
38
|
+
// exclude it. Remember its path (if any) and force-process it below.
|
|
39
|
+
let justRolled = null;
|
|
40
|
+
try {
|
|
41
|
+
justRolled = (0, snapshot_1.snapshot)(projectDir, sessionId);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// snapshot() already returns null on ENOENT; any other failure bubbles
|
|
45
|
+
// into the glob below which will skip it. Keep drain() fault-tolerant.
|
|
46
|
+
}
|
|
47
|
+
// Step 4: process every snapshot.
|
|
48
|
+
const { eligible, skipped } = listSnapshots(dir, skipRecentMs, justRolled);
|
|
49
|
+
result.snapshotsSkippedRecent = skipped;
|
|
50
|
+
for (const snap of eligible) {
|
|
51
|
+
try {
|
|
52
|
+
await (0, process_file_1.processFile)(snap, { registry: opts?.registry });
|
|
53
|
+
result.snapshotsProcessed++;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// processFile never throws in normal paths, but be defensive
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Step 5: cleanup — strictly queue/ only; never the session dir.
|
|
60
|
+
result.snapshotsRemaining = listSnapshots(dir, 0, null).eligible.length;
|
|
61
|
+
result.cleanedQueueDir = tryCleanupQueueDir(projectDir, sessionId);
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Enumerate snapshot files under `dir`, filtering out those touched within
|
|
66
|
+
* `skipRecentMs` unless they match `forceInclude` (the path we just rolled
|
|
67
|
+
* this drain cycle — it always needs processing even if its mtime is fresh).
|
|
68
|
+
*/
|
|
69
|
+
function listSnapshots(dir, skipRecentMs, forceInclude) {
|
|
70
|
+
let entries;
|
|
71
|
+
try {
|
|
72
|
+
entries = (0, fs_1.readdirSync)(dir);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return { eligible: [], skipped: 0 };
|
|
76
|
+
}
|
|
77
|
+
const now = Date.now();
|
|
78
|
+
const eligible = [];
|
|
79
|
+
let skipped = 0;
|
|
80
|
+
for (const name of entries) {
|
|
81
|
+
if (!paths_1.SNAPSHOT_FILENAME_REGEX.test(name)) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const full = (0, path_1.join)(dir, name);
|
|
85
|
+
if (forceInclude !== null && full === forceInclude) {
|
|
86
|
+
eligible.push(full);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (skipRecentMs > 0) {
|
|
90
|
+
try {
|
|
91
|
+
const mtime = (0, fs_1.statSync)(full).mtimeMs;
|
|
92
|
+
if (now - mtime < skipRecentMs) {
|
|
93
|
+
skipped++;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// stat failed — include and let processFile handle it
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
eligible.push(full);
|
|
102
|
+
}
|
|
103
|
+
eligible.sort();
|
|
104
|
+
return { eligible, skipped };
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Remove worker.log and empty dead-letter.jsonl, then rmdir queue/ — but
|
|
108
|
+
* only if no undelivered work or non-empty triage record remains.
|
|
109
|
+
* The session directory itself is owned by the consumer; never touched.
|
|
110
|
+
*/
|
|
111
|
+
function tryCleanupQueueDir(projectDir, sessionId) {
|
|
112
|
+
const dir = (0, paths_1.queueDir)(projectDir, sessionId);
|
|
113
|
+
let entries;
|
|
114
|
+
try {
|
|
115
|
+
entries = (0, fs_1.readdirSync)(dir);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
// Any undelivered snapshot, any live file, or any non-empty dead-letter
|
|
121
|
+
// content blocks cleanup.
|
|
122
|
+
for (const name of entries) {
|
|
123
|
+
if (name === "jobs.jsonl") {
|
|
124
|
+
if (fileSize((0, path_1.join)(dir, name)) > 0) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (paths_1.SNAPSHOT_FILENAME_REGEX.test(name)) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
if (name === "dead-letter.jsonl" || paths_1.DEAD_LETTER_ROTATED_REGEX.test(name)) {
|
|
132
|
+
if (fileSize((0, path_1.join)(dir, name)) > 0) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Safe to cleanup. Remove discardable files first.
|
|
138
|
+
for (const name of entries) {
|
|
139
|
+
if (name === "jobs.jsonl"
|
|
140
|
+
|| name === "dead-letter.jsonl"
|
|
141
|
+
|| paths_1.DEAD_LETTER_ROTATED_REGEX.test(name)
|
|
142
|
+
|| name === "worker.log"
|
|
143
|
+
|| paths_1.WORKER_LOG_ROTATED_REGEX.test(name)) {
|
|
144
|
+
try {
|
|
145
|
+
(0, fs_1.unlinkSync)((0, path_1.join)(dir, name));
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// best-effort
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Attempt rmdir queue/ — fails silently if other (unknown) files remain,
|
|
153
|
+
// which is the safe thing to do.
|
|
154
|
+
try {
|
|
155
|
+
(0, fs_1.rmdirSync)(dir);
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function fileSize(path) {
|
|
163
|
+
try {
|
|
164
|
+
return (0, fs_1.statSync)(path).size;
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return 0;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=drain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drain.js","sourceRoot":"","sources":["../../src/queue/drain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IronBee CLI — Queue flush helpers
|
|
3
|
+
*
|
|
4
|
+
* Per-session flush triggers for consumer hooks. Two modes, to be chosen per
|
|
5
|
+
* §5.6 of docs/job-queue.md:
|
|
6
|
+
*
|
|
7
|
+
* - flushInBackground() — used by Stop-class hooks (active session).
|
|
8
|
+
* snapshot() the live file and fire-and-forget a
|
|
9
|
+
* detached worker on it. Returns in <10 ms.
|
|
10
|
+
*
|
|
11
|
+
* - flushSynchronously() — used by SessionEnd-class hooks (consumer is
|
|
12
|
+
* about to exit). Synchronously drain() every
|
|
13
|
+
* snapshot. May block for milliseconds to low
|
|
14
|
+
* seconds.
|
|
15
|
+
*
|
|
16
|
+
* Both helpers are fail-safe: any thrown error is swallowed and debug-logged
|
|
17
|
+
* so a queue fault cannot break the hook.
|
|
18
|
+
*/
|
|
19
|
+
import { DrainOptions, DrainResult } from "./drain";
|
|
20
|
+
/** Default threshold for `maybeAutoFlush` when unset in config (32 KB). */
|
|
21
|
+
export declare const DEFAULT_AUTO_FLUSH_SIZE_BYTES: number;
|
|
22
|
+
/**
|
|
23
|
+
* Stop-class hooks use this: snapshot the live queue and launch a detached
|
|
24
|
+
* worker. The caller's process may exit immediately after — the worker's
|
|
25
|
+
* `child.unref()` detaches it from the parent's event loop and process group
|
|
26
|
+
* to the extent the platform allows.
|
|
27
|
+
*
|
|
28
|
+
* Behaviour when queue has no work: snapshot() returns null (no live file),
|
|
29
|
+
* no worker spawned. No-op when the queue module has no producer yet.
|
|
30
|
+
*/
|
|
31
|
+
export declare function flushInBackground(projectDir: string, sessionId: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Producer-side auto-flush trigger. Called from `submit()` after a successful
|
|
34
|
+
* append. If the live `jobs.jsonl` has grown to at least the configured
|
|
35
|
+
* threshold (`jobQueue.autoFlushSizeBytes`, default 32 KB), snapshot it and
|
|
36
|
+
* spawn a detached worker in the background — same mechanism as a Stop hook,
|
|
37
|
+
* just triggered mid-session by queue growth instead of by a lifecycle event.
|
|
38
|
+
*
|
|
39
|
+
* Complements Stop / SessionEnd flushes: provides checkpointing for turns
|
|
40
|
+
* that emit many tool_call events (so collector sees them sooner) and caps
|
|
41
|
+
* worst-case live file size on abandoned sessions.
|
|
42
|
+
*
|
|
43
|
+
* Fail-safe: config read errors, stat failures, and flushInBackground
|
|
44
|
+
* exceptions are all swallowed so a queue fault can never break submit().
|
|
45
|
+
*
|
|
46
|
+
* Threshold <= 0 disables the feature (only lifecycle flushes remain).
|
|
47
|
+
*/
|
|
48
|
+
export declare function maybeAutoFlush(projectDir: string, sessionId: string): void;
|
|
49
|
+
/** Default recent-skip window used by `flushSynchronously` (see §7.3). */
|
|
50
|
+
export declare const SESSION_END_SKIP_RECENT_MS: number;
|
|
51
|
+
/**
|
|
52
|
+
* SessionEnd-class hooks use this: synchronously drain every snapshot for the
|
|
53
|
+
* session, then (if possible) clean up the queue/ subdir. Consumer owns the
|
|
54
|
+
* session dir itself — drain never touches anything outside queue/.
|
|
55
|
+
*
|
|
56
|
+
* By default skips snapshot files modified in the last 2 seconds — this is
|
|
57
|
+
* the "in-flight detached worker" window opened by a Stop hook firing right
|
|
58
|
+
* before SessionEnd (§7.3). Override with `opts.skipRecentMs = 0` if you
|
|
59
|
+
* want to treat recent snapshots as orphans (e.g. from tests). Skipped
|
|
60
|
+
* snapshots remain on disk and are drained by the next `ironbee queue drain`
|
|
61
|
+
* invocation.
|
|
62
|
+
*/
|
|
63
|
+
export declare function flushSynchronously(projectDir: string, sessionId: string, opts?: DrainOptions): Promise<DrainResult>;
|
|
64
|
+
//# sourceMappingURL=flush.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flush.d.ts","sourceRoot":"","sources":["../../src/queue/flush.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAS,MAAM,SAAS,CAAC;AAK3D,2EAA2E;AAC3E,eAAO,MAAM,6BAA6B,EAAE,MAAkB,CAAC;AAE/D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAU7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAkB1E;AAED,0EAA0E;AAC1E,eAAO,MAAM,0BAA0B,EAAE,MAAa,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACpC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC,CAYtB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* IronBee CLI — Queue flush helpers
|
|
4
|
+
*
|
|
5
|
+
* Per-session flush triggers for consumer hooks. Two modes, to be chosen per
|
|
6
|
+
* §5.6 of docs/job-queue.md:
|
|
7
|
+
*
|
|
8
|
+
* - flushInBackground() — used by Stop-class hooks (active session).
|
|
9
|
+
* snapshot() the live file and fire-and-forget a
|
|
10
|
+
* detached worker on it. Returns in <10 ms.
|
|
11
|
+
*
|
|
12
|
+
* - flushSynchronously() — used by SessionEnd-class hooks (consumer is
|
|
13
|
+
* about to exit). Synchronously drain() every
|
|
14
|
+
* snapshot. May block for milliseconds to low
|
|
15
|
+
* seconds.
|
|
16
|
+
*
|
|
17
|
+
* Both helpers are fail-safe: any thrown error is swallowed and debug-logged
|
|
18
|
+
* so a queue fault cannot break the hook.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.SESSION_END_SKIP_RECENT_MS = exports.DEFAULT_AUTO_FLUSH_SIZE_BYTES = void 0;
|
|
22
|
+
exports.flushInBackground = flushInBackground;
|
|
23
|
+
exports.maybeAutoFlush = maybeAutoFlush;
|
|
24
|
+
exports.flushSynchronously = flushSynchronously;
|
|
25
|
+
const fs_1 = require("fs");
|
|
26
|
+
const config_1 = require("../lib/config");
|
|
27
|
+
const logger_1 = require("../lib/logger");
|
|
28
|
+
const drain_1 = require("./drain");
|
|
29
|
+
const paths_1 = require("./paths");
|
|
30
|
+
const snapshot_1 = require("./snapshot");
|
|
31
|
+
const spawn_1 = require("./spawn");
|
|
32
|
+
/** Default threshold for `maybeAutoFlush` when unset in config (32 KB). */
|
|
33
|
+
exports.DEFAULT_AUTO_FLUSH_SIZE_BYTES = 32 * 1024;
|
|
34
|
+
/**
|
|
35
|
+
* Stop-class hooks use this: snapshot the live queue and launch a detached
|
|
36
|
+
* worker. The caller's process may exit immediately after — the worker's
|
|
37
|
+
* `child.unref()` detaches it from the parent's event loop and process group
|
|
38
|
+
* to the extent the platform allows.
|
|
39
|
+
*
|
|
40
|
+
* Behaviour when queue has no work: snapshot() returns null (no live file),
|
|
41
|
+
* no worker spawned. No-op when the queue module has no producer yet.
|
|
42
|
+
*/
|
|
43
|
+
function flushInBackground(projectDir, sessionId) {
|
|
44
|
+
try {
|
|
45
|
+
(0, paths_1.validateSessionId)(sessionId);
|
|
46
|
+
const snap = (0, snapshot_1.snapshot)(projectDir, sessionId);
|
|
47
|
+
if (snap !== null) {
|
|
48
|
+
(0, spawn_1.spawnDetachedWorker)(snap);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
logger_1.logger.debug(`queue flushInBackground failed: ${e instanceof Error ? e.message : e}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Producer-side auto-flush trigger. Called from `submit()` after a successful
|
|
57
|
+
* append. If the live `jobs.jsonl` has grown to at least the configured
|
|
58
|
+
* threshold (`jobQueue.autoFlushSizeBytes`, default 32 KB), snapshot it and
|
|
59
|
+
* spawn a detached worker in the background — same mechanism as a Stop hook,
|
|
60
|
+
* just triggered mid-session by queue growth instead of by a lifecycle event.
|
|
61
|
+
*
|
|
62
|
+
* Complements Stop / SessionEnd flushes: provides checkpointing for turns
|
|
63
|
+
* that emit many tool_call events (so collector sees them sooner) and caps
|
|
64
|
+
* worst-case live file size on abandoned sessions.
|
|
65
|
+
*
|
|
66
|
+
* Fail-safe: config read errors, stat failures, and flushInBackground
|
|
67
|
+
* exceptions are all swallowed so a queue fault can never break submit().
|
|
68
|
+
*
|
|
69
|
+
* Threshold <= 0 disables the feature (only lifecycle flushes remain).
|
|
70
|
+
*/
|
|
71
|
+
function maybeAutoFlush(projectDir, sessionId) {
|
|
72
|
+
try {
|
|
73
|
+
const config = (0, config_1.loadConfig)(projectDir);
|
|
74
|
+
const raw = config.jobQueue?.autoFlushSizeBytes;
|
|
75
|
+
const threshold = typeof raw === "number" ? raw : exports.DEFAULT_AUTO_FLUSH_SIZE_BYTES;
|
|
76
|
+
if (threshold <= 0) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const livePath = (0, paths_1.liveQueueFile)(projectDir, sessionId);
|
|
80
|
+
const size = (0, fs_1.statSync)(livePath).size;
|
|
81
|
+
if (size >= threshold) {
|
|
82
|
+
flushInBackground(projectDir, sessionId);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
// ENOENT on stat (file rolled between submit and stat) or any other
|
|
87
|
+
// fault must not propagate — submit() already persisted the line.
|
|
88
|
+
logger_1.logger.debug(`queue maybeAutoFlush skipped: ${e instanceof Error ? e.message : e}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** Default recent-skip window used by `flushSynchronously` (see §7.3). */
|
|
92
|
+
exports.SESSION_END_SKIP_RECENT_MS = 2000;
|
|
93
|
+
/**
|
|
94
|
+
* SessionEnd-class hooks use this: synchronously drain every snapshot for the
|
|
95
|
+
* session, then (if possible) clean up the queue/ subdir. Consumer owns the
|
|
96
|
+
* session dir itself — drain never touches anything outside queue/.
|
|
97
|
+
*
|
|
98
|
+
* By default skips snapshot files modified in the last 2 seconds — this is
|
|
99
|
+
* the "in-flight detached worker" window opened by a Stop hook firing right
|
|
100
|
+
* before SessionEnd (§7.3). Override with `opts.skipRecentMs = 0` if you
|
|
101
|
+
* want to treat recent snapshots as orphans (e.g. from tests). Skipped
|
|
102
|
+
* snapshots remain on disk and are drained by the next `ironbee queue drain`
|
|
103
|
+
* invocation.
|
|
104
|
+
*/
|
|
105
|
+
async function flushSynchronously(projectDir, sessionId, opts) {
|
|
106
|
+
try {
|
|
107
|
+
(0, paths_1.validateSessionId)(sessionId);
|
|
108
|
+
const merged = {
|
|
109
|
+
...opts,
|
|
110
|
+
skipRecentMs: opts?.skipRecentMs ?? exports.SESSION_END_SKIP_RECENT_MS,
|
|
111
|
+
};
|
|
112
|
+
return await (0, drain_1.drain)(projectDir, sessionId, merged);
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
logger_1.logger.debug(`queue flushSynchronously failed: ${e instanceof Error ? e.message : e}`);
|
|
116
|
+
return { snapshotsProcessed: 0, snapshotsRemaining: 0, cleanedQueueDir: false, snapshotsSkippedRecent: 0 };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=flush.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flush.js","sourceRoot":"","sources":["../../src/queue/flush.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;AAsBH,8CAUC;AAkBD,wCAkBC;AAiBD,gDAgBC;AAnGD,2BAA8B;AAC9B,0CAA0D;AAC1D,0CAAuC;AACvC,mCAA2D;AAC3D,mCAA2D;AAC3D,yCAAsC;AACtC,mCAA8C;AAE9C,2EAA2E;AAC9D,QAAA,6BAA6B,GAAW,EAAE,GAAG,IAAI,CAAC;AAE/D;;;;;;;;GAQG;AACH,SAAgB,iBAAiB,CAAC,UAAkB,EAAE,SAAiB;IACnE,IAAI,CAAC;QACD,IAAA,yBAAiB,EAAC,SAAS,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAkB,IAAA,mBAAQ,EAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC5D,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,IAAA,2BAAmB,EAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;IACL,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,cAAc,CAAC,UAAkB,EAAE,SAAiB;IAChE,IAAI,CAAC;QACD,MAAM,MAAM,GAAkB,IAAA,mBAAU,EAAC,UAAU,CAAC,CAAC;QACrD,MAAM,GAAG,GAAuB,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC;QACpE,MAAM,SAAS,GAAW,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,qCAA6B,CAAC;QACxF,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACjB,OAAO;QACX,CAAC;QACD,MAAM,QAAQ,GAAW,IAAA,qBAAa,EAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAW,IAAA,aAAQ,EAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;QAC7C,IAAI,IAAI,IAAI,SAAS,EAAE,CAAC;YACpB,iBAAiB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC7C,CAAC;IACL,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,oEAAoE;QACpE,kEAAkE;QAClE,eAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxF,CAAC;AACL,CAAC;AAED,0EAA0E;AAC7D,QAAA,0BAA0B,GAAW,IAAI,CAAC;AAEvD;;;;;;;;;;;GAWG;AACI,KAAK,UAAU,kBAAkB,CACpC,UAAkB,EAClB,SAAiB,EACjB,IAAmB;IAEnB,IAAI,CAAC;QACD,IAAA,yBAAiB,EAAC,SAAS,CAAC,CAAC;QAC7B,MAAM,MAAM,GAAiB;YACzB,GAAG,IAAI;YACP,YAAY,EAAE,IAAI,EAAE,YAAY,IAAI,kCAA0B;SACjE,CAAC;QACF,OAAO,MAAM,IAAA,aAAK,EAAC,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvF,OAAO,EAAE,kBAAkB,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,EAAE,CAAC;IAC/G,CAAC;AACL,CAAC"}
|