@the-open-engine/zeroshot 6.10.2 → 6.12.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.
Files changed (76) hide show
  1. package/cli/commands/providers.js +13 -13
  2. package/cli/index.js +77 -35
  3. package/cli/lib/first-run.js +12 -11
  4. package/cli/lib/update-checker.js +517 -132
  5. package/lib/agent-cli-provider/adapters/opencode.d.ts.map +1 -1
  6. package/lib/agent-cli-provider/adapters/opencode.js +3 -0
  7. package/lib/agent-cli-provider/adapters/opencode.js.map +1 -1
  8. package/lib/agent-cli-provider/types.d.ts +1 -0
  9. package/lib/agent-cli-provider/types.d.ts.map +1 -1
  10. package/lib/agent-cli-provider/types.js.map +1 -1
  11. package/lib/cluster/client.cjs +146 -0
  12. package/lib/cluster/client.d.ts +44 -0
  13. package/lib/cluster/client.mjs +141 -0
  14. package/lib/cluster/connection.cjs +382 -0
  15. package/lib/cluster/connection.d.ts +41 -0
  16. package/lib/cluster/connection.mjs +378 -0
  17. package/lib/cluster/errors.cjs +44 -0
  18. package/lib/cluster/errors.d.ts +23 -0
  19. package/lib/cluster/errors.mjs +32 -0
  20. package/lib/cluster/frames.cjs +49 -0
  21. package/lib/cluster/frames.d.ts +12 -0
  22. package/lib/cluster/frames.mjs +45 -0
  23. package/lib/cluster/generated/protocol-schema.cjs +5 -0
  24. package/lib/cluster/generated/protocol-schema.d.ts +1 -0
  25. package/lib/cluster/generated/protocol-schema.mjs +2 -0
  26. package/lib/cluster/generated/protocol.cjs +22 -0
  27. package/lib/cluster/generated/protocol.d.ts +781 -0
  28. package/lib/cluster/generated/protocol.mjs +19 -0
  29. package/lib/cluster/index.cjs +40 -0
  30. package/lib/cluster/index.d.ts +10 -0
  31. package/lib/cluster/index.mjs +6 -0
  32. package/lib/cluster/queue.cjs +71 -0
  33. package/lib/cluster/queue.d.ts +15 -0
  34. package/lib/cluster/queue.mjs +67 -0
  35. package/lib/cluster/socket.cjs +15 -0
  36. package/lib/cluster/socket.d.ts +11 -0
  37. package/lib/cluster/socket.mjs +12 -0
  38. package/lib/cluster/subscriptions.cjs +270 -0
  39. package/lib/cluster/subscriptions.d.ts +69 -0
  40. package/lib/cluster/subscriptions.mjs +264 -0
  41. package/lib/cluster/validators.cjs +46 -0
  42. package/lib/cluster/validators.d.ts +3 -0
  43. package/lib/cluster/validators.mjs +42 -0
  44. package/lib/settings.js +195 -23
  45. package/lib/setup-apply.js +45 -32
  46. package/lib/setup-undo.js +25 -16
  47. package/package.json +25 -3
  48. package/scripts/build-cluster.js +43 -0
  49. package/scripts/generate-cluster-types.js +203 -0
  50. package/scripts/release-dry-run.js +6 -6
  51. package/scripts/rust-distribution.js +933 -0
  52. package/src/agent/agent-hook-executor.js +14 -6
  53. package/src/agent/agent-lifecycle.js +25 -8
  54. package/src/agent/agent-task-executor.js +711 -139
  55. package/src/agent/output-reformatter.js +54 -41
  56. package/src/agent/pr-verification.js +11 -3
  57. package/src/agent/task-execution-handle.js +373 -0
  58. package/src/agent-cli-provider/adapters/opencode.ts +3 -0
  59. package/src/agent-cli-provider/types.ts +1 -0
  60. package/src/agent-wrapper.js +5 -2
  61. package/src/cluster/client.ts +199 -0
  62. package/src/cluster/connection.ts +300 -0
  63. package/src/cluster/errors.ts +32 -0
  64. package/src/cluster/frames.ts +44 -0
  65. package/src/cluster/generated/protocol-schema.ts +2 -0
  66. package/src/cluster/generated/protocol.ts +183 -0
  67. package/src/cluster/index.ts +38 -0
  68. package/src/cluster/queue.ts +84 -0
  69. package/src/cluster/socket.ts +31 -0
  70. package/src/cluster/subscriptions.ts +256 -0
  71. package/src/cluster/validators.ts +56 -0
  72. package/src/cluster/ws.d.ts +7 -0
  73. package/src/isolation-manager.js +16 -0
  74. package/src/issue-providers/jira-provider.js +1 -1
  75. package/src/issue-providers/linear-provider.js +4 -4
  76. package/task-lib/runner.js +3 -0
@@ -0,0 +1,19 @@
1
+ // Generated by scripts/generate-cluster-types.js from the checked-in Cluster Protocol v1 artifacts.
2
+ // Do not edit this file by hand. Run npm run protocol:generate.
3
+ export const JSON_RPC_VERSION = "2.0";
4
+ export const PROTOCOL_VERSION = "openengine.cluster/v1";
5
+ export const SUBSCRIPTION_QUEUE_CAPACITY = 1024;
6
+ export const MAX_FRAME_BYTES = 1048576;
7
+ export const CLUSTER_METHODS = ["initialize", "plan", "apply", "update", "stop", "retry", "resubmit", "delete", "get", "watch", "logs", "agent/attach"];
8
+ export const UNARY_METHODS = ["initialize", "plan", "apply", "update", "stop", "retry", "resubmit", "delete", "get"];
9
+ export const SUBSCRIPTION_METHODS = ["watch", "logs", "agent/attach"];
10
+ export const METHOD_RESULT_DEFINITIONS = { "initialize": "InitializeResult", "plan": "PlanResult", "apply": "ApplyResult", "update": "UpdateResult", "stop": "StopResult", "retry": "RetryResult", "resubmit": "ResubmitResult", "delete": "DeleteResult", "get": "GetResult", "watch": "WatchResult", "logs": "LogsResult", "agent/attach": "AgentAttachResult" };
11
+ export const JSON_RPC_ERROR_CODES = {
12
+ PARSE_ERROR: -32700,
13
+ INVALID_REQUEST: -32600,
14
+ METHOD_NOT_FOUND: -32601,
15
+ INVALID_PARAMS: -32602,
16
+ INTERNAL_ERROR: -32603,
17
+ APPLICATION_ERROR: -32000,
18
+ };
19
+ export const DOMAIN_ERROR_CODES = ["NOT_FOUND", "GONE", "SLOW_CONSUMER", "UNSUPPORTED_PROTOCOL_VERSION", "INTERNAL_ERROR"];
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.connect = exports.ClusterClient = exports.WatchSubscriptionStream = exports.LogsSubscriptionStream = exports.AgentAttachSubscriptionStream = exports.Connection = exports.PROTOCOL_DIAGNOSTIC_CAPACITY = exports.CONNECTION_TRANSITIONS = exports.ClusterTransportError = exports.ClusterTimeoutError = exports.ClusterStateError = exports.ClusterRpcError = exports.ClusterProtocolError = exports.ClusterInternalError = exports.ClusterError = exports.ClusterConfigError = exports.SUBSCRIPTION_QUEUE_MAX_BYTES = void 0;
18
+ __exportStar(require("./generated/protocol.cjs"), exports);
19
+ var queue_js_1 = require("./queue.cjs");
20
+ Object.defineProperty(exports, "SUBSCRIPTION_QUEUE_MAX_BYTES", { enumerable: true, get: function () { return queue_js_1.SUBSCRIPTION_QUEUE_MAX_BYTES; } });
21
+ var errors_js_1 = require("./errors.cjs");
22
+ Object.defineProperty(exports, "ClusterConfigError", { enumerable: true, get: function () { return errors_js_1.ClusterConfigError; } });
23
+ Object.defineProperty(exports, "ClusterError", { enumerable: true, get: function () { return errors_js_1.ClusterError; } });
24
+ Object.defineProperty(exports, "ClusterInternalError", { enumerable: true, get: function () { return errors_js_1.ClusterInternalError; } });
25
+ Object.defineProperty(exports, "ClusterProtocolError", { enumerable: true, get: function () { return errors_js_1.ClusterProtocolError; } });
26
+ Object.defineProperty(exports, "ClusterRpcError", { enumerable: true, get: function () { return errors_js_1.ClusterRpcError; } });
27
+ Object.defineProperty(exports, "ClusterStateError", { enumerable: true, get: function () { return errors_js_1.ClusterStateError; } });
28
+ Object.defineProperty(exports, "ClusterTimeoutError", { enumerable: true, get: function () { return errors_js_1.ClusterTimeoutError; } });
29
+ Object.defineProperty(exports, "ClusterTransportError", { enumerable: true, get: function () { return errors_js_1.ClusterTransportError; } });
30
+ var connection_js_1 = require("./connection.cjs");
31
+ Object.defineProperty(exports, "CONNECTION_TRANSITIONS", { enumerable: true, get: function () { return connection_js_1.CONNECTION_TRANSITIONS; } });
32
+ Object.defineProperty(exports, "PROTOCOL_DIAGNOSTIC_CAPACITY", { enumerable: true, get: function () { return connection_js_1.PROTOCOL_DIAGNOSTIC_CAPACITY; } });
33
+ Object.defineProperty(exports, "Connection", { enumerable: true, get: function () { return connection_js_1.Connection; } });
34
+ var subscriptions_js_1 = require("./subscriptions.cjs");
35
+ Object.defineProperty(exports, "AgentAttachSubscriptionStream", { enumerable: true, get: function () { return subscriptions_js_1.AgentAttachSubscriptionStream; } });
36
+ Object.defineProperty(exports, "LogsSubscriptionStream", { enumerable: true, get: function () { return subscriptions_js_1.LogsSubscriptionStream; } });
37
+ Object.defineProperty(exports, "WatchSubscriptionStream", { enumerable: true, get: function () { return subscriptions_js_1.WatchSubscriptionStream; } });
38
+ var client_js_1 = require("./client.cjs");
39
+ Object.defineProperty(exports, "ClusterClient", { enumerable: true, get: function () { return client_js_1.ClusterClient; } });
40
+ Object.defineProperty(exports, "connect", { enumerable: true, get: function () { return client_js_1.connect; } });
@@ -0,0 +1,10 @@
1
+ export * from './generated/protocol.js';
2
+ export { SUBSCRIPTION_QUEUE_MAX_BYTES } from './queue.js';
3
+ export { ClusterConfigError, ClusterError, ClusterInternalError, ClusterProtocolError, ClusterRpcError, ClusterStateError, ClusterTimeoutError, ClusterTransportError, } from './errors.js';
4
+ export { CONNECTION_TRANSITIONS, PROTOCOL_DIAGNOSTIC_CAPACITY, Connection } from './connection.js';
5
+ export type { CallOptions, ConnectionState, } from './connection.js';
6
+ export type { WebSocketLike } from './socket.js';
7
+ export { AgentAttachSubscriptionStream, LogsSubscriptionStream, WatchSubscriptionStream, } from './subscriptions.js';
8
+ export type { Subscription, SubscriptionClosedItem, SubscriptionItem, WatchSubscriptionItem, WatchSubscriptionClosedItem, } from './subscriptions.js';
9
+ export { ClusterClient, connect } from './client.js';
10
+ export type { AgentAttachSubscription, CoherentWatchSubscription, ConnectOptions, LogsSubscription, WatchSubscription, } from './client.js';
@@ -0,0 +1,6 @@
1
+ export * from './generated/protocol.mjs';
2
+ export { SUBSCRIPTION_QUEUE_MAX_BYTES } from './queue.mjs';
3
+ export { ClusterConfigError, ClusterError, ClusterInternalError, ClusterProtocolError, ClusterRpcError, ClusterStateError, ClusterTimeoutError, ClusterTransportError, } from './errors.mjs';
4
+ export { CONNECTION_TRANSITIONS, PROTOCOL_DIAGNOSTIC_CAPACITY, Connection } from './connection.mjs';
5
+ export { AgentAttachSubscriptionStream, LogsSubscriptionStream, WatchSubscriptionStream, } from './subscriptions.mjs';
6
+ export { ClusterClient, connect } from './client.mjs';
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BoundedQueue = exports.SUBSCRIPTION_QUEUE_MAX_BYTES = void 0;
4
+ const protocol_js_1 = require("./generated/protocol.cjs");
5
+ const errors_js_1 = require("./errors.cjs");
6
+ exports.SUBSCRIPTION_QUEUE_MAX_BYTES = 8 * 1024 * 1024;
7
+ function deferred() {
8
+ let resolve;
9
+ const promise = new Promise((onResolve) => { resolve = onResolve; });
10
+ return { promise, resolve };
11
+ }
12
+ class BoundedQueue {
13
+ #items = [];
14
+ #waiters = [];
15
+ #bytes = 0;
16
+ #producerClosed = false;
17
+ get retainedCount() { return this.#items.length; }
18
+ push(value, bytes) {
19
+ if (this.#producerClosed)
20
+ return 'closed';
21
+ const waiter = this.#waiters.shift();
22
+ if (waiter) {
23
+ waiter.resolve({ done: false, value });
24
+ this.#assertInvariant();
25
+ return 'delivered';
26
+ }
27
+ if (this.#items.length >= protocol_js_1.SUBSCRIPTION_QUEUE_CAPACITY ||
28
+ this.#bytes + bytes > exports.SUBSCRIPTION_QUEUE_MAX_BYTES)
29
+ return 'overflow';
30
+ this.#items.push({ value, bytes });
31
+ this.#bytes += bytes;
32
+ this.#assertInvariant();
33
+ return 'buffered';
34
+ }
35
+ recv() {
36
+ const item = this.#items.shift();
37
+ if (item) {
38
+ this.#bytes -= item.bytes;
39
+ this.#assertInvariant();
40
+ return Promise.resolve({ done: false, value: item.value });
41
+ }
42
+ if (this.#producerClosed)
43
+ return Promise.resolve({ done: true });
44
+ const waiter = deferred();
45
+ this.#waiters.push(waiter);
46
+ this.#assertInvariant();
47
+ return waiter.promise;
48
+ }
49
+ endRetainingBuffer() {
50
+ if (this.#producerClosed)
51
+ return;
52
+ this.#producerClosed = true;
53
+ while (this.#waiters.length > 0)
54
+ this.#waiters.shift().resolve({ done: true });
55
+ this.#assertInvariant();
56
+ }
57
+ closeAndDiscard() {
58
+ this.#producerClosed = true;
59
+ this.#items.length = 0;
60
+ this.#bytes = 0;
61
+ while (this.#waiters.length > 0)
62
+ this.#waiters.shift().resolve({ done: true });
63
+ this.#assertInvariant();
64
+ }
65
+ #assertInvariant() {
66
+ if (this.#items.length > 0 && this.#waiters.length > 0) {
67
+ throw new errors_js_1.ClusterInternalError('queue contains both buffered items and waiters', 'QUEUE_INVARIANT');
68
+ }
69
+ }
70
+ }
71
+ exports.BoundedQueue = BoundedQueue;
@@ -0,0 +1,15 @@
1
+ export declare const SUBSCRIPTION_QUEUE_MAX_BYTES: number;
2
+ export type QueueValue<T> = {
3
+ readonly done: false;
4
+ readonly value: T;
5
+ } | {
6
+ readonly done: true;
7
+ };
8
+ export declare class BoundedQueue<T> {
9
+ #private;
10
+ get retainedCount(): number;
11
+ push(value: T, bytes: number): 'buffered' | 'delivered' | 'overflow' | 'closed';
12
+ recv(): Promise<QueueValue<T>>;
13
+ endRetainingBuffer(): void;
14
+ closeAndDiscard(): void;
15
+ }
@@ -0,0 +1,67 @@
1
+ import { SUBSCRIPTION_QUEUE_CAPACITY } from './generated/protocol.mjs';
2
+ import { ClusterInternalError } from './errors.mjs';
3
+ export const SUBSCRIPTION_QUEUE_MAX_BYTES = 8 * 1024 * 1024;
4
+ function deferred() {
5
+ let resolve;
6
+ const promise = new Promise((onResolve) => { resolve = onResolve; });
7
+ return { promise, resolve };
8
+ }
9
+ export class BoundedQueue {
10
+ #items = [];
11
+ #waiters = [];
12
+ #bytes = 0;
13
+ #producerClosed = false;
14
+ get retainedCount() { return this.#items.length; }
15
+ push(value, bytes) {
16
+ if (this.#producerClosed)
17
+ return 'closed';
18
+ const waiter = this.#waiters.shift();
19
+ if (waiter) {
20
+ waiter.resolve({ done: false, value });
21
+ this.#assertInvariant();
22
+ return 'delivered';
23
+ }
24
+ if (this.#items.length >= SUBSCRIPTION_QUEUE_CAPACITY ||
25
+ this.#bytes + bytes > SUBSCRIPTION_QUEUE_MAX_BYTES)
26
+ return 'overflow';
27
+ this.#items.push({ value, bytes });
28
+ this.#bytes += bytes;
29
+ this.#assertInvariant();
30
+ return 'buffered';
31
+ }
32
+ recv() {
33
+ const item = this.#items.shift();
34
+ if (item) {
35
+ this.#bytes -= item.bytes;
36
+ this.#assertInvariant();
37
+ return Promise.resolve({ done: false, value: item.value });
38
+ }
39
+ if (this.#producerClosed)
40
+ return Promise.resolve({ done: true });
41
+ const waiter = deferred();
42
+ this.#waiters.push(waiter);
43
+ this.#assertInvariant();
44
+ return waiter.promise;
45
+ }
46
+ endRetainingBuffer() {
47
+ if (this.#producerClosed)
48
+ return;
49
+ this.#producerClosed = true;
50
+ while (this.#waiters.length > 0)
51
+ this.#waiters.shift().resolve({ done: true });
52
+ this.#assertInvariant();
53
+ }
54
+ closeAndDiscard() {
55
+ this.#producerClosed = true;
56
+ this.#items.length = 0;
57
+ this.#bytes = 0;
58
+ while (this.#waiters.length > 0)
59
+ this.#waiters.shift().resolve({ done: true });
60
+ this.#assertInvariant();
61
+ }
62
+ #assertInvariant() {
63
+ if (this.#items.length > 0 && this.#waiters.length > 0) {
64
+ throw new ClusterInternalError('queue contains both buffered items and waiters', 'QUEUE_INVARIANT');
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addSocketListener = addSocketListener;
4
+ const errors_js_1 = require("./errors.cjs");
5
+ function addSocketListener(socket, type, listener) {
6
+ if (socket.addEventListener) {
7
+ socket.addEventListener(type, listener);
8
+ return () => socket.removeEventListener?.(type, listener);
9
+ }
10
+ if (socket.on) {
11
+ socket.on(type, listener);
12
+ return () => (socket.off ?? socket.removeListener)?.call(socket, type, listener);
13
+ }
14
+ throw new errors_js_1.ClusterConfigError('WebSocket implementation must support event listeners', 'INVALID_WEBSOCKET');
15
+ }
@@ -0,0 +1,11 @@
1
+ export interface WebSocketLike {
2
+ readonly readyState: number;
3
+ send(data: string, callback?: (error?: Error) => void): void | Promise<void>;
4
+ close(code?: number, reason?: string): void | Promise<void>;
5
+ addEventListener?(type: string, listener: (...args: unknown[]) => void): void;
6
+ removeEventListener?(type: string, listener: (...args: unknown[]) => void): void;
7
+ on?(type: string, listener: (...args: unknown[]) => void): void;
8
+ off?(type: string, listener: (...args: unknown[]) => void): void;
9
+ removeListener?(type: string, listener: (...args: unknown[]) => void): void;
10
+ }
11
+ export declare function addSocketListener(socket: WebSocketLike, type: string, listener: (...args: unknown[]) => void): () => void;
@@ -0,0 +1,12 @@
1
+ import { ClusterConfigError } from './errors.mjs';
2
+ export function addSocketListener(socket, type, listener) {
3
+ if (socket.addEventListener) {
4
+ socket.addEventListener(type, listener);
5
+ return () => socket.removeEventListener?.(type, listener);
6
+ }
7
+ if (socket.on) {
8
+ socket.on(type, listener);
9
+ return () => (socket.off ?? socket.removeListener)?.call(socket, type, listener);
10
+ }
11
+ throw new ClusterConfigError('WebSocket implementation must support event listeners', 'INVALID_WEBSOCKET');
12
+ }
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.WatchSubscriptionStream = exports.AgentAttachSubscriptionStream = exports.LogsSubscriptionStream = void 0;
5
+ const errors_js_1 = require("./errors.cjs");
6
+ const frames_js_1 = require("./frames.cjs");
7
+ const validators_js_1 = require("./validators.cjs");
8
+ class SubscriptionStream {
9
+ connection;
10
+ registration;
11
+ parse;
12
+ #done = false;
13
+ constructor(connection, registration, parse) {
14
+ this.connection = connection;
15
+ this.registration = registration;
16
+ this.parse = parse;
17
+ }
18
+ get subscriptionId() { return this.registration.id; }
19
+ get retainedCount() { return this.registration.queue.retainedCount; }
20
+ [Symbol.asyncIterator]() { return this; }
21
+ async next() {
22
+ if (this.#done)
23
+ return { done: true, value: undefined };
24
+ const queued = await this.registration.queue.recv();
25
+ if (queued.done) {
26
+ if (this.registration.overflowed) {
27
+ this.registration.overflowed = false;
28
+ this.#done = true;
29
+ return { done: false, value: { type: 'closed', reason: 'SLOW_CONSUMER' } };
30
+ }
31
+ this.#done = true;
32
+ return { done: true, value: undefined };
33
+ }
34
+ try {
35
+ const value = this.parse(queued.value);
36
+ if (value.type === 'closed')
37
+ this.#finishWithoutCancel();
38
+ return { done: false, value };
39
+ }
40
+ catch (cause) {
41
+ await this.#terminate(true);
42
+ throw cause;
43
+ }
44
+ }
45
+ async return() {
46
+ await this.#terminate(true);
47
+ return { done: true, value: undefined };
48
+ }
49
+ async throw(error) {
50
+ await this.#terminate(true);
51
+ throw error;
52
+ }
53
+ cancel() { return this.#terminate(true); }
54
+ async #terminate(sendCancel) {
55
+ if (this.#done)
56
+ return;
57
+ this.#done = true;
58
+ this.connection.unregisterSubscription(this.registration.id, this.registration);
59
+ this.registration.queue.closeAndDiscard();
60
+ if (sendCancel) {
61
+ try {
62
+ await this.connection.cancelSubscription(this.registration);
63
+ }
64
+ catch (error) {
65
+ this.connection.recordDiagnostic(error);
66
+ }
67
+ }
68
+ }
69
+ #finishWithoutCancel() {
70
+ if (this.#done)
71
+ return;
72
+ this.#done = true;
73
+ this.connection.unregisterSubscription(this.registration.id, this.registration);
74
+ this.registration.queue.closeAndDiscard();
75
+ }
76
+ }
77
+ function parseCursorlessClosed(params, definition) {
78
+ (0, validators_js_1.assertDefinition)(definition, params);
79
+ return { type: 'closed', reason: params.reason };
80
+ }
81
+ function parseWatchClosed(params) {
82
+ (0, validators_js_1.assertDefinition)('SubscriptionClosedNotification', params);
83
+ const cursor = params.lastDeliveredCursor;
84
+ return {
85
+ type: 'closed',
86
+ reason: params.reason,
87
+ ...(cursor === undefined ? {} : { lastDeliveredCursor: cursor }),
88
+ };
89
+ }
90
+ function subscriptionParser(field, eventDefinition, closedDefinition) {
91
+ return (frame) => {
92
+ if (!(0, frames_js_1.isRecord)(frame.params)) {
93
+ throw new errors_js_1.ClusterProtocolError('notification params are missing', 'INVALID_SUBSCRIPTION_EVENT');
94
+ }
95
+ if (frame.method === 'subscription/closed') {
96
+ return parseCursorlessClosed(frame.params, closedDefinition);
97
+ }
98
+ if (frame.method !== 'event') {
99
+ throw new errors_js_1.ClusterProtocolError('malformed subscription event', 'INVALID_SUBSCRIPTION_EVENT');
100
+ }
101
+ (0, validators_js_1.assertDefinition)(eventDefinition, frame.params);
102
+ return { type: 'event', event: frame.params[field] };
103
+ };
104
+ }
105
+ class LogsSubscriptionStream extends SubscriptionStream {
106
+ constructor(connection, registration) {
107
+ super(connection, registration, subscriptionParser('record', 'LogEventNotification', 'LogsClosedNotification'));
108
+ }
109
+ }
110
+ exports.LogsSubscriptionStream = LogsSubscriptionStream;
111
+ class AgentAttachSubscriptionStream extends SubscriptionStream {
112
+ constructor(connection, registration) {
113
+ super(connection, registration, subscriptionParser('event', 'AgentAttachEventNotification', 'AgentAttachClosedNotification'));
114
+ }
115
+ }
116
+ exports.AgentAttachSubscriptionStream = AgentAttachSubscriptionStream;
117
+ class WatchSubscriptionStream {
118
+ #connection;
119
+ #registration;
120
+ #lastSeenRunId;
121
+ #lastSeenCursor;
122
+ #lastDelivered;
123
+ #runId;
124
+ #done = false;
125
+ #reconnectConsumed = false;
126
+ #readBarrier = Promise.resolve();
127
+ constructor(init) {
128
+ this.#connection = init.connection;
129
+ this.#registration = init.registration;
130
+ this.#lastSeenRunId = init.lastSeenRunId;
131
+ this.#lastSeenCursor = init.lastSeenCursor;
132
+ this.#lastDelivered = init.params.fromCursor;
133
+ this.#runId = init.result.runId ?? init.params.runId;
134
+ }
135
+ get subscriptionId() { return this.#registration.id; }
136
+ get retainedCount() { return this.#registration.queue.retainedCount; }
137
+ get lastDeliveredCursor() { return this.#lastDelivered; }
138
+ [Symbol.asyncIterator]() { return this; }
139
+ next() {
140
+ const read = this.#readBarrier.then(() => this.#nextLogical());
141
+ this.#readBarrier = read.then(() => undefined, () => undefined);
142
+ return read;
143
+ }
144
+ async #nextLogical() {
145
+ while (!this.#done) {
146
+ const queued = await this.#registration.queue.recv();
147
+ if (queued.done)
148
+ return this.#finishQueue();
149
+ const item = await this.#decode(queued.value);
150
+ if (item)
151
+ return { done: false, value: item };
152
+ }
153
+ return { done: true, value: undefined };
154
+ }
155
+ #finishQueue() {
156
+ this.#done = true;
157
+ if (!this.#registration.overflowed)
158
+ return { done: true, value: undefined };
159
+ this.#registration.overflowed = false;
160
+ const cursor = this.#lastDelivered;
161
+ return {
162
+ done: false,
163
+ value: { type: 'closed', reason: 'SLOW_CONSUMER', ...(cursor === undefined ? {} : { lastDeliveredCursor: cursor }) },
164
+ };
165
+ }
166
+ async #decode(frame) {
167
+ if (!(0, frames_js_1.isRecord)(frame.params))
168
+ return this.#invalid('notification params are missing');
169
+ if (frame.method === 'subscription/closed') {
170
+ const closed = parseWatchClosed(frame.params);
171
+ if (closed.lastDeliveredCursor !== undefined)
172
+ this.#lastDelivered = closed.lastDeliveredCursor;
173
+ this.#finishWithoutCancel();
174
+ return closed;
175
+ }
176
+ if (frame.method !== 'event')
177
+ return this.#invalid('malformed watch event');
178
+ try {
179
+ (0, validators_js_1.assertDefinition)('EventNotification', frame.params);
180
+ }
181
+ catch {
182
+ return this.#invalid('malformed watch event');
183
+ }
184
+ const { runId, cursor, event } = frame.params;
185
+ if (this.#lastSeenRunId === runId && this.#lastSeenCursor === cursor)
186
+ return undefined;
187
+ this.#lastSeenRunId = runId;
188
+ this.#lastSeenCursor = cursor;
189
+ this.#runId = runId;
190
+ this.#lastDelivered = cursor;
191
+ return { type: 'event', runId, cursor, event };
192
+ }
193
+ async return() {
194
+ await this.#terminate(true);
195
+ return { done: true, value: undefined };
196
+ }
197
+ async throw(error) {
198
+ await this.#terminate(true);
199
+ throw error;
200
+ }
201
+ cancel() { return this.#terminate(true); }
202
+ reconnect(freshConnection) {
203
+ if (this.#reconnectConsumed) {
204
+ throw new errors_js_1.ClusterStateError('watch stream reconnect is one-shot', 'RECONNECT_CONSUMED');
205
+ }
206
+ this.#reconnectConsumed = true;
207
+ return this.#reconnectOn(freshConnection);
208
+ }
209
+ async #reconnectOn(freshConnection) {
210
+ await this.#terminate(true);
211
+ try {
212
+ const runId = this.#runId;
213
+ const fromCursor = this.#lastDelivered;
214
+ const params = {
215
+ ...(runId === undefined ? {} : { runId }),
216
+ ...(fromCursor === undefined ? {} : { fromCursor }),
217
+ };
218
+ const established = await freshConnection.openSubscription('watch', params);
219
+ return {
220
+ result: established.result,
221
+ stream: new _a({
222
+ connection: freshConnection,
223
+ registration: established.registration,
224
+ result: established.result,
225
+ params,
226
+ ...(this.#lastSeenRunId === undefined ? {} : { lastSeenRunId: this.#lastSeenRunId }),
227
+ ...(this.#lastSeenCursor === undefined ? {} : { lastSeenCursor: this.#lastSeenCursor }),
228
+ }),
229
+ };
230
+ }
231
+ catch (error) {
232
+ await freshConnection.close();
233
+ throw error;
234
+ }
235
+ }
236
+ async #terminate(sendCancel) {
237
+ if (this.#done)
238
+ return;
239
+ this.#done = true;
240
+ this.#connection.unregisterSubscription(this.#registration.id, this.#registration);
241
+ this.#registration.queue.closeAndDiscard();
242
+ if (sendCancel) {
243
+ try {
244
+ await this.#connection.cancelSubscription(this.#registration);
245
+ }
246
+ catch (error) {
247
+ this.#connection.recordDiagnostic(error);
248
+ }
249
+ }
250
+ }
251
+ #finishWithoutCancel() {
252
+ if (this.#done)
253
+ return;
254
+ this.#done = true;
255
+ this.#connection.unregisterSubscription(this.#registration.id, this.#registration);
256
+ this.#registration.queue.closeAndDiscard();
257
+ }
258
+ async #invalid(message) {
259
+ await this.#terminate(true);
260
+ throw new errors_js_1.ClusterProtocolError(message, 'INVALID_SUBSCRIPTION_EVENT');
261
+ }
262
+ }
263
+ exports.WatchSubscriptionStream = WatchSubscriptionStream;
264
+ _a = WatchSubscriptionStream;
265
+ Object.defineProperty(SubscriptionStream.prototype, Symbol.asyncDispose, {
266
+ configurable: true, value: SubscriptionStream.prototype.cancel,
267
+ });
268
+ Object.defineProperty(WatchSubscriptionStream.prototype, Symbol.asyncDispose, {
269
+ configurable: true, value: WatchSubscriptionStream.prototype.cancel,
270
+ });
@@ -0,0 +1,69 @@
1
+ import type { AgentAttachEvent, LogRecord, SubscriptionCloseReason, WatchEvent, WatchParams, WatchResult } from './generated/protocol.js';
2
+ import { Connection } from './connection.js';
3
+ import type { SubscriptionRegistration } from './connection.js';
4
+ import type { FrameRecord } from './frames.js';
5
+ export type SubscriptionClosedItem = {
6
+ readonly type: 'closed';
7
+ readonly reason: SubscriptionCloseReason;
8
+ };
9
+ export type WatchSubscriptionClosedItem = SubscriptionClosedItem & {
10
+ readonly lastDeliveredCursor?: string | null;
11
+ };
12
+ export type SubscriptionItem<T> = {
13
+ readonly type: 'event';
14
+ readonly event: T;
15
+ } | SubscriptionClosedItem;
16
+ export type WatchSubscriptionItem = {
17
+ readonly type: 'event';
18
+ readonly runId: string;
19
+ readonly cursor: string;
20
+ readonly event: WatchEvent;
21
+ } | WatchSubscriptionClosedItem;
22
+ export interface Subscription<T> extends AsyncIterator<SubscriptionItem<T>>, AsyncIterable<SubscriptionItem<T>> {
23
+ readonly subscriptionId: string;
24
+ readonly retainedCount: number;
25
+ cancel(): Promise<void>;
26
+ }
27
+ type FrameParser<T> = (frame: FrameRecord) => SubscriptionItem<T>;
28
+ declare class SubscriptionStream<T> implements Subscription<T> {
29
+ #private;
30
+ protected readonly connection: Connection;
31
+ protected readonly registration: SubscriptionRegistration;
32
+ private readonly parse;
33
+ constructor(connection: Connection, registration: SubscriptionRegistration, parse: FrameParser<T>);
34
+ get subscriptionId(): string;
35
+ get retainedCount(): number;
36
+ [Symbol.asyncIterator](): this;
37
+ next(): Promise<IteratorResult<SubscriptionItem<T>>>;
38
+ return(): Promise<IteratorResult<SubscriptionItem<T>>>;
39
+ throw(error?: unknown): Promise<IteratorResult<SubscriptionItem<T>>>;
40
+ cancel(): Promise<void>;
41
+ }
42
+ export declare class LogsSubscriptionStream extends SubscriptionStream<LogRecord> {
43
+ constructor(connection: Connection, registration: SubscriptionRegistration);
44
+ }
45
+ export declare class AgentAttachSubscriptionStream extends SubscriptionStream<AgentAttachEvent> {
46
+ constructor(connection: Connection, registration: SubscriptionRegistration);
47
+ }
48
+ type WatchStreamInit = {
49
+ readonly connection: Connection;
50
+ readonly registration: SubscriptionRegistration;
51
+ readonly result: WatchResult;
52
+ readonly params: WatchParams;
53
+ readonly lastSeenRunId?: string;
54
+ readonly lastSeenCursor?: string;
55
+ };
56
+ export declare class WatchSubscriptionStream implements AsyncIterator<WatchSubscriptionItem>, AsyncIterable<WatchSubscriptionItem> {
57
+ #private;
58
+ constructor(init: WatchStreamInit);
59
+ get subscriptionId(): string;
60
+ get retainedCount(): number;
61
+ get lastDeliveredCursor(): string | null | undefined;
62
+ [Symbol.asyncIterator](): this;
63
+ next(): Promise<IteratorResult<WatchSubscriptionItem>>;
64
+ return(): Promise<IteratorResult<WatchSubscriptionItem>>;
65
+ throw(error?: unknown): Promise<IteratorResult<WatchSubscriptionItem>>;
66
+ cancel(): Promise<void>;
67
+ reconnect(freshConnection: Connection): Promise<import('./client.js').WatchSubscription>;
68
+ }
69
+ export {};