@haywoodmarx/agent-pager 0.1.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/LICENSE +21 -0
- package/README.md +63 -0
- package/dist/src/broker/address.d.ts +49 -0
- package/dist/src/broker/address.js +110 -0
- package/dist/src/broker/broker.d.ts +665 -0
- package/dist/src/broker/broker.js +2270 -0
- package/dist/src/broker/database.d.ts +81 -0
- package/dist/src/broker/database.js +69 -0
- package/dist/src/broker/operator-projection.d.ts +291 -0
- package/dist/src/broker/operator-projection.js +722 -0
- package/dist/src/broker/protocol.d.ts +237 -0
- package/dist/src/broker/protocol.js +311 -0
- package/dist/src/broker/schema.d.ts +94 -0
- package/dist/src/broker/schema.js +454 -0
- package/dist/src/broker/snapshot.d.ts +171 -0
- package/dist/src/broker/snapshot.js +78 -0
- package/dist/src/configuration-defaults.d.ts +64 -0
- package/dist/src/configuration-defaults.js +48 -0
- package/dist/src/configuration.d.ts +76 -0
- package/dist/src/configuration.js +156 -0
- package/dist/src/implementations/claude/environment.d.ts +8 -0
- package/dist/src/implementations/claude/environment.js +9 -0
- package/dist/src/implementations/claude/gateway-cli.d.ts +2 -0
- package/dist/src/implementations/claude/gateway-cli.js +136 -0
- package/dist/src/implementations/claude/gateway-identity.d.ts +134 -0
- package/dist/src/implementations/claude/gateway-identity.js +103 -0
- package/dist/src/implementations/claude/gateway.d.ts +148 -0
- package/dist/src/implementations/claude/gateway.js +236 -0
- package/dist/src/implementations/claude/instructions.d.ts +33 -0
- package/dist/src/implementations/claude/instructions.js +64 -0
- package/dist/src/implementations/claude/manifest.d.ts +33 -0
- package/dist/src/implementations/claude/manifest.js +108 -0
- package/dist/src/implementations/claude/plugin-directory.d.ts +80 -0
- package/dist/src/implementations/claude/plugin-directory.js +137 -0
- package/dist/src/implementations/claude/session-continuation.d.ts +25 -0
- package/dist/src/implementations/claude/session-continuation.js +125 -0
- package/dist/src/implementations/claude/session-identity.d.ts +25 -0
- package/dist/src/implementations/claude/session-identity.js +31 -0
- package/dist/src/implementations/claude/session-start-cli.d.ts +2 -0
- package/dist/src/implementations/claude/session-start-cli.js +16 -0
- package/dist/src/implementations/claude/socket-delivery.d.ts +52 -0
- package/dist/src/implementations/claude/socket-delivery.js +159 -0
- package/dist/src/implementations/model.d.ts +162 -0
- package/dist/src/implementations/model.js +1 -0
- package/dist/src/implementations/opencode/adapter.d.ts +71 -0
- package/dist/src/implementations/opencode/adapter.js +94 -0
- package/dist/src/implementations/opencode/environment.d.ts +8 -0
- package/dist/src/implementations/opencode/environment.js +9 -0
- package/dist/src/implementations/opencode/manifest.d.ts +30 -0
- package/dist/src/implementations/opencode/manifest.js +93 -0
- package/dist/src/implementations/opencode/plugin-api.d.ts +120 -0
- package/dist/src/implementations/opencode/plugin-api.js +1 -0
- package/dist/src/implementations/opencode/plugin.d.ts +38 -0
- package/dist/src/implementations/opencode/plugin.js +303 -0
- package/dist/src/implementations/opencode/self-close-tool.d.ts +9 -0
- package/dist/src/implementations/opencode/self-close-tool.js +31 -0
- package/dist/src/implementations/orca/terminal.d.ts +48 -0
- package/dist/src/implementations/orca/terminal.js +154 -0
- package/dist/src/implementations/pi/broker-client.d.ts +56 -0
- package/dist/src/implementations/pi/broker-client.js +156 -0
- package/dist/src/implementations/pi/environment.d.ts +8 -0
- package/dist/src/implementations/pi/environment.js +9 -0
- package/dist/src/implementations/pi/extension.d.ts +57 -0
- package/dist/src/implementations/pi/extension.js +253 -0
- package/dist/src/implementations/pi/host-slots.d.ts +18 -0
- package/dist/src/implementations/pi/host-slots.js +27 -0
- package/dist/src/implementations/pi/manifest.d.ts +11 -0
- package/dist/src/implementations/pi/manifest.js +61 -0
- package/dist/src/implementations/pi/self-close-tool.d.ts +7 -0
- package/dist/src/implementations/pi/self-close-tool.js +27 -0
- package/dist/src/implementations/registry.d.ts +47 -0
- package/dist/src/implementations/registry.js +157 -0
- package/dist/src/implementations/session-key.d.ts +13 -0
- package/dist/src/implementations/session-key.js +19 -0
- package/dist/src/index.d.ts +27 -0
- package/dist/src/index.js +26 -0
- package/dist/src/launch/broker-lock.d.ts +257 -0
- package/dist/src/launch/broker-lock.js +644 -0
- package/dist/src/launch/cli.d.ts +37 -0
- package/dist/src/launch/cli.js +317 -0
- package/dist/src/launch/environment.d.ts +45 -0
- package/dist/src/launch/environment.js +48 -0
- package/dist/src/launch/launch.d.ts +235 -0
- package/dist/src/launch/launch.js +223 -0
- package/dist/src/launch/on-demand.d.ts +202 -0
- package/dist/src/launch/on-demand.js +435 -0
- package/dist/src/launch/runtime-composition.d.ts +88 -0
- package/dist/src/launch/runtime-composition.js +253 -0
- package/dist/src/launch/runtime.d.ts +79 -0
- package/dist/src/launch/runtime.js +196 -0
- package/dist/src/launch/service-system.d.ts +11 -0
- package/dist/src/launch/service-system.js +39 -0
- package/dist/src/launch/service.d.ts +173 -0
- package/dist/src/launch/service.js +492 -0
- package/dist/src/launch/skill.d.ts +57 -0
- package/dist/src/launch/skill.js +81 -0
- package/dist/src/launch/terminal.d.ts +26 -0
- package/dist/src/launch/terminal.js +43 -0
- package/dist/src/launch/workspace-branch.d.ts +10 -0
- package/dist/src/launch/workspace-branch.js +29 -0
- package/dist/src/messaging/delivery-client.d.ts +144 -0
- package/dist/src/messaging/delivery-client.js +261 -0
- package/dist/src/messaging/delivery.d.ts +75 -0
- package/dist/src/messaging/delivery.js +22 -0
- package/dist/src/messaging/inbox-socket.d.ts +98 -0
- package/dist/src/messaging/inbox-socket.js +278 -0
- package/dist/src/messaging/mcp.d.ts +53 -0
- package/dist/src/messaging/mcp.js +501 -0
- package/dist/src/messaging/notifications.d.ts +231 -0
- package/dist/src/messaging/notifications.js +489 -0
- package/dist/src/messaging/push-delivery.d.ts +77 -0
- package/dist/src/messaging/push-delivery.js +187 -0
- package/dist/src/messaging/tools.d.ts +11 -0
- package/dist/src/messaging/tools.js +102 -0
- package/dist/src/messaging/wake.d.ts +23 -0
- package/dist/src/messaging/wake.js +39 -0
- package/dist/src/operator/agent-projection.d.ts +102 -0
- package/dist/src/operator/agent-projection.js +249 -0
- package/dist/src/operator/commands.d.ts +50 -0
- package/dist/src/operator/commands.js +199 -0
- package/dist/src/operator/diagnostics.d.ts +21 -0
- package/dist/src/operator/diagnostics.js +22 -0
- package/dist/src/operator/protocol.d.ts +511 -0
- package/dist/src/operator/protocol.js +49 -0
- package/dist/src/operator/repository-system.d.ts +14 -0
- package/dist/src/operator/repository-system.js +150 -0
- package/dist/src/operator/repository.d.ts +79 -0
- package/dist/src/operator/repository.js +72 -0
- package/dist/src/operator/traffic-projection.d.ts +19 -0
- package/dist/src/operator/traffic-projection.js +229 -0
- package/dist/src/operator/transport.d.ts +87 -0
- package/dist/src/operator/transport.js +549 -0
- package/dist/src/operator/update-store.d.ts +53 -0
- package/dist/src/operator/update-store.js +162 -0
- package/dist/src/operator/updates.d.ts +94 -0
- package/dist/src/operator/updates.js +280 -0
- package/dist/src/operator/validation.d.ts +114 -0
- package/dist/src/operator/validation.js +916 -0
- package/dist/src/shared/guards.d.ts +59 -0
- package/dist/src/shared/guards.js +119 -0
- package/dist/src/shared/http.d.ts +30 -0
- package/dist/src/shared/http.js +50 -0
- package/dist/src/shared/row.d.ts +2 -0
- package/dist/src/shared/row.js +1 -0
- package/dist/src/shared/shell.d.ts +6 -0
- package/dist/src/shared/shell.js +8 -0
- package/dist/src/tui/actions.d.ts +166 -0
- package/dist/src/tui/actions.js +253 -0
- package/dist/src/tui/agent-tree.d.ts +125 -0
- package/dist/src/tui/agent-tree.js +663 -0
- package/dist/src/tui/app.d.ts +38 -0
- package/dist/src/tui/app.js +378 -0
- package/dist/src/tui/chrome.d.ts +86 -0
- package/dist/src/tui/chrome.js +85 -0
- package/dist/src/tui/client.d.ts +41 -0
- package/dist/src/tui/client.js +279 -0
- package/dist/src/tui/composition.d.ts +41 -0
- package/dist/src/tui/composition.js +146 -0
- package/dist/src/tui/message-views.d.ts +94 -0
- package/dist/src/tui/message-views.js +515 -0
- package/dist/src/tui/model.d.ts +414 -0
- package/dist/src/tui/model.js +758 -0
- package/dist/src/tui/presentation.d.ts +350 -0
- package/dist/src/tui/presentation.js +541 -0
- package/dist/src/tui/production.d.ts +79 -0
- package/dist/src/tui/production.js +253 -0
- package/dist/src/tui/run-terminal.d.ts +32 -0
- package/dist/src/tui/run-terminal.js +54 -0
- package/dist/src/tui/runtime.d.ts +113 -0
- package/dist/src/tui/runtime.js +189 -0
- package/dist/src/tui/theme.d.ts +49 -0
- package/dist/src/tui/theme.js +55 -0
- package/dist/src/tui/transport.d.ts +31 -0
- package/dist/src/tui/transport.js +255 -0
- package/dist/src/version.d.ts +11 -0
- package/dist/src/version.js +52 -0
- package/package.json +142 -0
- package/skills/pager/SKILL.md +112 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { ProtocolError } from "../broker/protocol.js";
|
|
2
|
+
import { spawnInheritedSession } from "./terminal.js";
|
|
3
|
+
/** Direct local-process terminal provider. */
|
|
4
|
+
export class DirectTerminalProvider {
|
|
5
|
+
/** Identifies the direct local-process provider. */
|
|
6
|
+
name = "direct";
|
|
7
|
+
#spawnProcess;
|
|
8
|
+
/**
|
|
9
|
+
* Construct a direct provider with an explicit process boundary.
|
|
10
|
+
* @param spawnProcess - Starts the child process; the provider calls `unref` on it, so the parent may exit while it runs.
|
|
11
|
+
*/
|
|
12
|
+
constructor(spawnProcess) {
|
|
13
|
+
this.#spawnProcess = spawnProcess;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Launch one implementation plan as a direct child process.
|
|
17
|
+
* @param request - Plan to run; its sensitive environment overrides its environment, which overrides the base environment.
|
|
18
|
+
* @returns - Session with no exit promise, because the child is detached.
|
|
19
|
+
*/
|
|
20
|
+
launch(request) {
|
|
21
|
+
const child = this.#spawnProcess(request.plan.command, [...request.plan.args], {
|
|
22
|
+
cwd: request.plan.workspacePath,
|
|
23
|
+
env: {
|
|
24
|
+
...request.baseEnvironment,
|
|
25
|
+
...request.plan.environment,
|
|
26
|
+
...request.plan.sensitiveEnvironment,
|
|
27
|
+
},
|
|
28
|
+
stdio: "ignore",
|
|
29
|
+
detached: true,
|
|
30
|
+
});
|
|
31
|
+
child.unref();
|
|
32
|
+
return Promise.resolve({
|
|
33
|
+
provider: this.name,
|
|
34
|
+
...(child.pid === undefined ? {} : { pid: child.pid }),
|
|
35
|
+
taskCompletion: { supported: false },
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Foreground local-process provider that hands the current terminal to the implementation. */
|
|
40
|
+
export class ForegroundTerminalProvider {
|
|
41
|
+
/** Identifies the inherited-terminal provider. */
|
|
42
|
+
name = "foreground";
|
|
43
|
+
#spawnProcess;
|
|
44
|
+
/**
|
|
45
|
+
* Construct the provider around an explicit foreground process boundary.
|
|
46
|
+
* @param spawnProcess - Starts the child with inherited terminal streams; its `error` and `exit` events settle the session's exit promise.
|
|
47
|
+
*/
|
|
48
|
+
constructor(spawnProcess) {
|
|
49
|
+
this.#spawnProcess = spawnProcess;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Launch one implementation in the caller's foreground terminal.
|
|
53
|
+
* @param request - Plan to run; its sensitive environment overrides its environment, which overrides the base environment.
|
|
54
|
+
* @returns - Session whose exit promise resolves with the child's code and signal, and rejects if the child cannot start.
|
|
55
|
+
*/
|
|
56
|
+
launch(request) {
|
|
57
|
+
const { child, exit } = spawnInheritedSession(this.#spawnProcess, request);
|
|
58
|
+
return Promise.resolve({
|
|
59
|
+
provider: this.name,
|
|
60
|
+
...(child.pid === undefined ? {} : { pid: child.pid }),
|
|
61
|
+
taskCompletion: { supported: false },
|
|
62
|
+
exit,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Reserves agents, starts their terminals, and binds their attachments. */
|
|
67
|
+
export class LaunchService {
|
|
68
|
+
#broker;
|
|
69
|
+
#implementations;
|
|
70
|
+
#providers;
|
|
71
|
+
#environment;
|
|
72
|
+
#diagnostics = [];
|
|
73
|
+
#sessions = new Map();
|
|
74
|
+
/**
|
|
75
|
+
* Construct launch orchestration from neutral registries and terminal providers.
|
|
76
|
+
* @param broker - Durable broker instance that owns message state.
|
|
77
|
+
* @param implementations - Registry resolving opaque implementation ids.
|
|
78
|
+
* @param providers - Terminal backends a request can select by name; a later provider replaces an earlier one of the same name.
|
|
79
|
+
* @param environment - Process environment inherited by terminal providers.
|
|
80
|
+
*/
|
|
81
|
+
constructor(broker, implementations, providers, environment) {
|
|
82
|
+
this.#broker = broker;
|
|
83
|
+
this.#implementations = implementations;
|
|
84
|
+
this.#environment = environment;
|
|
85
|
+
this.#providers = new Map(providers.map((provider) => [provider.name, provider]));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Reserve and launch one agent through its implementation and terminal providers.
|
|
89
|
+
* @param request - Validated neutral launch request.
|
|
90
|
+
* @returns - Public launch result without process-binding values.
|
|
91
|
+
*/
|
|
92
|
+
async launchAgent(request) {
|
|
93
|
+
const terminalProviderName = request.terminalProvider ?? "direct";
|
|
94
|
+
const terminalProvider = this.#providers.get(terminalProviderName);
|
|
95
|
+
if (!terminalProvider)
|
|
96
|
+
throw new ProtocolError("validation_failed", `unknown terminal provider: ${terminalProviderName}`);
|
|
97
|
+
const implementation = this.#implementations.resolve(request.implementationId);
|
|
98
|
+
if (!implementation.launch.supported)
|
|
99
|
+
throw new ProtocolError("validation_failed", `implementation does not support launch: ${request.implementationId}`);
|
|
100
|
+
let reserved;
|
|
101
|
+
try {
|
|
102
|
+
const implementationIdentity = {
|
|
103
|
+
id: implementation.descriptor.id,
|
|
104
|
+
...(implementation.descriptor.version.known ? { version: implementation.descriptor.version.value } : {}),
|
|
105
|
+
};
|
|
106
|
+
reserved = request.selfRegistration
|
|
107
|
+
? this.#broker.registerAgentWithoutReservation({
|
|
108
|
+
workspacePath: request.workspacePath,
|
|
109
|
+
implementation: implementationIdentity,
|
|
110
|
+
...(request.sessionName ? { sessionName: request.sessionName } : {}),
|
|
111
|
+
})
|
|
112
|
+
: this.#broker.reserveAgent({
|
|
113
|
+
teamId: request.teamId ?? this.#broker.teamForAgent(request.parentId),
|
|
114
|
+
parentId: request.parentId,
|
|
115
|
+
...(request.sessionName ? { sessionName: request.sessionName } : {}),
|
|
116
|
+
workspacePath: request.workspacePath,
|
|
117
|
+
implementation: implementationIdentity,
|
|
118
|
+
});
|
|
119
|
+
this.#diagnostics.push({
|
|
120
|
+
type: "reservation_created",
|
|
121
|
+
agentId: reserved.agentId,
|
|
122
|
+
implementationId: request.implementationId,
|
|
123
|
+
provider: terminalProviderName,
|
|
124
|
+
});
|
|
125
|
+
const plan = await implementation.launch.buildPlan({
|
|
126
|
+
agentId: reserved.agentId,
|
|
127
|
+
brokerUrl: request.brokerUrl,
|
|
128
|
+
reservation: reserved.reservation,
|
|
129
|
+
deliveryReservation: this.#broker.reserveAttachment(reserved.agentId, "delivery"),
|
|
130
|
+
passthroughArgs: request.passthroughArgs ?? [],
|
|
131
|
+
workspacePath: request.workspacePath,
|
|
132
|
+
});
|
|
133
|
+
const session = await terminalProvider.launch({
|
|
134
|
+
agentId: reserved.agentId,
|
|
135
|
+
plan,
|
|
136
|
+
baseEnvironment: this.#environment,
|
|
137
|
+
});
|
|
138
|
+
this.#sessions.set(reserved.agentId, session);
|
|
139
|
+
this.#diagnostics.push({
|
|
140
|
+
type: "process_spawned",
|
|
141
|
+
agentId: reserved.agentId,
|
|
142
|
+
implementationId: request.implementationId,
|
|
143
|
+
provider: terminalProviderName,
|
|
144
|
+
detail: { pid: session.pid },
|
|
145
|
+
});
|
|
146
|
+
if (request.initialTask) {
|
|
147
|
+
this.#broker.send({
|
|
148
|
+
type: "task",
|
|
149
|
+
from: request.parentId,
|
|
150
|
+
to: reserved.agentId,
|
|
151
|
+
subject: "Initial task",
|
|
152
|
+
body: {
|
|
153
|
+
type: "initial_task",
|
|
154
|
+
task: request.initialTask,
|
|
155
|
+
parentId: request.parentId,
|
|
156
|
+
taskId: request.taskId ?? null,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
ok: true,
|
|
162
|
+
agentId: reserved.agentId,
|
|
163
|
+
alias: this.#broker.agentIdentity(reserved.agentId).alias,
|
|
164
|
+
implementationId: request.implementationId,
|
|
165
|
+
attachState: "pending",
|
|
166
|
+
processState: "launching",
|
|
167
|
+
provider: terminalProviderName,
|
|
168
|
+
...(session.pid === undefined ? {} : { pid: session.pid }),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
this.#broker.reapExpiredReservations();
|
|
173
|
+
const protocol = error instanceof ProtocolError
|
|
174
|
+
? error
|
|
175
|
+
: new ProtocolError("validation_failed", error instanceof Error ? error.message : "launch failed");
|
|
176
|
+
this.#diagnostics.push({
|
|
177
|
+
type: "launch_failed",
|
|
178
|
+
...(reserved ? { agentId: reserved.agentId } : {}),
|
|
179
|
+
implementationId: request.implementationId,
|
|
180
|
+
provider: terminalProviderName,
|
|
181
|
+
detail: protocol,
|
|
182
|
+
});
|
|
183
|
+
return {
|
|
184
|
+
ok: false,
|
|
185
|
+
...(reserved ? { agentId: reserved.agentId, alias: this.#broker.agentIdentity(reserved.agentId).alias } : {}),
|
|
186
|
+
implementationId: request.implementationId,
|
|
187
|
+
attachState: "failed",
|
|
188
|
+
processState: "failed",
|
|
189
|
+
provider: terminalProviderName,
|
|
190
|
+
error: { code: protocol.code, message: protocol.message },
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Wait for a foreground process to exit when its provider exposes one.
|
|
196
|
+
* @param agentId - Launched agent whose foreground disposition is requested.
|
|
197
|
+
* @returns - Child exit disposition, or undefined for detached and external terminals.
|
|
198
|
+
*/
|
|
199
|
+
waitForExit(agentId) {
|
|
200
|
+
return this.#sessions.get(agentId)?.exit;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Return launch diagnostics for operational output.
|
|
204
|
+
* @returns - Lifecycle events in observation order.
|
|
205
|
+
*/
|
|
206
|
+
diagnostics() {
|
|
207
|
+
return [...this.#diagnostics];
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Render stable human-facing launch output.
|
|
212
|
+
* @param result - Launch outcome to render.
|
|
213
|
+
* @param json - Whether to emit the machine-readable representation.
|
|
214
|
+
* @returns - Newline-terminated text: the JSON result when `json`, otherwise a one-line summary.
|
|
215
|
+
*/
|
|
216
|
+
export function renderLaunchResult(result, json = false) {
|
|
217
|
+
if (json)
|
|
218
|
+
return `${JSON.stringify(result)}\n`;
|
|
219
|
+
if (result.ok) {
|
|
220
|
+
return `agent ${result.agentId} ${result.attachState}/${result.processState} alias=${result.alias}\n`;
|
|
221
|
+
}
|
|
222
|
+
return `launch failed ${result.error.code}: ${result.error.message}\n`;
|
|
223
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { ProtocolError } from "../broker/protocol.js";
|
|
2
|
+
import type { RuntimeEnvironment } from "./environment.js";
|
|
3
|
+
import { type BrokerLock, type ProcessStartTime } from "./broker-lock.js";
|
|
4
|
+
/** Bounds one loopback endpoint probe, which either answers promptly or is treated as unreachable. */
|
|
5
|
+
export declare const BROKER_PROBE_TIMEOUT_MS = 2000;
|
|
6
|
+
/**
|
|
7
|
+
* Marks a service whose standard error is a file the starting caller reads, and deletes once the
|
|
8
|
+
* service has started.
|
|
9
|
+
*/
|
|
10
|
+
export declare const STARTUP_CAPTURE_ENVIRONMENT = "PAGER_STARTUP_CAPTURE";
|
|
11
|
+
/**
|
|
12
|
+
* Stop writing to a standard error that only the starting caller read, once startup has settled.
|
|
13
|
+
*
|
|
14
|
+
* The caller deletes the capture file, but the service keeps its descriptor for life, so any later
|
|
15
|
+
* write would fill a file nothing can read. `console.error` and `console.warn` are silenced too:
|
|
16
|
+
* under Bun 1.4.2 neither goes through `stderr.write`, so leaving them alone would still reach the
|
|
17
|
+
* deleted file's descriptor.
|
|
18
|
+
* @param environment - The service's environment, which says whether its standard error is a capture.
|
|
19
|
+
* @param stderr - The stream whose writes are dropped when it is.
|
|
20
|
+
* @param consoleLike - Console whose `error` and `warn` are dropped alongside `stderr`; defaults to
|
|
21
|
+
* the global console.
|
|
22
|
+
*/
|
|
23
|
+
export declare function endStartupCapture(environment: NodeJS.ProcessEnv, stderr: Pick<NodeJS.WriteStream, "write">, consoleLike?: Pick<Console, "error" | "warn">): void;
|
|
24
|
+
/** Names the loopback endpoints published by a live broker service. */
|
|
25
|
+
export type BrokerEndpoints = {
|
|
26
|
+
/** Identifies the process that owns the service. */
|
|
27
|
+
pid: number;
|
|
28
|
+
/** Locates the shared MCP endpoint. */
|
|
29
|
+
mcpUrl: string;
|
|
30
|
+
/** Locates the shared snapshot origin. */
|
|
31
|
+
snapshotUrl: string;
|
|
32
|
+
/** Locates the ordered operator projection endpoint. */
|
|
33
|
+
operatorUrl?: string;
|
|
34
|
+
};
|
|
35
|
+
/** The members of a spawned service process that on-demand startup touches. */
|
|
36
|
+
export type SpawnedServiceProcess = {
|
|
37
|
+
/** Identifies the child, absent when the operating system never assigned one. */
|
|
38
|
+
readonly pid?: number | undefined;
|
|
39
|
+
/** Lets this process exit while the detached service keeps running. */
|
|
40
|
+
unref(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Reports whether the child has ended.
|
|
43
|
+
* @returns - How the child ended, or undefined while it still runs.
|
|
44
|
+
*/
|
|
45
|
+
exitStatus(): {
|
|
46
|
+
code: number | null;
|
|
47
|
+
signal: NodeJS.Signals | null;
|
|
48
|
+
} | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Reads what the child has written to standard error so far.
|
|
51
|
+
* @returns - The text written since the child started.
|
|
52
|
+
*/
|
|
53
|
+
startupOutput(): string;
|
|
54
|
+
/** Removes the captured output once startup is settled, ending this process's view of it. */
|
|
55
|
+
releaseOutput(): void;
|
|
56
|
+
/**
|
|
57
|
+
* Ends a child whose service never published usable endpoints.
|
|
58
|
+
* @param signal - Signal delivered to the child.
|
|
59
|
+
*/
|
|
60
|
+
kill(signal: NodeJS.Signals): void;
|
|
61
|
+
};
|
|
62
|
+
/** Supplies process and timing seams used by on-demand service discovery. */
|
|
63
|
+
export type OnDemandServiceDependencies = {
|
|
64
|
+
/** Starts a detached service process with the caller's resolved environment. */
|
|
65
|
+
spawnService(command: string, args: string[], environment: NodeJS.ProcessEnv): SpawnedServiceProcess;
|
|
66
|
+
/**
|
|
67
|
+
* Shows the operator what a service that did start wrote to standard error while starting.
|
|
68
|
+
* @param message - Text the service wrote, such as a report of a database recreation.
|
|
69
|
+
*/
|
|
70
|
+
report(message: string): void;
|
|
71
|
+
/** Builds the detached service command for the resolved environment. */
|
|
72
|
+
serviceCommand(environment: RuntimeEnvironment): {
|
|
73
|
+
command: string;
|
|
74
|
+
args: string[];
|
|
75
|
+
};
|
|
76
|
+
/** Reports whether an operating-system process still exists. */
|
|
77
|
+
processIsAlive(pid: number): boolean;
|
|
78
|
+
/** Reports when a process started, so a recycled process id is not mistaken for the owner. */
|
|
79
|
+
processStartedAt(pid: number): ProcessStartTime;
|
|
80
|
+
/** Reports whether published endpoints answer. */
|
|
81
|
+
endpointsReady(endpoints: BrokerEndpoints): Promise<BrokerProbeOutcome>;
|
|
82
|
+
/** Delays one bounded discovery attempt. */
|
|
83
|
+
wait(milliseconds: number): Promise<void>;
|
|
84
|
+
/** Supplies the monotonic-enough clock used for a bounded wait. */
|
|
85
|
+
now(): number;
|
|
86
|
+
};
|
|
87
|
+
/** Named failure raised when no service publishes usable endpoints within the configured budget. */
|
|
88
|
+
export declare class ServiceStartupTimeoutError extends ProtocolError {
|
|
89
|
+
/**
|
|
90
|
+
* Construct the timeout reported to callers.
|
|
91
|
+
* @param output - What the still-running child wrote to standard error, appended when not blank.
|
|
92
|
+
*/
|
|
93
|
+
constructor(output?: string);
|
|
94
|
+
}
|
|
95
|
+
/** Named failure raised when the spawned service ends before it publishes endpoints. */
|
|
96
|
+
export declare class ServiceStartupFailedError extends ProtocolError {
|
|
97
|
+
/**
|
|
98
|
+
* Construct a failure carrying the reason the service gave for ending.
|
|
99
|
+
* @param status - How the child ended.
|
|
100
|
+
* @param output - What the child wrote to standard error before it ended.
|
|
101
|
+
*/
|
|
102
|
+
constructor(status: {
|
|
103
|
+
code: number | null;
|
|
104
|
+
signal: NodeJS.Signals | null;
|
|
105
|
+
}, output: string);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Outcome of one readiness probe against a lock-owning service.
|
|
109
|
+
*
|
|
110
|
+
* A service that answers with a different identity is incompatible and settles the question, while
|
|
111
|
+
* one that does not answer may simply be slow and is worth asking again. `unreachable` and
|
|
112
|
+
* `unhealthy` are both worth retrying but are not the same observation: the first means nothing was
|
|
113
|
+
* answered at all, the second that the service answered and reported itself not ready.
|
|
114
|
+
*/
|
|
115
|
+
export type BrokerProbeOutcome = "ready" | "mismatch" | "unreachable" | "unhealthy";
|
|
116
|
+
/** Named failure raised when the current-build service owns the lock but will not answer. */
|
|
117
|
+
export declare class BrokerServiceUnreachableError extends ProtocolError {
|
|
118
|
+
/** Identifies the running process that owns the database. */
|
|
119
|
+
readonly pid: number;
|
|
120
|
+
/** Records how many probes failed before the budget ran out. */
|
|
121
|
+
readonly probes: number;
|
|
122
|
+
/** Records the elapsed time those probes covered. */
|
|
123
|
+
readonly windowMs: number;
|
|
124
|
+
/** Records which kind of failure the last probe saw. */
|
|
125
|
+
readonly outcome: "unreachable" | "unhealthy";
|
|
126
|
+
/**
|
|
127
|
+
* Construct a failure that reports what the probes observed and nothing beyond it.
|
|
128
|
+
*
|
|
129
|
+
* A busy owner and a broken one produce the same probe result, so the message states the
|
|
130
|
+
* observation and leaves the operator a retry before any action that would stop a working service.
|
|
131
|
+
* @param pid - Process id recorded by the current-identity lock, still running when probing ended.
|
|
132
|
+
* @param probes - Number of readiness probes that were made and failed.
|
|
133
|
+
* @param windowMs - Elapsed time those probes covered, in milliseconds.
|
|
134
|
+
* @param outcome - Whether the probes went unanswered or were answered with a not-ready status.
|
|
135
|
+
*/
|
|
136
|
+
constructor(
|
|
137
|
+
/** Identifies the running process that owns the database. */
|
|
138
|
+
pid: number,
|
|
139
|
+
/** Records how many probes failed before the budget ran out. */
|
|
140
|
+
probes: number,
|
|
141
|
+
/** Records the elapsed time those probes covered. */
|
|
142
|
+
windowMs: number,
|
|
143
|
+
/** Records which kind of failure the last probe saw. */
|
|
144
|
+
outcome: "unreachable" | "unhealthy");
|
|
145
|
+
}
|
|
146
|
+
/** Named failure raised when a signalled broker service is still running once the exit budget is spent. */
|
|
147
|
+
export declare class BrokerServiceExitTimeoutError extends ProtocolError {
|
|
148
|
+
/**
|
|
149
|
+
* Construct the failure reported when the owner ignores or outlasts its termination signal.
|
|
150
|
+
* @param pid - Process id of the owner that was signalled.
|
|
151
|
+
*/
|
|
152
|
+
constructor(pid: number);
|
|
153
|
+
}
|
|
154
|
+
/** Named failure raised when an upgrade encounters a live pre-identity service. */
|
|
155
|
+
export declare class LegacyBrokerServiceError extends ProtocolError {
|
|
156
|
+
/**
|
|
157
|
+
* Construct an actionable upgrade failure without terminating an arbitrary process.
|
|
158
|
+
* @param pid - Process id recorded by the incompatible lock.
|
|
159
|
+
*/
|
|
160
|
+
constructor(pid: number);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Return live endpoints from a lock only when its owning process still exists.
|
|
164
|
+
* @param lock - Candidate lock read beside the configured database.
|
|
165
|
+
* @param isAlive - Operating-system liveness boundary.
|
|
166
|
+
* @param startedAt - Reads a process start time, used to reject a recycled process id. Omit it to skip
|
|
167
|
+
* that check, which costs a subprocess on macOS.
|
|
168
|
+
* @returns - Complete service endpoints when the lock is live and fully published.
|
|
169
|
+
*/
|
|
170
|
+
export declare function liveBrokerEndpoints(lock: BrokerLock | undefined, isAlive: (pid: number) => boolean, startedAt?: (pid: number) => ProcessStartTime): BrokerEndpoints | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* Adopt a running broker service or start one detached and wait for its endpoints.
|
|
173
|
+
* @param environment - Resolved configuration shared by the caller and service process.
|
|
174
|
+
* @param overrides - Optional process and timing seams for isolated verification.
|
|
175
|
+
* @returns - Live loopback endpoints owned by the singleton service process.
|
|
176
|
+
*/
|
|
177
|
+
export declare function ensureBrokerService(environment: RuntimeEnvironment, overrides?: Partial<OnDemandServiceDependencies>): Promise<BrokerEndpoints>;
|
|
178
|
+
/** Supplies the process seams stopping a broker service needs. */
|
|
179
|
+
export type BrokerStopDependencies = {
|
|
180
|
+
processIsAlive(pid: number): boolean;
|
|
181
|
+
processStartedAt(pid: number): ProcessStartTime;
|
|
182
|
+
signal(pid: number, signal: NodeJS.Signals): void;
|
|
183
|
+
wait(milliseconds: number): Promise<void>;
|
|
184
|
+
now(): number;
|
|
185
|
+
};
|
|
186
|
+
/** Reports what stopping the broker service found: the owner it stopped, or no live owner at all. */
|
|
187
|
+
export type BrokerStopOutcome = {
|
|
188
|
+
state: "stopped";
|
|
189
|
+
pid: number;
|
|
190
|
+
} | {
|
|
191
|
+
state: "not_running";
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Stop the broker service that owns the configured database, whichever build started it.
|
|
195
|
+
*
|
|
196
|
+
* A lock whose process id now belongs to a process started at a different time names no owner, so
|
|
197
|
+
* that process is left alone rather than signalled.
|
|
198
|
+
* @param environment - Resolved configuration locating the database whose owner is stopped.
|
|
199
|
+
* @param overrides - Optional process and timing seams for isolated verification.
|
|
200
|
+
* @returns - The owner that exited after being signalled, or `not_running` when there was none.
|
|
201
|
+
*/
|
|
202
|
+
export declare function stopBrokerService(environment: RuntimeEnvironment, overrides?: Partial<BrokerStopDependencies>): Promise<BrokerStopOutcome>;
|