@ours.network/fleet 1.2.0-nightly.70 → 1.2.0-nightly.71
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/application/conversation-history.d.ts +7 -0
- package/dist/application/conversation-history.js +65 -0
- package/dist/application/fleet-query-service.d.ts +1 -1
- package/dist/application/fleet-query-service.js +2 -2
- package/dist/application/resource-observer.d.ts +40 -0
- package/dist/application/resource-observer.js +278 -0
- package/dist/application/role-repository.d.ts +1 -1
- package/dist/application/role-repository.js +11 -5
- package/dist/application/task-layouts.js +2 -0
- package/dist/application/task-room-service.d.ts +2 -0
- package/dist/application/task-room-service.js +2 -2
- package/dist/build-info.json +4 -4
- package/dist/daemon-recovery.d.ts +13 -1
- package/dist/daemon-recovery.js +117 -3
- package/dist/monitor.d.ts +1 -0
- package/dist/monitor.js +1 -1
- package/dist/notifications/fleet-producer.d.ts +4 -1
- package/dist/notifications/fleet-producer.js +36 -7
- package/dist/notifications/target-cleanup.d.ts +1 -0
- package/dist/notifications/target-cleanup.js +1 -1
- package/dist/notifications/task-producer.d.ts +3 -1
- package/dist/notifications/task-producer.js +38 -5
- package/dist/rooms-tasks/add-member.js +2 -1
- package/dist/rooms-tasks/layout.js +2 -1
- package/dist/rooms-tasks/task-state.d.ts +1 -0
- package/dist/rooms-tasks/task-state.js +6 -1
- package/dist/runner.js +22 -7
- package/dist/subscriptions/login.d.ts +4 -3
- package/dist/subscriptions/login.js +14 -6
- package/dist/subscriptions/service.d.ts +1 -1
- package/dist/subscriptions/service.js +4 -4
- package/dist/subscriptions/store.js +3 -0
- package/dist/watchdog/query.d.ts +3 -1
- package/dist/watchdog/query.js +2 -1
- package/dist/web/events.d.ts +2 -0
- package/dist/web/events.js +9 -0
- package/dist/web/prefix-gateway.js +20 -10
- package/dist/web/resource-views.d.ts +124 -0
- package/dist/web/resource-views.js +424 -0
- package/dist/web/runtime.js +4 -1
- package/dist/web/server.d.ts +3 -0
- package/dist/web/server.js +170 -19
- package/docs/conversation-stream.md +6 -0
- package/package.json +1 -1
|
@@ -26,6 +26,7 @@ class BaseLogin {
|
|
|
26
26
|
provider;
|
|
27
27
|
owner;
|
|
28
28
|
kind;
|
|
29
|
+
changed;
|
|
29
30
|
loginId = randomBytes(16).toString('hex');
|
|
30
31
|
expiresAt;
|
|
31
32
|
state = 'starting';
|
|
@@ -35,10 +36,11 @@ class BaseLogin {
|
|
|
35
36
|
done;
|
|
36
37
|
finish;
|
|
37
38
|
timer;
|
|
38
|
-
constructor(provider, owner, kind, now = Date.now()) {
|
|
39
|
+
constructor(provider, owner, kind, now = Date.now(), changed = () => { }) {
|
|
39
40
|
this.provider = provider;
|
|
40
41
|
this.owner = owner;
|
|
41
42
|
this.kind = kind;
|
|
43
|
+
this.changed = changed;
|
|
42
44
|
this.expiresAt = now + LOGIN_TTL_MS;
|
|
43
45
|
this.done = new Promise(resolve => { this.finish = resolve; });
|
|
44
46
|
this.timer = setTimeout(() => this.end('expired', 'login timed out'), LOGIN_TTL_MS);
|
|
@@ -64,6 +66,7 @@ class BaseLogin {
|
|
|
64
66
|
clearTimeout(this.timer);
|
|
65
67
|
this.stop();
|
|
66
68
|
this.finish(state === 'succeeded');
|
|
69
|
+
this.changed();
|
|
67
70
|
}
|
|
68
71
|
/** Called by the service after verifying the new home. */
|
|
69
72
|
complete(ok, error) { this.end(ok ? 'succeeded' : 'failed', error); }
|
|
@@ -76,8 +79,8 @@ export class ClaudeLogin extends BaseLogin {
|
|
|
76
79
|
continued = false;
|
|
77
80
|
/** Resolves with the CLI exit status once it exits. */
|
|
78
81
|
exited;
|
|
79
|
-
constructor(owner, bins, home, profileId) {
|
|
80
|
-
super('claude', owner, 'paste_code');
|
|
82
|
+
constructor(owner, bins, home, profileId, changed) {
|
|
83
|
+
super('claude', owner, 'paste_code', Date.now(), changed);
|
|
81
84
|
const darwin = process.platform === 'darwin';
|
|
82
85
|
const args = darwin
|
|
83
86
|
? ['-q', '/dev/null', bins.claude, 'auth', 'login']
|
|
@@ -109,6 +112,7 @@ export class ClaudeLogin extends BaseLogin {
|
|
|
109
112
|
}
|
|
110
113
|
this.url = url;
|
|
111
114
|
this.state = 'awaiting_user';
|
|
115
|
+
this.changed();
|
|
112
116
|
}
|
|
113
117
|
}
|
|
114
118
|
// Claude asks for Enter after success; the answer carries no secret.
|
|
@@ -131,6 +135,7 @@ export class ClaudeLogin extends BaseLogin {
|
|
|
131
135
|
throw new FleetError('invalid_request', 'that does not look like a sign-in code');
|
|
132
136
|
this.submitted = true;
|
|
133
137
|
this.state = 'verifying';
|
|
138
|
+
this.changed();
|
|
134
139
|
this.output = '';
|
|
135
140
|
this.child?.stdin.write(`${code}\r`);
|
|
136
141
|
}
|
|
@@ -151,8 +156,8 @@ export class CodexDeviceLogin extends BaseLogin {
|
|
|
151
156
|
codexLoginId;
|
|
152
157
|
/** Resolves true when the app-server reports a successful login. */
|
|
153
158
|
completed;
|
|
154
|
-
constructor(owner, bins, home, profileId) {
|
|
155
|
-
super('codex', owner, 'device_code');
|
|
159
|
+
constructor(owner, bins, home, profileId, changed) {
|
|
160
|
+
super('codex', owner, 'device_code', Date.now(), changed);
|
|
156
161
|
this.completed = (async () => {
|
|
157
162
|
try {
|
|
158
163
|
this.server = await CodexAppServer.start(bins.codex, profileEnv('CODEX_HOME', profileId, home));
|
|
@@ -184,9 +189,12 @@ export class CodexDeviceLogin extends BaseLogin {
|
|
|
184
189
|
this.url = url;
|
|
185
190
|
this.userCode = String(started.userCode).slice(0, 32);
|
|
186
191
|
this.state = 'awaiting_user';
|
|
192
|
+
this.changed();
|
|
187
193
|
const ok = await Promise.race([completion, this.done.then(() => false)]);
|
|
188
|
-
if (this.state === 'awaiting_user')
|
|
194
|
+
if (this.state === 'awaiting_user') {
|
|
189
195
|
this.state = 'verifying';
|
|
196
|
+
this.changed();
|
|
197
|
+
}
|
|
190
198
|
return ok;
|
|
191
199
|
}
|
|
192
200
|
catch {
|
|
@@ -71,7 +71,7 @@ export declare class SubscriptionService {
|
|
|
71
71
|
private readonly logins;
|
|
72
72
|
private readonly probes;
|
|
73
73
|
constructor(options: SubscriptionServiceOptions);
|
|
74
|
-
list(): Promise<ProviderView[]>;
|
|
74
|
+
list(observeOnly?: boolean): Promise<ProviderView[]>;
|
|
75
75
|
/** Health + account + (Codex) usage for one profile. Concurrent calls share one run. */
|
|
76
76
|
check(provider: SubscriptionProvider, profileId: string): Promise<CheckResult>;
|
|
77
77
|
private checkClaude;
|
|
@@ -23,7 +23,7 @@ export class SubscriptionService {
|
|
|
23
23
|
this.bins = options.binaries ?? defaultBinaries();
|
|
24
24
|
this.now = options.now ?? Date.now;
|
|
25
25
|
}
|
|
26
|
-
async list() {
|
|
26
|
+
async list(observeOnly = false) {
|
|
27
27
|
const state = readSubscriptionState();
|
|
28
28
|
const pins = await this.pins();
|
|
29
29
|
return SUBSCRIPTION_PROVIDERS.map(provider => {
|
|
@@ -31,7 +31,7 @@ export class SubscriptionService {
|
|
|
31
31
|
const profiles = p.profiles.map(profile => {
|
|
32
32
|
const key = `${provider}/${profile.id}`;
|
|
33
33
|
const cached = this.checks.get(key);
|
|
34
|
-
if (!cached || this.now() - Date.parse(cached.health.checkedAt ?? '0') > STALE_CHECK_MS)
|
|
34
|
+
if (!observeOnly && (!cached || this.now() - Date.parse(cached.health.checkedAt ?? '0') > STALE_CHECK_MS))
|
|
35
35
|
void this.check(provider, profile.id).catch(() => { });
|
|
36
36
|
const observed = provider === 'claude' ? this.observedUsage(pins, profile.id) : undefined;
|
|
37
37
|
const probed = provider === 'claude' ? this.probedUsage(profile.id) : undefined;
|
|
@@ -135,8 +135,8 @@ export class SubscriptionService {
|
|
|
135
135
|
}
|
|
136
136
|
const { id: profileId, home } = createProfileHome(provider);
|
|
137
137
|
const login = provider === 'claude'
|
|
138
|
-
? new ClaudeLogin(owner, this.bins, home, profileId)
|
|
139
|
-
: new CodexDeviceLogin(owner, this.bins, home, profileId);
|
|
138
|
+
? new ClaudeLogin(owner, this.bins, home, profileId, this.options.onChange)
|
|
139
|
+
: new CodexDeviceLogin(owner, this.bins, home, profileId, this.options.onChange);
|
|
140
140
|
const loginId = login.view().loginId;
|
|
141
141
|
this.logins.set(loginId, login);
|
|
142
142
|
void this.completeLogin(provider, profileId, login);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { publishFleetResourceCommit } from '../application/resource-observer.js';
|
|
1
2
|
import { existsSync, mkdirSync, readFileSync, rmSync, symlinkSync } from 'node:fs';
|
|
2
3
|
import { randomBytes } from 'node:crypto';
|
|
3
4
|
import { join } from 'node:path';
|
|
@@ -94,6 +95,7 @@ export async function updateSubscriptionState(fn) {
|
|
|
94
95
|
const state = readSubscriptionState();
|
|
95
96
|
const result = fn(state);
|
|
96
97
|
replaceFileAtomically(stateFile(), `${JSON.stringify(state, null, 2)}\n`, 0o600);
|
|
98
|
+
publishFleetResourceCommit(stateFile());
|
|
97
99
|
return result;
|
|
98
100
|
});
|
|
99
101
|
}
|
|
@@ -137,4 +139,5 @@ export function readPin(stateDir, provider) {
|
|
|
137
139
|
}
|
|
138
140
|
export function writePin(stateDir, pin) {
|
|
139
141
|
replaceFileAtomically(join(stateDir, PIN_FILE), `${JSON.stringify({ [pin.provider]: pin })}\n`, 0o600);
|
|
142
|
+
publishFleetResourceCommit(join(stateDir, PIN_FILE));
|
|
140
143
|
}
|
package/dist/watchdog/query.d.ts
CHANGED
|
@@ -39,7 +39,9 @@ export declare function buildWatchdogFindings(cfg: {
|
|
|
39
39
|
* polling. `now` is injectable (defaults to Date.now) so the TTL boundary is
|
|
40
40
|
* unit-testable without real timers.
|
|
41
41
|
*/
|
|
42
|
-
export declare function cachedWatchdogFindingsProvider(build: () => Map<string, WatchdogRoleFinding>, ttlMs: number, now?: () => number): () => Map<string, WatchdogRoleFinding
|
|
42
|
+
export declare function cachedWatchdogFindingsProvider(build: () => Map<string, WatchdogRoleFinding>, ttlMs: number, now?: () => number): (() => Map<string, WatchdogRoleFinding>) & {
|
|
43
|
+
invalidate: () => void;
|
|
44
|
+
};
|
|
43
45
|
export interface WatchdogSummary {
|
|
44
46
|
name: string;
|
|
45
47
|
enabled: boolean;
|
package/dist/watchdog/query.js
CHANGED
|
@@ -59,12 +59,13 @@ export function buildWatchdogFindings(cfg, latestReport) {
|
|
|
59
59
|
*/
|
|
60
60
|
export function cachedWatchdogFindingsProvider(build, ttlMs, now = Date.now) {
|
|
61
61
|
let cached;
|
|
62
|
-
|
|
62
|
+
const read = () => {
|
|
63
63
|
const at = now();
|
|
64
64
|
if (!cached || at - cached.at >= ttlMs)
|
|
65
65
|
cached = { at, value: build() };
|
|
66
66
|
return cached.value;
|
|
67
67
|
};
|
|
68
|
+
return Object.assign(read, { invalidate: () => { cached = undefined; } });
|
|
68
69
|
}
|
|
69
70
|
const DEFAULT_REPORTS_LIMIT = 50;
|
|
70
71
|
const MAX_REPORTS_LIMIT = 500;
|
package/dist/web/events.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface FleetEvent {
|
|
|
8
8
|
}
|
|
9
9
|
export declare class FleetEventBus {
|
|
10
10
|
private readonly events;
|
|
11
|
+
private readonly resourceListeners;
|
|
12
|
+
subscribeResources(listener: () => void): () => void;
|
|
11
13
|
private readonly clients;
|
|
12
14
|
publish(kind: string, payload: unknown, roleId?: string): FleetEvent;
|
|
13
15
|
attach(socket: WebSocket, lastEventId?: string): () => void;
|
package/dist/web/events.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
export class FleetEventBus {
|
|
3
3
|
events = [];
|
|
4
|
+
resourceListeners = new Set();
|
|
5
|
+
subscribeResources(listener) { this.resourceListeners.add(listener); return () => { this.resourceListeners.delete(listener); }; }
|
|
4
6
|
clients = new Set();
|
|
5
7
|
publish(kind, payload, roleId) {
|
|
6
8
|
const event = { eventId: randomUUID(), at: new Date().toISOString(), roleId, kind, payload };
|
|
@@ -12,6 +14,12 @@ export class FleetEventBus {
|
|
|
12
14
|
if (socket.readyState === socket.OPEN && socket.bufferedAmount < 1024 * 1024)
|
|
13
15
|
socket.send(frame);
|
|
14
16
|
}
|
|
17
|
+
for (const listener of this.resourceListeners) {
|
|
18
|
+
try {
|
|
19
|
+
listener();
|
|
20
|
+
}
|
|
21
|
+
catch { }
|
|
22
|
+
}
|
|
15
23
|
return event;
|
|
16
24
|
}
|
|
17
25
|
attach(socket, lastEventId) {
|
|
@@ -30,5 +38,6 @@ export class FleetEventBus {
|
|
|
30
38
|
for (const socket of this.clients)
|
|
31
39
|
socket.close(1001, 'server shutdown');
|
|
32
40
|
this.clients.clear();
|
|
41
|
+
this.resourceListeners.clear();
|
|
33
42
|
}
|
|
34
43
|
}
|
|
@@ -103,17 +103,24 @@ export function createPrefixGateway(options) {
|
|
|
103
103
|
delete headers['sec-websocket-protocol'];
|
|
104
104
|
return { ...route, headers, session, authHeaders, deviceSocket: socketCredential !== undefined };
|
|
105
105
|
};
|
|
106
|
-
const track = (authHeaders, session, close) => {
|
|
106
|
+
const track = (authHeaders, session, close, neutral = false) => {
|
|
107
107
|
if (!session)
|
|
108
108
|
return () => { };
|
|
109
109
|
// The session authenticated for this request, with its own deadline, not whatever is current later.
|
|
110
110
|
const unbind = auth.bindTransport(session, close);
|
|
111
|
-
const timer = setInterval(() => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
const timer = setInterval(() => {
|
|
112
|
+
if (neutral) {
|
|
113
|
+
if (!auth.sessionValid(session))
|
|
114
|
+
close();
|
|
115
|
+
}
|
|
116
|
+
else
|
|
117
|
+
try {
|
|
118
|
+
auth.authenticate({ headers: authHeaders });
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
close();
|
|
122
|
+
}
|
|
123
|
+
}, neutral ? 1000 : 30_000);
|
|
117
124
|
timer.unref();
|
|
118
125
|
return () => { clearInterval(timer); unbind(); };
|
|
119
126
|
};
|
|
@@ -123,7 +130,7 @@ export function createPrefixGateway(options) {
|
|
|
123
130
|
const accountCors = (req) => {
|
|
124
131
|
const origin = auth?.accountOrigin(req);
|
|
125
132
|
return origin ? { 'access-control-allow-origin': origin, vary: 'Origin',
|
|
126
|
-
'access-control-expose-headers': 'Accept-Ranges, Content-Disposition, Content-Length, Content-Range, Content-Type, ETag, X-Ours-Workspace-Auth, X-Ours-Request-Id' } : {};
|
|
133
|
+
'access-control-expose-headers': 'Accept-Ranges, Content-Disposition, Content-Length, Content-Range, Content-Type, ETag, X-Ours-Workspace-Auth, X-Ours-Request-Id, X-Resource-Producer, X-Resource-Revision, X-Resource-Source-Generation, X-Resource-Source-Position, X-Resource-Connection, X-Resource-View, X-Resource-Epoch, X-Resource-Baseline' } : {};
|
|
127
134
|
};
|
|
128
135
|
const server = createServer((req, res) => {
|
|
129
136
|
const cors = accountCors(req);
|
|
@@ -134,7 +141,7 @@ export function createPrefixGateway(options) {
|
|
|
134
141
|
auth.validateBoundary({ headers: req.headers, method: req.method, url: req.url }, false);
|
|
135
142
|
res.writeHead(204, { ...cors, 'cache-control': 'no-store', 'access-control-max-age': '600',
|
|
136
143
|
'access-control-allow-methods': 'GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS',
|
|
137
|
-
'access-control-allow-headers': 'Authorization, Content-Type, Idempotency-Key, If-None-Match, Range, X-CSRF-Token, X-Ours-Messenger-CSRF, X-Voice-Duration' });
|
|
144
|
+
'access-control-allow-headers': 'Authorization, Content-Type, Idempotency-Key, If-None-Match, Range, X-CSRF-Token, X-Ours-Messenger-CSRF, X-Voice-Duration, X-Resource-Connection, X-Resource-View, X-Resource-Epoch, X-Resource-Baseline' });
|
|
138
145
|
res.end();
|
|
139
146
|
return;
|
|
140
147
|
}
|
|
@@ -186,7 +193,10 @@ export function createPrefixGateway(options) {
|
|
|
186
193
|
res.writeHead(502, { ...(route.service ? cors : {}), 'content-type': 'application/json' });
|
|
187
194
|
res.end(JSON.stringify({ error: { code: 'upstream_unavailable', message: 'Service is unavailable' } }));
|
|
188
195
|
});
|
|
189
|
-
const
|
|
196
|
+
const neutral = req.method === 'GET' && route.service?.prefix === '/notifications'
|
|
197
|
+
&& new URL(req.url ?? '/', 'http://gateway.invalid').searchParams.get('resources') === '1'
|
|
198
|
+
&& new URL(req.url ?? '/', 'http://gateway.invalid').pathname === '/notifications/api/v1/events';
|
|
199
|
+
const untrack = track(route.authHeaders, route.session, () => { upstream.destroy(); res.destroy(); }, neutral);
|
|
190
200
|
res.on('close', untrack);
|
|
191
201
|
req.on('aborted', () => upstream.destroy());
|
|
192
202
|
res.on('close', () => upstream.destroy());
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { ServerResponse } from 'node:http';
|
|
2
|
+
import { type FleetResourceScope, type FleetResourceState } from '../application/resource-observer.js';
|
|
3
|
+
export declare function abortableProjection<T>(read: Promise<T>, signal: AbortSignal): Promise<T>;
|
|
4
|
+
export interface ResourceFrameBinding {
|
|
5
|
+
readonly protocolVersion: 1;
|
|
6
|
+
readonly producerGeneration: string;
|
|
7
|
+
readonly subscriptionEpoch: number;
|
|
8
|
+
readonly viewId: string;
|
|
9
|
+
readonly sequence: number;
|
|
10
|
+
readonly revision: number;
|
|
11
|
+
readonly baselineId?: string;
|
|
12
|
+
}
|
|
13
|
+
export type ResourceHealthReason = 'auth_required' | 'unsupported' | 'upstream_unavailable';
|
|
14
|
+
export type ResourceEnvelope = ResourceFrameBinding & ({
|
|
15
|
+
readonly kind: 'snapshot';
|
|
16
|
+
readonly payload: unknown;
|
|
17
|
+
} | {
|
|
18
|
+
readonly kind: 'upsert';
|
|
19
|
+
readonly payload: unknown;
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: 'delete';
|
|
22
|
+
readonly payload: {
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly revision: number;
|
|
25
|
+
};
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: 'ready';
|
|
28
|
+
readonly payload: {
|
|
29
|
+
readonly baselineId: string;
|
|
30
|
+
readonly source: FleetResourceState;
|
|
31
|
+
};
|
|
32
|
+
} | {
|
|
33
|
+
readonly kind: 'coverage';
|
|
34
|
+
readonly payload: {
|
|
35
|
+
readonly source: FleetResourceState;
|
|
36
|
+
};
|
|
37
|
+
} | {
|
|
38
|
+
readonly kind: 'resync';
|
|
39
|
+
readonly payload: {
|
|
40
|
+
readonly reason: 'capacity' | 'projection_unavailable';
|
|
41
|
+
};
|
|
42
|
+
} | {
|
|
43
|
+
readonly kind: 'health';
|
|
44
|
+
readonly payload: {
|
|
45
|
+
readonly healthy: false;
|
|
46
|
+
readonly reason: ResourceHealthReason;
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
export interface ResourceWireFrame {
|
|
50
|
+
event: 'resource' | 'resource-chunk';
|
|
51
|
+
data: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
export declare const RESOURCE_FRAME_BYTES: number;
|
|
54
|
+
export declare const RESOURCE_PENDING_BYTES: number;
|
|
55
|
+
export declare const RESOURCE_ASSEMBLY_BYTES: number;
|
|
56
|
+
/** Lazily yield byte chunks so backpressure never queues an entire large record.
|
|
57
|
+
* Base64 prevents splitting a Unicode scalar from corrupting JSON/SSE parsing. */
|
|
58
|
+
export declare function resourceFrames(envelope: ResourceEnvelope): Generator<ResourceWireFrame>;
|
|
59
|
+
/** One Fleet HTTP writer. The active record owns the assembly budget;
|
|
60
|
+
* waiting live records share the smaller pending-output budget. */
|
|
61
|
+
export declare class ResourceOutput {
|
|
62
|
+
#private;
|
|
63
|
+
readonly response: ServerResponse;
|
|
64
|
+
readonly signal: AbortSignal;
|
|
65
|
+
readonly failed: (error: Error) => void;
|
|
66
|
+
constructor(response: ServerResponse, signal: AbortSignal, failed: (error: Error) => void);
|
|
67
|
+
send(envelope: ResourceEnvelope): Promise<void>;
|
|
68
|
+
close(error?: Error): void;
|
|
69
|
+
}
|
|
70
|
+
export interface ResourceDescriptor {
|
|
71
|
+
viewId: string;
|
|
72
|
+
resource: 'directory' | 'roles' | 'tasks' | 'task-lists' | 'configuration' | 'previews' | 'task-layout' | 'creation-action' | 'action' | 'member-addition' | 'login' | 'onboarding-health' | 'subscriptions';
|
|
73
|
+
entityId?: string;
|
|
74
|
+
receiptId?: string;
|
|
75
|
+
provider?: 'claude' | 'codex';
|
|
76
|
+
includeTemporary?: boolean;
|
|
77
|
+
includeDefinitions?: boolean;
|
|
78
|
+
ids?: string[];
|
|
79
|
+
state?: string;
|
|
80
|
+
list?: string;
|
|
81
|
+
groupByList?: boolean;
|
|
82
|
+
includeDeleting?: boolean;
|
|
83
|
+
}
|
|
84
|
+
export declare function canonicalResourceDescriptor(input: unknown): ResourceDescriptor;
|
|
85
|
+
interface BoundProjection {
|
|
86
|
+
payload: unknown;
|
|
87
|
+
source: FleetResourceState;
|
|
88
|
+
producerGeneration: string;
|
|
89
|
+
revision: number;
|
|
90
|
+
baselineId: string;
|
|
91
|
+
descriptor: ResourceDescriptor;
|
|
92
|
+
}
|
|
93
|
+
export declare class ResourceBindingError extends Error {
|
|
94
|
+
readonly status: number;
|
|
95
|
+
constructor(status: number, message: string);
|
|
96
|
+
}
|
|
97
|
+
/** Same committed snapshot/ready/bound-read contract as Messenger. No controllers,
|
|
98
|
+
* notification reads or presence are acquired by this delivery owner. */
|
|
99
|
+
export declare class FleetResourceViews {
|
|
100
|
+
private scope;
|
|
101
|
+
private project;
|
|
102
|
+
readonly producerGeneration: `${string}-${string}-${string}-${string}-${string}`;
|
|
103
|
+
private connections;
|
|
104
|
+
constructor(scope: FleetResourceScope, project: (descriptor: ResourceDescriptor, signal: AbortSignal, owner: string) => Promise<unknown>);
|
|
105
|
+
open(response: ServerResponse, owner: string, authorized: () => boolean): {
|
|
106
|
+
connectionId: `${string}-${string}-${string}-${string}-${string}`;
|
|
107
|
+
close: () => void;
|
|
108
|
+
};
|
|
109
|
+
register(owner: string, connectionId: string, viewId: string, epoch: number, input: unknown): {
|
|
110
|
+
subscriptionEpoch: number;
|
|
111
|
+
baselineId: string;
|
|
112
|
+
};
|
|
113
|
+
remove(owner: string, connectionId: string, viewId: string, epoch: number): void;
|
|
114
|
+
bound(owner: string, connectionId: string, viewId: string, epoch: number, baselineId: string): Promise<BoundProjection>;
|
|
115
|
+
close(): void;
|
|
116
|
+
private get;
|
|
117
|
+
private current;
|
|
118
|
+
private retire;
|
|
119
|
+
private emit;
|
|
120
|
+
private affects;
|
|
121
|
+
private schedule;
|
|
122
|
+
private refresh;
|
|
123
|
+
}
|
|
124
|
+
export {};
|