add cursor-based pull events: clide events --since <cursor> (T-223)

The one-shot request/response complement to the never-returning
`tail --events` stream — what an agent poll loop wants. The IPC server now
keeps a single global, arrival-ordered event log keyed by a monotonic
cursor (alongside the per-subsystem replay ring), bounded by eventLogDepth
with drop-oldest back-pressure (D-85: producer never blocks).

`clide events [--since <cursor>] [--filter X]` returns events after the
cursor, a high-water `cursor` to poll from next, and `gap: true` (+
oldestCursor) when the requested cursor predates the retained window so a
caller detects loss instead of silently missing dropped events. Repeated
polls neither drop nor duplicate. No on-disk persistence.

`events` is handled in the IPC server like `tail` (not the dispatcher);
added to the argv umbrella set. bindingWhen/CommandContribution untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 21:24:34 +02:00
co-authored by Claude Opus 4.8
parent 1fefd26ef0
commit d6dccd841b
5 changed files with 291 additions and 3 deletions
+7
View File
@@ -94,6 +94,13 @@ void main() {
expect(_expectOk(parseArgv(['ping'], requestId: 'p')).cmd, 'ping');
expect(_expectOk(parseArgv(['version'], requestId: 'v')).cmd, 'version');
});
test('"events --since 5 --filter pane" parses to the events command (T-223)', () {
final req = _expectOk(parseArgv(['events', '--since', '5', '--filter', 'pane'], requestId: 'e'));
expect(req.cmd, 'events');
expect((req.args['flags'] as Map)['since'], '5');
expect((req.args['flags'] as Map)['filter'], 'pane');
});
});
group('parseArgv — errors', () {