@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,317 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { realpathSync } from "node:fs";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import { AGENT_ID_SCHEME, ProtocolError } from "../broker/protocol.js";
|
|
5
|
+
import { implementationId } from "../implementations/registry.js";
|
|
6
|
+
import { renderLaunchResult } from "./launch.js";
|
|
7
|
+
import { createBroker, createImplementationRegistry, createInteractiveLaunchService, openBroker, readRuntimeEnvironment, } from "./runtime-composition.js";
|
|
8
|
+
import { endStartupCapture, ensureBrokerService, stopBrokerService } from "./on-demand.js";
|
|
9
|
+
import { packagedSkills } from "./skill.js";
|
|
10
|
+
import { createOperatorTuiClient, fileBackedTuiLayout, DEFAULT_OPERATOR_TUI_THEME, startOperatorTui, } from "../tui/production.js";
|
|
11
|
+
import { assertSupportedBunRuntime } from "./runtime.js";
|
|
12
|
+
import { BrokerService } from "./service.js";
|
|
13
|
+
import { systemBrokerServiceFilesystem, systemBrokerServiceScheduler } from "./service-system.js";
|
|
14
|
+
import { BrokerLockGuard, brokerLockPath, brokerLockHasCurrentIdentity, brokerLockIsLive, processIsAlive, readBrokerLock, readBrokerOwnerPid, } from "./broker-lock.js";
|
|
15
|
+
/**
|
|
16
|
+
* Run the operational CLI.
|
|
17
|
+
*
|
|
18
|
+
* Most commands write one `{ ok, … }` envelope to stdout on success. An invocation naming no command at all renders the operator TUI on the terminal instead of
|
|
19
|
+
* writing an envelope; the bare `<implementation-id>` wrapper hands or inherits stdio to the child
|
|
20
|
+
* process, and the wrapper's own failure path writes to stderr instead of stdout. `--help`, `-h`,
|
|
21
|
+
* and `help` write only to stderr, through `usage()`. Any other thrown failure is caught here and
|
|
22
|
+
* written to stderr as `{ ok: false, … }`.
|
|
23
|
+
* @param argv - Command tokens supplied after the executable name.
|
|
24
|
+
*/
|
|
25
|
+
export async function main(argv = process.argv.slice(2)) {
|
|
26
|
+
let broker;
|
|
27
|
+
let propagatedSignal;
|
|
28
|
+
try {
|
|
29
|
+
assertSupportedBunRuntime();
|
|
30
|
+
const [command, ...rest] = argv;
|
|
31
|
+
const environment = readRuntimeEnvironment(process.env);
|
|
32
|
+
const implementations = await createImplementationRegistry();
|
|
33
|
+
assertNoReservedImplementationIds(implementations);
|
|
34
|
+
const dbPath = environment.dbPath;
|
|
35
|
+
switch (command) {
|
|
36
|
+
case undefined:
|
|
37
|
+
await runOperatorTui(environment, implementations);
|
|
38
|
+
break;
|
|
39
|
+
case "--help":
|
|
40
|
+
case "-h":
|
|
41
|
+
case "help":
|
|
42
|
+
usage(implementations);
|
|
43
|
+
break;
|
|
44
|
+
case "status": {
|
|
45
|
+
if (rest.length > 0)
|
|
46
|
+
throw new ProtocolError("validation_failed", "status does not accept arguments");
|
|
47
|
+
const lockPath = brokerLockPath(dbPath);
|
|
48
|
+
const lock = readBrokerLock(lockPath);
|
|
49
|
+
const ownerPid = lock?.pid ?? readBrokerOwnerPid(lockPath);
|
|
50
|
+
const ownerAlive = ownerPid !== undefined && processIsAlive(ownerPid);
|
|
51
|
+
const running = brokerLockIsLive(lock, processIsAlive);
|
|
52
|
+
const starting = ownerAlive && brokerLockHasCurrentIdentity(lock) && lock?.epoch === "starting";
|
|
53
|
+
console.log(JSON.stringify({
|
|
54
|
+
ok: true,
|
|
55
|
+
state: running ? "running" : starting ? "starting" : ownerAlive ? "incompatible" : "stopped",
|
|
56
|
+
...(ownerAlive ? { pid: ownerPid } : {}),
|
|
57
|
+
...(running && lock.mcpUrl ? { mcpUrl: lock.mcpUrl } : {}),
|
|
58
|
+
dbPath,
|
|
59
|
+
}));
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
case "exit": {
|
|
63
|
+
if (rest.length > 0)
|
|
64
|
+
throw new ProtocolError("validation_failed", "exit does not accept arguments");
|
|
65
|
+
console.log(JSON.stringify({ ok: true, ...(await stopBrokerService(environment)) }));
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case "restart": {
|
|
69
|
+
if (rest.length > 0)
|
|
70
|
+
throw new ProtocolError("validation_failed", "restart does not accept arguments");
|
|
71
|
+
const stopped = await stopBrokerService(environment);
|
|
72
|
+
const endpoints = await ensureBrokerService(environment);
|
|
73
|
+
console.log(JSON.stringify({ ok: true, stopped, ...endpoints }));
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
case "serve": {
|
|
77
|
+
const service = new BrokerService(dbPath, implementations, {
|
|
78
|
+
now: Date.now,
|
|
79
|
+
report: (message) => {
|
|
80
|
+
process.stderr.write(`${message}\n`);
|
|
81
|
+
},
|
|
82
|
+
scheduler: systemBrokerServiceScheduler(),
|
|
83
|
+
filesystem: systemBrokerServiceFilesystem(),
|
|
84
|
+
lock: new BrokerLockGuard(brokerLockPath(dbPath)),
|
|
85
|
+
openBroker,
|
|
86
|
+
config: environment.config,
|
|
87
|
+
configPath: environment.configPath,
|
|
88
|
+
storeDirectory: environment.storeDirectory,
|
|
89
|
+
});
|
|
90
|
+
let status;
|
|
91
|
+
try {
|
|
92
|
+
status = await service.start();
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
// A service that lost lock arbitration has nothing to serve. Exiting explicitly is required
|
|
96
|
+
// because a listener or timer opened before the failure would otherwise hold this process
|
|
97
|
+
// resident forever, leaving an orphan that answers nothing.
|
|
98
|
+
console.error(JSON.stringify({ ok: false, error: { message: errorMessage(error) } }));
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
endStartupCapture(process.env, process.stderr);
|
|
102
|
+
console.log(JSON.stringify({ ok: true, ...status }));
|
|
103
|
+
const abandoned = new Promise((resolve) => {
|
|
104
|
+
service.onAbandoned(resolve);
|
|
105
|
+
});
|
|
106
|
+
await Promise.race([waitForShutdown(), abandoned]);
|
|
107
|
+
// This process exists only to serve, and it has been told to stop serving, by a shutdown signal
|
|
108
|
+
// or by abandonment, so the stop gets a bounded chance and then the process ends.
|
|
109
|
+
await Promise.race([service.stop().catch(() => undefined), delay(SHUTDOWN_GRACE_MS)]);
|
|
110
|
+
process.exit(process.exitCode ?? 0);
|
|
111
|
+
}
|
|
112
|
+
// eslint-disable-next-line no-fallthrough -- process.exit ends the process, so control never reaches the next case.
|
|
113
|
+
default: {
|
|
114
|
+
broker = createBroker(environment);
|
|
115
|
+
const { selectedImplementation, sessionName, passthrough } = parseWrapperCommand(command, rest, implementations);
|
|
116
|
+
const endpoints = await ensureBrokerService(environment);
|
|
117
|
+
const interactive = await createInteractiveLaunchService(broker, environment, implementations, (message) => {
|
|
118
|
+
process.stderr.write(`${message}\n`);
|
|
119
|
+
});
|
|
120
|
+
const result = await interactive.service.launchAgent({
|
|
121
|
+
implementationId: selectedImplementation,
|
|
122
|
+
parentId: `${AGENT_ID_SCHEME}interactive-wrapper`,
|
|
123
|
+
terminalProvider: interactive.terminalProvider,
|
|
124
|
+
brokerUrl: endpoints.mcpUrl,
|
|
125
|
+
workspacePath: process.cwd(),
|
|
126
|
+
selfRegistration: true,
|
|
127
|
+
...(sessionName ? { sessionName } : {}),
|
|
128
|
+
passthroughArgs: passthrough,
|
|
129
|
+
});
|
|
130
|
+
if (!result.ok) {
|
|
131
|
+
process.stderr.write(renderLaunchResult(result));
|
|
132
|
+
process.exitCode = 1;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
const disposition = await interactive.service.waitForExit(result.agentId);
|
|
136
|
+
if (disposition?.signal)
|
|
137
|
+
propagatedSignal = disposition.signal;
|
|
138
|
+
else if (disposition?.code !== null && disposition?.code !== undefined)
|
|
139
|
+
process.exitCode = disposition.code;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
const protocol = error instanceof ProtocolError
|
|
145
|
+
? error
|
|
146
|
+
: new ProtocolError("validation_failed", error instanceof Error ? error.message : "command failed");
|
|
147
|
+
console.error(JSON.stringify({ ok: false, error: { code: protocol.code, message: protocol.message } }));
|
|
148
|
+
process.exitCode = 1;
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
broker?.close();
|
|
152
|
+
}
|
|
153
|
+
if (propagatedSignal)
|
|
154
|
+
process.kill(process.pid, propagatedSignal);
|
|
155
|
+
}
|
|
156
|
+
if (isEntryPoint(process.argv[1]))
|
|
157
|
+
void main();
|
|
158
|
+
/**
|
|
159
|
+
* Collect the registration each implementation offers, for the menu to run on request.
|
|
160
|
+
*
|
|
161
|
+
* Read once at startup because an implementation's registration cannot change while the screen is
|
|
162
|
+
* open.
|
|
163
|
+
* @param implementations - Registry whose providers are asked what registers them.
|
|
164
|
+
* @returns - One entry per implementation that registers itself with a host, omitting one whose
|
|
165
|
+
* command cannot be named.
|
|
166
|
+
*/
|
|
167
|
+
function hostRegistrations(implementations) {
|
|
168
|
+
const registrations = [];
|
|
169
|
+
for (const descriptor of implementations.descriptors()) {
|
|
170
|
+
const provider = implementations.resolve(descriptor.id);
|
|
171
|
+
if (!provider.hostRegistration.supported)
|
|
172
|
+
continue;
|
|
173
|
+
// Naming the command can involve writing what it installs, and the operator screen is not the
|
|
174
|
+
// place to fail over that: the entry is left out and every other screen still opens.
|
|
175
|
+
try {
|
|
176
|
+
registrations.push({
|
|
177
|
+
id: descriptor.id,
|
|
178
|
+
label: descriptor.displayName,
|
|
179
|
+
command: provider.hostRegistration.registrationCommand(),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return registrations;
|
|
187
|
+
}
|
|
188
|
+
const reservedCommands = ["status", "exit", "restart", "serve", "help"];
|
|
189
|
+
/**
|
|
190
|
+
* Reject installed implementation identities that would be shadowed by a reserved subcommand.
|
|
191
|
+
* @param implementations - Registry whose open ids share the first CLI argument slot.
|
|
192
|
+
*/
|
|
193
|
+
export function assertNoReservedImplementationIds(implementations) {
|
|
194
|
+
const collisions = implementations
|
|
195
|
+
.descriptors()
|
|
196
|
+
.map(({ id }) => id)
|
|
197
|
+
.filter((id) => reservedCommands.includes(id));
|
|
198
|
+
if (collisions.length > 0) {
|
|
199
|
+
throw new ProtocolError("conflict", `reserved implementation id collision: ${collisions.join(", ")}; reserved commands: ${reservedCommands.join(", ")}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Parse a bare implementation wrapper command without naming a concrete provider.
|
|
204
|
+
* @param command - First command token already known not to be a reserved subcommand.
|
|
205
|
+
* @param args - Wrapper options and implementation passthrough arguments.
|
|
206
|
+
* @param implementations - Registry used to distinguish valid-but-uninstalled ids.
|
|
207
|
+
* @returns - Resolved implementation, optional stable session name, and passthrough arguments.
|
|
208
|
+
*/
|
|
209
|
+
export function parseWrapperCommand(command, args, implementations) {
|
|
210
|
+
const selectedImplementation = implementationId(command);
|
|
211
|
+
try {
|
|
212
|
+
implementations.resolve(selectedImplementation);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
const installed = implementations.descriptors().map(({ id }) => id);
|
|
216
|
+
throw new ProtocolError("validation_failed", `implementation is not installed: ${selectedImplementation}; installed implementation ids: ${installed.join(", ") || "none"}`);
|
|
217
|
+
}
|
|
218
|
+
const separator = args.indexOf("--");
|
|
219
|
+
const optionArgs = separator === -1 ? args : args.slice(0, separator);
|
|
220
|
+
const passthrough = separator === -1 ? [] : args.slice(separator + 1);
|
|
221
|
+
let sessionName;
|
|
222
|
+
for (let index = 0; index < optionArgs.length; index += 1) {
|
|
223
|
+
const flag = optionArgs[index];
|
|
224
|
+
if (flag !== "--session-name") {
|
|
225
|
+
throw new ProtocolError("validation_failed", `unknown wrapper option: ${String(flag)}`);
|
|
226
|
+
}
|
|
227
|
+
sessionName = requiredOptionValue(flag, optionArgs[index + 1]);
|
|
228
|
+
index += 1;
|
|
229
|
+
}
|
|
230
|
+
return { selectedImplementation, ...(sessionName ? { sessionName } : {}), passthrough };
|
|
231
|
+
}
|
|
232
|
+
function requiredOptionValue(flag, value) {
|
|
233
|
+
if (value === undefined)
|
|
234
|
+
throw new ProtocolError("validation_failed", `${flag} requires a value`);
|
|
235
|
+
return value;
|
|
236
|
+
}
|
|
237
|
+
/** Bounds how long a stopping service waits for its endpoints to close before exiting. */
|
|
238
|
+
const SHUTDOWN_GRACE_MS = 5_000;
|
|
239
|
+
/**
|
|
240
|
+
* Resolve after a delay.
|
|
241
|
+
* @param milliseconds - Non-negative delay.
|
|
242
|
+
* @returns - Promise that settles once the delay elapses.
|
|
243
|
+
*/
|
|
244
|
+
function delay(milliseconds) {
|
|
245
|
+
return new Promise((resolve) => {
|
|
246
|
+
setTimeout(resolve, milliseconds);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Start the operator TUI, starting the broker service first when none is already serving.
|
|
251
|
+
* @param environment - Resolved runtime configuration naming the store directory the layout persists to.
|
|
252
|
+
* @param implementations - Registry supplying the host registrations the TUI offers as start actions.
|
|
253
|
+
*/
|
|
254
|
+
async function runOperatorTui(environment, implementations) {
|
|
255
|
+
const endpoints = await ensureBrokerService(environment);
|
|
256
|
+
if (!endpoints.operatorUrl)
|
|
257
|
+
throw new ProtocolError("validation_failed", "operator endpoint is unavailable");
|
|
258
|
+
const client = createOperatorTuiClient({
|
|
259
|
+
operatorUrl: endpoints.operatorUrl,
|
|
260
|
+
theme: DEFAULT_OPERATOR_TUI_THEME,
|
|
261
|
+
layout: fileBackedTuiLayout(environment.storeDirectory),
|
|
262
|
+
});
|
|
263
|
+
await startOperatorTui({
|
|
264
|
+
...client,
|
|
265
|
+
actions: { skills: packagedSkills(), registrations: hostRegistrations(implementations) },
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Write the command summary to stderr.
|
|
270
|
+
* @param implementations - Registry whose installed harness ids the summary lists.
|
|
271
|
+
*/
|
|
272
|
+
function usage(implementations) {
|
|
273
|
+
const harnesses = implementations
|
|
274
|
+
.descriptors()
|
|
275
|
+
.map(({ id }) => id)
|
|
276
|
+
.join(", ");
|
|
277
|
+
console.error([
|
|
278
|
+
"pager open the operator TUI",
|
|
279
|
+
"pager <harness> [--session-name <name>] [-- <harness arguments>]",
|
|
280
|
+
` start a harness attached to the broker (installed: ${harnesses || "none"})`,
|
|
281
|
+
"pager status broker state, pid, MCP endpoint and database",
|
|
282
|
+
"pager exit stop the broker",
|
|
283
|
+
"pager restart stop the broker and start a fresh one",
|
|
284
|
+
"pager serve run the broker in the foreground",
|
|
285
|
+
"pager help show this text",
|
|
286
|
+
].join("\n"));
|
|
287
|
+
}
|
|
288
|
+
function isEntryPoint(path) {
|
|
289
|
+
return path ? import.meta.url === canonicalFileUrl(path) : false;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Return the canonical encoded file URL used to compare a CLI process entrypoint.
|
|
293
|
+
* @param path - Existing filesystem path supplied by the process argument vector.
|
|
294
|
+
* @returns - URL-safe identity after resolving filesystem links.
|
|
295
|
+
*/
|
|
296
|
+
export function canonicalFileUrl(path) {
|
|
297
|
+
return pathToFileURL(realpathSync(path)).href;
|
|
298
|
+
}
|
|
299
|
+
function waitForShutdown() {
|
|
300
|
+
return new Promise((resolve) => {
|
|
301
|
+
const shutdown = () => {
|
|
302
|
+
process.off("SIGINT", shutdown);
|
|
303
|
+
process.off("SIGTERM", shutdown);
|
|
304
|
+
resolve();
|
|
305
|
+
};
|
|
306
|
+
process.once("SIGINT", shutdown);
|
|
307
|
+
process.once("SIGTERM", shutdown);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Render any thrown value as a single diagnostic line.
|
|
312
|
+
* @param error - Value thrown by a failed operation.
|
|
313
|
+
* @returns - Message text safe to write to stderr.
|
|
314
|
+
*/
|
|
315
|
+
function errorMessage(error) {
|
|
316
|
+
return error instanceof Error ? error.message : String(error);
|
|
317
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type PagerConfig } from "../configuration.js";
|
|
2
|
+
/**
|
|
3
|
+
* Names the broker MCP endpoint set for a launched implementation, inherited from its own process
|
|
4
|
+
* environment. Some implementations treat it, alongside their other launch values, as an
|
|
5
|
+
* all-or-nothing launch identity.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PAGER_MCP_URL_ENVIRONMENT = "PAGER_MCP_URL";
|
|
8
|
+
/**
|
|
9
|
+
* Names one implementation's own broker connection setting, distinct from
|
|
10
|
+
* {@link PAGER_MCP_URL_ENVIRONMENT}.
|
|
11
|
+
*
|
|
12
|
+
* Publishing that implementation's own broker URL under the shared `PAGER_MCP_URL` name
|
|
13
|
+
* would make any child that reads that shared name inherit it as one part of its own launch
|
|
14
|
+
* identity: with the rest of that identity absent, an all-or-nothing reader goes inactive or
|
|
15
|
+
* throws instead of self-registering. This key carries the URL instead, so that hazard does not
|
|
16
|
+
* arise.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PAGER_BROKER_URL_ENVIRONMENT = "PAGER_BROKER_URL";
|
|
19
|
+
/** Names the single-use attachment reservation a launching process publishes to the launched one. */
|
|
20
|
+
export declare const PAGER_ATTACH_RESERVATION_ENVIRONMENT = "PAGER_ATTACH_RESERVATION";
|
|
21
|
+
/** Names the reserved broker identity a launching process publishes to the launched one. */
|
|
22
|
+
export declare const PAGER_AGENT_ID_ENVIRONMENT = "PAGER_AGENT_ID";
|
|
23
|
+
/** Defines process configuration consumed by the Bun runtime and editor-hosted launch boundaries. */
|
|
24
|
+
export type RuntimeEnvironment = {
|
|
25
|
+
/** Supplies environment variables to providers and launch services. */
|
|
26
|
+
processEnv: NodeJS.ProcessEnv;
|
|
27
|
+
/** Carries validated user configuration for every runtime consumer. */
|
|
28
|
+
config: PagerConfig;
|
|
29
|
+
/** Names the user configuration file, or null when discovery found none. */
|
|
30
|
+
configPath: string | null;
|
|
31
|
+
/** Names the directory owning user configuration and durable state. */
|
|
32
|
+
storeDirectory: string;
|
|
33
|
+
/** Names the broker database file. */
|
|
34
|
+
dbPath: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Read process configuration without importing the SQLite-backed composition root.
|
|
38
|
+
* @param environment - Process environment supplying runtime configuration.
|
|
39
|
+
* @param options - Explicit user-path inputs supplied by the command boundary.
|
|
40
|
+
* @returns - Resolved runtime configuration safe to consume inside editor plugin hosts.
|
|
41
|
+
*/
|
|
42
|
+
export declare function readRuntimeEnvironment(environment?: NodeJS.ProcessEnv, options?: {
|
|
43
|
+
homeDirectory?: string;
|
|
44
|
+
platform?: NodeJS.Platform;
|
|
45
|
+
}): RuntimeEnvironment;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { loadPagerConfiguration } from "../configuration.js";
|
|
3
|
+
import { ADAPTER_HEARTBEAT_INTERVAL_ENVIRONMENT } from "../configuration-defaults.js";
|
|
4
|
+
/**
|
|
5
|
+
* Names the broker MCP endpoint set for a launched implementation, inherited from its own process
|
|
6
|
+
* environment. Some implementations treat it, alongside their other launch values, as an
|
|
7
|
+
* all-or-nothing launch identity.
|
|
8
|
+
*/
|
|
9
|
+
export const PAGER_MCP_URL_ENVIRONMENT = "PAGER_MCP_URL";
|
|
10
|
+
/**
|
|
11
|
+
* Names one implementation's own broker connection setting, distinct from
|
|
12
|
+
* {@link PAGER_MCP_URL_ENVIRONMENT}.
|
|
13
|
+
*
|
|
14
|
+
* Publishing that implementation's own broker URL under the shared `PAGER_MCP_URL` name
|
|
15
|
+
* would make any child that reads that shared name inherit it as one part of its own launch
|
|
16
|
+
* identity: with the rest of that identity absent, an all-or-nothing reader goes inactive or
|
|
17
|
+
* throws instead of self-registering. This key carries the URL instead, so that hazard does not
|
|
18
|
+
* arise.
|
|
19
|
+
*/
|
|
20
|
+
export const PAGER_BROKER_URL_ENVIRONMENT = "PAGER_BROKER_URL";
|
|
21
|
+
/** Names the single-use attachment reservation a launching process publishes to the launched one. */
|
|
22
|
+
export const PAGER_ATTACH_RESERVATION_ENVIRONMENT = "PAGER_ATTACH_RESERVATION";
|
|
23
|
+
/** Names the reserved broker identity a launching process publishes to the launched one. */
|
|
24
|
+
export const PAGER_AGENT_ID_ENVIRONMENT = "PAGER_AGENT_ID";
|
|
25
|
+
/**
|
|
26
|
+
* Read process configuration without importing the SQLite-backed composition root.
|
|
27
|
+
* @param environment - Process environment supplying runtime configuration.
|
|
28
|
+
* @param options - Explicit user-path inputs supplied by the command boundary.
|
|
29
|
+
* @returns - Resolved runtime configuration safe to consume inside editor plugin hosts.
|
|
30
|
+
*/
|
|
31
|
+
export function readRuntimeEnvironment(environment = process.env, options = {}) {
|
|
32
|
+
const homeDirectory = options.homeDirectory ?? homedir();
|
|
33
|
+
const loaded = loadPagerConfiguration({
|
|
34
|
+
homeDirectory,
|
|
35
|
+
environment,
|
|
36
|
+
...(options.platform ? { platform: options.platform } : {}),
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
processEnv: {
|
|
40
|
+
...environment,
|
|
41
|
+
[ADAPTER_HEARTBEAT_INTERVAL_ENVIRONMENT]: String(loaded.config.adapterHeartbeatIntervalMs),
|
|
42
|
+
},
|
|
43
|
+
config: loaded.config,
|
|
44
|
+
configPath: loaded.filePath,
|
|
45
|
+
storeDirectory: loaded.storeDirectory,
|
|
46
|
+
dbPath: loaded.config.databasePath,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import type { Broker } from "../broker/broker.js";
|
|
2
|
+
import { ProtocolError, type AgentId } from "../broker/protocol.js";
|
|
3
|
+
import type { ImplementationId, ImplementationLaunchPlan } from "../implementations/model.js";
|
|
4
|
+
import type { ImplementationRegistry } from "../implementations/registry.js";
|
|
5
|
+
/** Broker operations launch orchestration performs. */
|
|
6
|
+
export type LaunchBrokerPort = Pick<Broker, "registerAgentWithoutReservation" | "reserveAgent" | "teamForAgent" | "reserveAttachment" | "send" | "agentIdentity" | "reapExpiredReservations">;
|
|
7
|
+
/** Resolves an opaque implementation id to the provider that owns it. */
|
|
8
|
+
export type ImplementationResolverPort = Pick<ImplementationRegistry, "resolve">;
|
|
9
|
+
/** Identifies a terminal provider through an open composition-owned value. */
|
|
10
|
+
export type TerminalProviderName = string;
|
|
11
|
+
/** Describes the launch lifecycle state of an implementation process. */
|
|
12
|
+
export type ProcessState = "launching" | "failed";
|
|
13
|
+
/** Describes whether a launch reservation has attached to its implementation. */
|
|
14
|
+
export type AttachState = "pending" | "attached" | "failed";
|
|
15
|
+
/** Defines the user-controlled inputs required to reserve and launch an agent. */
|
|
16
|
+
export type LaunchRequest = {
|
|
17
|
+
/** Selects an implementation through the configured registry. */
|
|
18
|
+
implementationId: ImplementationId;
|
|
19
|
+
/** Identifies the parent agent owning the launch. */
|
|
20
|
+
parentId: AgentId;
|
|
21
|
+
/** Selects the team used for name resolution. */
|
|
22
|
+
teamId?: string;
|
|
23
|
+
/** Supplies the workspace-unique session name used for routing and reconnection. */
|
|
24
|
+
sessionName?: string;
|
|
25
|
+
/** Correlates an optional initial task without creating another routing name. */
|
|
26
|
+
taskId?: string;
|
|
27
|
+
/** Supplies the implementation's initial task text. */
|
|
28
|
+
initialTask?: string;
|
|
29
|
+
/** Supplies arguments passed through to the implementation. */
|
|
30
|
+
passthroughArgs?: string[];
|
|
31
|
+
/** Selects the terminal provider implementation. */
|
|
32
|
+
terminalProvider?: TerminalProviderName;
|
|
33
|
+
/** Supplies the broker endpoint injected into implementation configuration. */
|
|
34
|
+
brokerUrl: string;
|
|
35
|
+
/** Supplies the workspace path associated with the launch. */
|
|
36
|
+
workspacePath: string;
|
|
37
|
+
/** Requests reservationless workspace registration for an interactive wrapper session. */
|
|
38
|
+
selfRegistration?: boolean;
|
|
39
|
+
};
|
|
40
|
+
/** Reports either a successful launch reservation or a failed launch attempt. */
|
|
41
|
+
export type LaunchResult = {
|
|
42
|
+
/** Reports that launch setup succeeded. */ ok: true;
|
|
43
|
+
/** Identifies the reserved agent. */ agentId: AgentId;
|
|
44
|
+
/** Supplies the current routing and reconnection alias. */ alias: string;
|
|
45
|
+
/** Identifies the selected implementation. */ implementationId: ImplementationId;
|
|
46
|
+
/** Reports implementation attachment state. */ attachState: AttachState;
|
|
47
|
+
/** Reports implementation process state. */ processState: ProcessState;
|
|
48
|
+
/** Identifies the terminal provider used for launch. */ provider: TerminalProviderName;
|
|
49
|
+
/** Identifies the operating-system process when available. */ pid?: number;
|
|
50
|
+
} | {
|
|
51
|
+
/** Reports that launch setup failed. */ ok: false;
|
|
52
|
+
/** Identifies the reservation created before failure when available. */ agentId?: AgentId;
|
|
53
|
+
/** Supplies the allocated routing and reconnection alias when reservation succeeded. */ alias?: string;
|
|
54
|
+
/** Identifies the selected implementation. */ implementationId: ImplementationId;
|
|
55
|
+
/** Reports implementation attachment state. */ attachState: AttachState;
|
|
56
|
+
/** Reports implementation process state. */ processState: ProcessState;
|
|
57
|
+
/** Identifies the terminal provider used for launch. */ provider: TerminalProviderName;
|
|
58
|
+
/** Describes the launch failure. */ error: {
|
|
59
|
+
/** Identifies the failure code. */ code: string;
|
|
60
|
+
/** Explains the failure. */ message: string;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
/** Describes an observable launch lifecycle event. */
|
|
64
|
+
export type LaunchDiagnostic = {
|
|
65
|
+
/** A reservation was created for a launch. */
|
|
66
|
+
type: "reservation_created";
|
|
67
|
+
agentId: AgentId;
|
|
68
|
+
implementationId: ImplementationId;
|
|
69
|
+
provider: TerminalProviderName;
|
|
70
|
+
} | {
|
|
71
|
+
/** The implementation's process started. */
|
|
72
|
+
type: "process_spawned";
|
|
73
|
+
agentId: AgentId;
|
|
74
|
+
implementationId: ImplementationId;
|
|
75
|
+
provider: TerminalProviderName;
|
|
76
|
+
detail: {
|
|
77
|
+
pid: number | undefined;
|
|
78
|
+
};
|
|
79
|
+
} | {
|
|
80
|
+
/**
|
|
81
|
+
* A launch attempt failed at some step. A failure after the process started leaves it
|
|
82
|
+
* running; this event does not report the process itself as stopped.
|
|
83
|
+
*/
|
|
84
|
+
type: "launch_failed";
|
|
85
|
+
agentId?: AgentId;
|
|
86
|
+
implementationId: ImplementationId;
|
|
87
|
+
provider: TerminalProviderName;
|
|
88
|
+
detail: ProtocolError;
|
|
89
|
+
};
|
|
90
|
+
/** Defines the provider-facing request used to start an implementation terminal. */
|
|
91
|
+
export type TerminalLaunch = {
|
|
92
|
+
/** Identifies the reserved agent for diagnostics. */
|
|
93
|
+
agentId: AgentId;
|
|
94
|
+
/** Supplies the implementation-owned process plan. */
|
|
95
|
+
plan: ImplementationLaunchPlan;
|
|
96
|
+
/** Supplies the process environment inherited at composition. */
|
|
97
|
+
baseEnvironment: NodeJS.ProcessEnv;
|
|
98
|
+
};
|
|
99
|
+
/** Describes an explicitly supported terminal task-completion operation. */
|
|
100
|
+
export type TerminalTaskCompletion = {
|
|
101
|
+
supported: false;
|
|
102
|
+
} | {
|
|
103
|
+
/** Reports that task completion is available. */ supported: true;
|
|
104
|
+
/** Completes a terminal task. */ run(taskId: string): Promise<void>;
|
|
105
|
+
};
|
|
106
|
+
/** Represents a started terminal session and its supported control operations. */
|
|
107
|
+
export type TerminalSession = {
|
|
108
|
+
/** Identifies the provider that started the session. */
|
|
109
|
+
provider: TerminalProviderName;
|
|
110
|
+
/** Identifies the operating-system process when available. */
|
|
111
|
+
pid?: number;
|
|
112
|
+
/** Exposes task completion as an explicit capability. */
|
|
113
|
+
taskCompletion: TerminalTaskCompletion;
|
|
114
|
+
/** Resolves when a foreground process exits; absent for detached or externally hosted terminals. */
|
|
115
|
+
exit?: Promise<{
|
|
116
|
+
code: number | null;
|
|
117
|
+
signal: NodeJS.Signals | null;
|
|
118
|
+
}>;
|
|
119
|
+
};
|
|
120
|
+
/** Launches terminals from implementation-owned plans. */
|
|
121
|
+
export interface TerminalProvider {
|
|
122
|
+
/** Identifies this terminal provider. */
|
|
123
|
+
readonly name: TerminalProviderName;
|
|
124
|
+
/** Orders interactive candidates; the highest value is tried first and an absent value counts as zero. */
|
|
125
|
+
readonly interactivePriority?: number;
|
|
126
|
+
/** Starts a terminal session without inspecting implementation identity. */
|
|
127
|
+
launch(request: TerminalLaunch): Promise<TerminalSession>;
|
|
128
|
+
/** Reports whether an optional provider can serve an interactive launch. */
|
|
129
|
+
available?(): Promise<boolean>;
|
|
130
|
+
}
|
|
131
|
+
/** What an implementation's conventionally named `terminal.js` module exports for discovery to load. */
|
|
132
|
+
export type TerminalProviderModule = {
|
|
133
|
+
/**
|
|
134
|
+
* Build the implementation's terminal provider.
|
|
135
|
+
* @param environment - Process environment the launch inherits, carrying any provider settings.
|
|
136
|
+
* @returns - Provider ready to launch plans.
|
|
137
|
+
*/
|
|
138
|
+
createTerminalProvider(environment: NodeJS.ProcessEnv): TerminalProvider;
|
|
139
|
+
};
|
|
140
|
+
/** Starts one detached child process for the direct terminal provider. */
|
|
141
|
+
export type ProcessSpawner = (command: string, args: string[], options: {
|
|
142
|
+
cwd: string;
|
|
143
|
+
env: NodeJS.ProcessEnv;
|
|
144
|
+
stdio: "ignore";
|
|
145
|
+
detached: true;
|
|
146
|
+
}) => {
|
|
147
|
+
/** Identifies the child process when assigned by the operating system. */ pid: number | undefined;
|
|
148
|
+
/** Detaches the child from the parent event loop. */ unref(): void;
|
|
149
|
+
};
|
|
150
|
+
/** Direct local-process terminal provider. */
|
|
151
|
+
export declare class DirectTerminalProvider implements TerminalProvider {
|
|
152
|
+
#private;
|
|
153
|
+
/** Identifies the direct local-process provider. */
|
|
154
|
+
readonly name = "direct";
|
|
155
|
+
/**
|
|
156
|
+
* Construct a direct provider with an explicit process boundary.
|
|
157
|
+
* @param spawnProcess - Starts the child process; the provider calls `unref` on it, so the parent may exit while it runs.
|
|
158
|
+
*/
|
|
159
|
+
constructor(spawnProcess: ProcessSpawner);
|
|
160
|
+
/**
|
|
161
|
+
* Launch one implementation plan as a direct child process.
|
|
162
|
+
* @param request - Plan to run; its sensitive environment overrides its environment, which overrides the base environment.
|
|
163
|
+
* @returns - Session with no exit promise, because the child is detached.
|
|
164
|
+
*/
|
|
165
|
+
launch(request: TerminalLaunch): Promise<TerminalSession>;
|
|
166
|
+
}
|
|
167
|
+
/** Starts one foreground child process with inherited terminal streams. */
|
|
168
|
+
export type ForegroundProcessSpawner = (command: string, args: string[], options: {
|
|
169
|
+
cwd: string;
|
|
170
|
+
env: NodeJS.ProcessEnv;
|
|
171
|
+
stdio: "inherit";
|
|
172
|
+
detached: false;
|
|
173
|
+
}) => {
|
|
174
|
+
/** Identifies the child process when assigned by the operating system. */ pid: number | undefined;
|
|
175
|
+
/** Registers a one-shot process event listener. */
|
|
176
|
+
once(event: "error", listener: (error: Error) => void): void;
|
|
177
|
+
/** Registers a one-shot exit listener. */
|
|
178
|
+
once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): void;
|
|
179
|
+
};
|
|
180
|
+
/** Foreground local-process provider that hands the current terminal to the implementation. */
|
|
181
|
+
export declare class ForegroundTerminalProvider implements TerminalProvider {
|
|
182
|
+
#private;
|
|
183
|
+
/** Identifies the inherited-terminal provider. */
|
|
184
|
+
readonly name = "foreground";
|
|
185
|
+
/**
|
|
186
|
+
* Construct the provider around an explicit foreground process boundary.
|
|
187
|
+
* @param spawnProcess - Starts the child with inherited terminal streams; its `error` and `exit` events settle the session's exit promise.
|
|
188
|
+
*/
|
|
189
|
+
constructor(spawnProcess: ForegroundProcessSpawner);
|
|
190
|
+
/**
|
|
191
|
+
* Launch one implementation in the caller's foreground terminal.
|
|
192
|
+
* @param request - Plan to run; its sensitive environment overrides its environment, which overrides the base environment.
|
|
193
|
+
* @returns - Session whose exit promise resolves with the child's code and signal, and rejects if the child cannot start.
|
|
194
|
+
*/
|
|
195
|
+
launch(request: TerminalLaunch): Promise<TerminalSession>;
|
|
196
|
+
}
|
|
197
|
+
/** Reserves agents, starts their terminals, and binds their attachments. */
|
|
198
|
+
export declare class LaunchService {
|
|
199
|
+
#private;
|
|
200
|
+
/**
|
|
201
|
+
* Construct launch orchestration from neutral registries and terminal providers.
|
|
202
|
+
* @param broker - Durable broker instance that owns message state.
|
|
203
|
+
* @param implementations - Registry resolving opaque implementation ids.
|
|
204
|
+
* @param providers - Terminal backends a request can select by name; a later provider replaces an earlier one of the same name.
|
|
205
|
+
* @param environment - Process environment inherited by terminal providers.
|
|
206
|
+
*/
|
|
207
|
+
constructor(broker: LaunchBrokerPort, implementations: ImplementationResolverPort, providers: readonly TerminalProvider[], environment: NodeJS.ProcessEnv);
|
|
208
|
+
/**
|
|
209
|
+
* Reserve and launch one agent through its implementation and terminal providers.
|
|
210
|
+
* @param request - Validated neutral launch request.
|
|
211
|
+
* @returns - Public launch result without process-binding values.
|
|
212
|
+
*/
|
|
213
|
+
launchAgent(request: LaunchRequest): Promise<LaunchResult>;
|
|
214
|
+
/**
|
|
215
|
+
* Wait for a foreground process to exit when its provider exposes one.
|
|
216
|
+
* @param agentId - Launched agent whose foreground disposition is requested.
|
|
217
|
+
* @returns - Child exit disposition, or undefined for detached and external terminals.
|
|
218
|
+
*/
|
|
219
|
+
waitForExit(agentId: AgentId): Promise<{
|
|
220
|
+
code: number | null;
|
|
221
|
+
signal: NodeJS.Signals | null;
|
|
222
|
+
}> | undefined;
|
|
223
|
+
/**
|
|
224
|
+
* Return launch diagnostics for operational output.
|
|
225
|
+
* @returns - Lifecycle events in observation order.
|
|
226
|
+
*/
|
|
227
|
+
diagnostics(): LaunchDiagnostic[];
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Render stable human-facing launch output.
|
|
231
|
+
* @param result - Launch outcome to render.
|
|
232
|
+
* @param json - Whether to emit the machine-readable representation.
|
|
233
|
+
* @returns - Newline-terminated text: the JSON result when `json`, otherwise a one-line summary.
|
|
234
|
+
*/
|
|
235
|
+
export declare function renderLaunchResult(result: LaunchResult, json?: boolean): string;
|