@stratusagent/cli 0.11.2 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/README.md +13 -7
  2. package/dist/approvals.d.ts +87 -0
  3. package/dist/approvals.d.ts.map +1 -0
  4. package/dist/approvals.js +315 -0
  5. package/dist/approvals.js.map +1 -0
  6. package/dist/commands/agent-new.d.ts +22 -0
  7. package/dist/commands/agent-new.d.ts.map +1 -0
  8. package/dist/commands/agent-new.js +154 -0
  9. package/dist/commands/agent-new.js.map +1 -0
  10. package/dist/commands/agents.d.ts +4 -0
  11. package/dist/commands/agents.d.ts.map +1 -0
  12. package/dist/commands/agents.js +90 -0
  13. package/dist/commands/agents.js.map +1 -0
  14. package/dist/commands/chat.d.ts +4 -0
  15. package/dist/commands/chat.d.ts.map +1 -0
  16. package/dist/commands/chat.js +224 -0
  17. package/dist/commands/chat.js.map +1 -0
  18. package/dist/commands/credential.d.ts +22 -0
  19. package/dist/commands/credential.d.ts.map +1 -0
  20. package/dist/commands/credential.js +93 -0
  21. package/dist/commands/credential.js.map +1 -0
  22. package/dist/commands/dashboard.d.ts +14 -0
  23. package/dist/commands/dashboard.d.ts.map +1 -0
  24. package/dist/commands/dashboard.js +195 -0
  25. package/dist/commands/dashboard.js.map +1 -0
  26. package/dist/commands/doctor.d.ts +40 -0
  27. package/dist/commands/doctor.d.ts.map +1 -0
  28. package/dist/commands/doctor.js +357 -0
  29. package/dist/commands/doctor.js.map +1 -0
  30. package/dist/commands/grants.d.ts +19 -0
  31. package/dist/commands/grants.d.ts.map +1 -0
  32. package/dist/commands/grants.js +128 -0
  33. package/dist/commands/grants.js.map +1 -0
  34. package/dist/commands/logs.d.ts +9 -0
  35. package/dist/commands/logs.d.ts.map +1 -0
  36. package/dist/commands/logs.js +58 -0
  37. package/dist/commands/logs.js.map +1 -0
  38. package/dist/commands/memory.d.ts +20 -0
  39. package/dist/commands/memory.d.ts.map +1 -0
  40. package/dist/commands/memory.js +110 -0
  41. package/dist/commands/memory.js.map +1 -0
  42. package/dist/commands/plugins.d.ts +91 -0
  43. package/dist/commands/plugins.d.ts.map +1 -0
  44. package/dist/commands/plugins.js +359 -0
  45. package/dist/commands/plugins.js.map +1 -0
  46. package/dist/commands/restart.d.ts +4 -0
  47. package/dist/commands/restart.d.ts.map +1 -0
  48. package/dist/commands/restart.js +25 -0
  49. package/dist/commands/restart.js.map +1 -0
  50. package/dist/commands/schedules.d.ts +11 -0
  51. package/dist/commands/schedules.d.ts.map +1 -0
  52. package/dist/commands/schedules.js +50 -0
  53. package/dist/commands/schedules.js.map +1 -0
  54. package/dist/commands/serve.d.ts +4 -0
  55. package/dist/commands/serve.d.ts.map +1 -0
  56. package/dist/commands/serve.js +612 -0
  57. package/dist/commands/serve.js.map +1 -0
  58. package/dist/commands/service.d.ts +9 -0
  59. package/dist/commands/service.d.ts.map +1 -0
  60. package/dist/commands/service.js +97 -0
  61. package/dist/commands/service.js.map +1 -0
  62. package/dist/commands/session.d.ts +9 -0
  63. package/dist/commands/session.d.ts.map +1 -0
  64. package/dist/commands/session.js +25 -0
  65. package/dist/commands/session.js.map +1 -0
  66. package/dist/commands/setup.d.ts +5 -0
  67. package/dist/commands/setup.d.ts.map +1 -0
  68. package/dist/commands/setup.js +2412 -0
  69. package/dist/commands/setup.js.map +1 -0
  70. package/dist/commands/skills.d.ts +15 -0
  71. package/dist/commands/skills.d.ts.map +1 -0
  72. package/dist/commands/skills.js +272 -0
  73. package/dist/commands/skills.js.map +1 -0
  74. package/dist/commands/template.d.ts +4 -0
  75. package/dist/commands/template.d.ts.map +1 -0
  76. package/dist/commands/template.js +575 -0
  77. package/dist/commands/template.js.map +1 -0
  78. package/dist/commands/update.d.ts +21 -0
  79. package/dist/commands/update.d.ts.map +1 -0
  80. package/dist/commands/update.js +291 -0
  81. package/dist/commands/update.js.map +1 -0
  82. package/dist/daemon.d.ts +74 -0
  83. package/dist/daemon.d.ts.map +1 -0
  84. package/dist/daemon.js +192 -0
  85. package/dist/daemon.js.map +1 -0
  86. package/dist/environment.d.ts +108 -0
  87. package/dist/environment.d.ts.map +1 -0
  88. package/dist/environment.js +2 -0
  89. package/dist/environment.js.map +1 -0
  90. package/dist/events.d.ts +17 -0
  91. package/dist/events.d.ts.map +1 -0
  92. package/dist/events.js +87 -0
  93. package/dist/events.js.map +1 -0
  94. package/dist/help.d.ts +2 -0
  95. package/dist/help.d.ts.map +1 -0
  96. package/dist/help.js +266 -0
  97. package/dist/help.js.map +1 -0
  98. package/dist/index.d.ts +31 -624
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +38 -6981
  101. package/dist/index.js.map +1 -1
  102. package/dist/io.d.ts +16 -0
  103. package/dist/io.d.ts.map +1 -0
  104. package/dist/io.js +45 -0
  105. package/dist/io.js.map +1 -0
  106. package/dist/loaders.d.ts +31 -0
  107. package/dist/loaders.d.ts.map +1 -0
  108. package/dist/loaders.js +56 -0
  109. package/dist/loaders.js.map +1 -0
  110. package/dist/main.d.ts +8 -0
  111. package/dist/main.d.ts.map +1 -0
  112. package/dist/main.js +214 -0
  113. package/dist/main.js.map +1 -0
  114. package/dist/npm.d.ts +66 -0
  115. package/dist/npm.d.ts.map +1 -0
  116. package/dist/npm.js +201 -0
  117. package/dist/npm.js.map +1 -0
  118. package/dist/parse.d.ts +231 -0
  119. package/dist/parse.d.ts.map +1 -0
  120. package/dist/parse.js +1082 -0
  121. package/dist/parse.js.map +1 -0
  122. package/dist/plugin-catalog.d.ts +35 -0
  123. package/dist/plugin-catalog.d.ts.map +1 -0
  124. package/dist/plugin-catalog.js +58 -0
  125. package/dist/plugin-catalog.js.map +1 -0
  126. package/dist/preflight.d.ts +60 -0
  127. package/dist/preflight.d.ts.map +1 -0
  128. package/dist/preflight.js +102 -0
  129. package/dist/preflight.js.map +1 -0
  130. package/dist/prompter.d.ts +84 -0
  131. package/dist/prompter.d.ts.map +1 -0
  132. package/dist/prompter.js +347 -0
  133. package/dist/prompter.js.map +1 -0
  134. package/dist/roster.d.ts +57 -0
  135. package/dist/roster.d.ts.map +1 -0
  136. package/dist/roster.js +78 -0
  137. package/dist/roster.js.map +1 -0
  138. package/dist/runtime.d.ts +59 -0
  139. package/dist/runtime.d.ts.map +1 -0
  140. package/dist/runtime.js +266 -0
  141. package/dist/runtime.js.map +1 -0
  142. package/dist/slack.d.ts +26 -0
  143. package/dist/slack.d.ts.map +1 -0
  144. package/dist/slack.js +113 -0
  145. package/dist/slack.js.map +1 -0
  146. package/dist/source.d.ts +24 -0
  147. package/dist/source.d.ts.map +1 -0
  148. package/dist/source.js +80 -0
  149. package/dist/source.js.map +1 -0
  150. package/dist/supervisor.d.ts +69 -0
  151. package/dist/supervisor.d.ts.map +1 -0
  152. package/dist/supervisor.js +218 -0
  153. package/dist/supervisor.js.map +1 -0
  154. package/dist/trusted-config.d.ts +71 -0
  155. package/dist/trusted-config.d.ts.map +1 -0
  156. package/dist/trusted-config.js +118 -0
  157. package/dist/trusted-config.js.map +1 -0
  158. package/package.json +25 -23
@@ -0,0 +1,612 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { createFileCommandWhitelist, createPermissionPolicy, describeCommandScope, describeOriginScope, describeToolGrant, } from '@stratusagent/permissions';
10
+ import { agentsDirPath, loadChannelCredentials, readProcessEnv, logsDirPath, resolveAgentApprovals, resolveAgentPrincipals, servedRuntimes, } from '@stratusagent/state';
11
+ import { createLogWriter, truncateRedirectLogs } from "../logs.js";
12
+ import { describePrincipals, describeApprovers } from "../approvals.js";
13
+ import { HomeHeldError, legacyDaemonServing, describeHeldHome } from "../daemon.js";
14
+ import { formatEvent, eventDetail } from "../events.js";
15
+ import { writeLine } from "../io.js";
16
+ import { loadSlackAdapter, loadControlApi } from "../loaders.js";
17
+ import { warnOnCredentialOverride } from "../runtime.js";
18
+ import { RESTART_EXIT_CODE, UNDRAINED_RESTART_EXIT_CODE, SUPERVISED_ENV, BOUND_API_PORT_ENV, defaultSupervisorLink, superviseRestarts, } from "../supervisor.js";
19
+ import { loadServeApprovals, loadServePrincipals, loadServeApi, loadServePlugins, } from "../trusted-config.js";
20
+ export const runServe = async (command, streams, env = {}) => {
21
+ // First, before anything that can throw. A broken install makes the
22
+ // gateway import below fail, the manager restarts, and the CLI's error
23
+ // and help text append to the redirect file again — the crash loop this
24
+ // bounding exists for. Running it after the import would skip exactly
25
+ // that case.
26
+ if (command.logToFile !== false) {
27
+ await truncateRedirectLogs(logsDirPath(env)).catch(() => undefined);
28
+ }
29
+ // Loaded lazily: the gateway pulls in node:sqlite, which every other CLI
30
+ // command neither needs nor should pay for (Node still prints an
31
+ // experimental warning for it).
32
+ const { createGateway, claimHome, HomeClaimedError } = await import('@stratusagent/gateway');
33
+ // Before anything of this daemon's is written or opened: a second daemon
34
+ // on this home is refused here, with no log line, no store, and no sweep
35
+ // or firing of its own.
36
+ let claim;
37
+ try {
38
+ claim = claimHome(env);
39
+ }
40
+ catch (error) {
41
+ if (error instanceof HomeClaimedError) {
42
+ throw new HomeHeldError(await describeHeldHome(env));
43
+ }
44
+ throw error;
45
+ }
46
+ let outcome;
47
+ try {
48
+ // The one daemon the claim cannot see: one that predates it.
49
+ if (await legacyDaemonServing(env)) {
50
+ throw new HomeHeldError(await describeHeldHome(env));
51
+ }
52
+ outcome = await serveHeldHome(command, streams, env, createGateway);
53
+ }
54
+ finally {
55
+ // After everything: the store closed by stop(), or whatever a throw
56
+ // reached — a preflight that rejected before the gateway existed
57
+ // included, so a host that calls runServe again is not refused for a
58
+ // daemon that never started. And never sooner, so a replacement cannot
59
+ // open the store while this one still writes.
60
+ claim.release();
61
+ }
62
+ // An announced restart, once the home is let go — the replacement claims
63
+ // it next. A daemon the supervisor started asks it for the next one by
64
+ // exiting; the first daemon becomes the supervisor itself. Either way the
65
+ // process the service manager (or the terminal) started is what stays.
66
+ if (outcome.code === RESTART_EXIT_CODE && !readProcessEnv(env)[SUPERVISED_ENV]) {
67
+ return superviseRestarts(command, { ...(outcome.boundApiPort !== undefined ? { boundApiPort: outcome.boundApiPort } : {}), sessions: outcome.sessions }, streams, env);
68
+ }
69
+ return outcome.code;
70
+ };
71
+ const serveHeldHome = async (command, streams, env, createGateway) => {
72
+ // Under a service manager the daemon's stdout is gone, so everything it
73
+ // says is also written to ~/.stratus/logs — that file is what `stratus
74
+ // logs` reads, and the only record of an overnight run.
75
+ const logWriter = command.logToFile === false
76
+ ? undefined
77
+ : createLogWriter({
78
+ dir: logsDirPath(env),
79
+ onError: (error) => writeLine(streams.stderr, `Warning: could not write the log file (${error instanceof Error ? error.message : String(error)}); continuing.`),
80
+ });
81
+ const log = (line) => {
82
+ writeLine(streams.stdout, line);
83
+ void logWriter?.write({ ts: new Date().toISOString(), level: 'info', msg: line });
84
+ };
85
+ const warn = (line) => {
86
+ writeLine(streams.stderr, `Warning: ${line}`);
87
+ void logWriter?.write({ ts: new Date().toISOString(), level: 'warn', msg: line });
88
+ };
89
+ // Agents with stored Slack tokens go live in Slack automatically — the
90
+ // tokens are gateway infrastructure secrets in the channels namespace of
91
+ // ~/.stratus/credentials.json (see @stratusagent/channel-slack's README
92
+ // for the 2-minute per-agent app setup).
93
+ // The approval policy and the Slack approver sets come from the same
94
+ // config block, resolved once here: the daemon must not answer "who can
95
+ // approve this" differently from "is anyone being asked at all".
96
+ const approvalsConfig = await loadServeApprovals(env, command.configPath, warn);
97
+ const approvalMode = command.approvals ?? approvalsConfig.mode ?? 'headless';
98
+ const principalsConfig = await loadServePrincipals(env, command.configPath, warn);
99
+ // Read here rather than inside the gateway for the same reason as the two
100
+ // blocks above: the trust boundary is a property of *which file* said it,
101
+ // and this is where the file precedence is already understood.
102
+ const pluginsConfig = await loadServePlugins(env, command.configPath, warn);
103
+ // Every kind of grant an agent holds — command scopes, origins, standing
104
+ // tool grants — in one file per agent beside its soul, through one store
105
+ // instance for the whole daemon. One instance, because the store caches
106
+ // each file for the life of the process: the control API's list and
107
+ // revoke go through this same object, which is what lets a revoke take
108
+ // effect on the policy's very next decision rather than at the next
109
+ // restart. A whitelist that exists and will not read is said here, once,
110
+ // and never written over — the daemon's log is where a grant list going
111
+ // quiet would otherwise go unnoticed.
112
+ const grantStore = createFileCommandWhitelist({ directory: agentsDirPath(env), warn });
113
+ // The control API is a channel adapter like any other: started after the
114
+ // roster loads, stopped before the store drains. It is optional because
115
+ // installing it is how an operator says they want a port open.
116
+ const apiConfig = await loadServeApi(env, command.configPath, warn);
117
+ const apiWanted = command.api ?? apiConfig.enabled ?? true;
118
+ // Typed as the seam, not as whatever the first push happens to be: the
119
+ // list holds the control API and the Slack adapter alike.
120
+ const controlApiChannels = [];
121
+ /** The API adapter itself, for what the seam does not carry: its address, and the sessions it hands across a restart. */
122
+ let boundApi;
123
+ if (apiWanted) {
124
+ const createControlApi = await loadControlApi();
125
+ // Resolved into locals first. Inlined, `a ?? b !== undefined` parses as
126
+ // `a ?? (b !== undefined)` — so an explicit `--api-port 0`, which is how
127
+ // you ask for any free port, was falsy and fell through to the default.
128
+ // Everything still bound and every test still passed, on whichever port
129
+ // nobody happened to be using.
130
+ const apiHost = command.apiHost ?? apiConfig.host;
131
+ const requestedPort = command.apiPort ?? apiConfig.port;
132
+ // The port the last daemon bound, from the supervisor that started
133
+ // this one — taken only where this daemon's own request is still for
134
+ // any free port. See BOUND_API_PORT_ENV.
135
+ const hinted = Number(readProcessEnv(env)[BOUND_API_PORT_ENV]);
136
+ const apiPort = requestedPort === 0 && Number.isInteger(hinted) && hinted > 0 ? hinted : requestedPort;
137
+ if (createControlApi) {
138
+ const api = createControlApi({
139
+ env,
140
+ ...(apiHost !== undefined ? { host: apiHost } : {}),
141
+ ...(apiPort !== undefined ? { port: apiPort } : {}),
142
+ ...(command.configPath ? { configPath: command.configPath } : {}),
143
+ grants: grantStore,
144
+ log,
145
+ warn,
146
+ });
147
+ boundApi = api;
148
+ controlApiChannels.push(api);
149
+ }
150
+ else if (command.api === true || apiConfig.enabled === true) {
151
+ // Only when someone asked for it explicitly. A daemon that was never
152
+ // told to serve an API should not complain about not having one.
153
+ warn('the control API was requested, but @stratusagent/control-api is not installed. '
154
+ + 'Run `npm install -g @stratusagent/control-api` to bring it online; starting without it.');
155
+ }
156
+ }
157
+ // Listening before anything else is awaited: what the supervisor hands
158
+ // this daemon is queued in the channel until then, and the API keeps it
159
+ // until it is serving.
160
+ const supervised = Boolean(readProcessEnv(env)[SUPERVISED_ENV]);
161
+ const link = env.supervisorLink ?? defaultSupervisorLink;
162
+ if (supervised) {
163
+ link.receive((message) => {
164
+ if (message.type === 'stratusd.sessions') {
165
+ boundApi?.adoptSessions(message.sessions);
166
+ }
167
+ });
168
+ }
169
+ const channelCredentials = await loadChannelCredentials(env);
170
+ const slackAgents = Object.entries(channelCredentials.slack ?? {});
171
+ const channels = [...controlApiChannels];
172
+ // Tracked on its own, never as `channels.length`: the list now holds the
173
+ // control API too, and "can anyone be asked for an approval" is a question
174
+ // about the Slack adapter specifically. Reading it off the list length
175
+ // would tell a daemon with an API and no Slack app that every agent is
176
+ // reachable, and its gated calls would park with nobody rendering them.
177
+ let slackAdapterUp = false;
178
+ if (slackAgents.length > 0) {
179
+ // Channel packages are optional peers: the CLI never bundles a
180
+ // transport nobody asked for (the Slack SDKs alone are ~9 MB). A
181
+ // missing one degrades like a broken app does — the daemon serves
182
+ // every other channel — with an actionable line instead of a
183
+ // module-not-found stack.
184
+ const adapter = await loadSlackAdapter();
185
+ if (adapter) {
186
+ slackAdapterUp = true;
187
+ channels.push(adapter({
188
+ agents: slackAgents.map(([agentId, tokens]) => {
189
+ const route = resolveAgentApprovals(approvalsConfig, agentId);
190
+ const principals = resolveAgentPrincipals(principalsConfig, agentId);
191
+ return {
192
+ agentId,
193
+ appToken: tokens.appToken,
194
+ botToken: tokens.botToken,
195
+ ...(route.slackApprovers ? { approvers: route.slackApprovers } : {}),
196
+ ...(route.slackChannel ? { approvalChannel: route.slackChannel } : {}),
197
+ ...(principals.slackUsers ? { principals: principals.slackUsers } : {}),
198
+ };
199
+ }),
200
+ log,
201
+ warn,
202
+ }));
203
+ }
204
+ else {
205
+ warn(`Slack tokens are stored for ${slackAgents.length} agent(s), but @stratusagent/channel-slack is not installed. `
206
+ + 'Run `npm install -g @stratusagent/channel-slack` to bring them online; starting without the Slack channel.');
207
+ }
208
+ }
209
+ // A daemon is the costliest place for a silently demoted subscription:
210
+ // every dispatch for as long as it runs, with nobody watching. The
211
+ // gateway resolves each agent's soul independently on dispatch, so an
212
+ // agent pinning anthropic can pick up an environment key even when the
213
+ // daemon's own default is openai — checking only the default selection
214
+ // would miss exactly the agent that is being billed. Each distinct
215
+ // selection is resolved once here, and duplicate warnings are collapsed
216
+ // so a ten-agent roster does not print ten identical lines.
217
+ {
218
+ const warned = new Set();
219
+ const collect = (line) => {
220
+ if (warned.has(line)) {
221
+ return;
222
+ }
223
+ warned.add(line);
224
+ // Through `warn`, not straight to stderr: under a service manager
225
+ // stderr is gone, and a cost warning that only exists there is
226
+ // invisible in exactly the deployment it matters for. `warn` adds
227
+ // its own prefix, so the one already on the line comes off.
228
+ warn(line.replace(/^Warning: /, ''));
229
+ };
230
+ const captured = {
231
+ stdout: { write: () => true },
232
+ stderr: { write: (chunk) => { collect(chunk.replace(/\n$/, '')); return true; } },
233
+ };
234
+ // A pinned soul does not merely add a provider — the gateway DEMOTES
235
+ // the daemon-wide defaults it outranks, including STRATUS_PROVIDER, so
236
+ // each served runtime is resolved the way a dispatch resolves it.
237
+ for (const served of await servedRuntimes(env, command.configPath)) {
238
+ await warnOnCredentialOverride(served.runtime, captured, served.env);
239
+ }
240
+ }
241
+ // The daemon had no policy at all: createGateway falls back to
242
+ // AllowAllApprovalPolicy, so every tool call from every agent
243
+ // auto-approved, indefinitely, with nobody watching. That was survivable
244
+ // while `serve` was something you ran in a terminal you were sitting at;
245
+ // it is not, now that setup installs it under launchd by default.
246
+ //
247
+ // There is no terminal behind a service manager, so the choice is
248
+ // between refusing every gated call (`headless`) and parking the turn to
249
+ // ask through a channel (`remote`). Headless stays the default: a daemon
250
+ // that starts waiting on people who were never told they are on the hook
251
+ // hangs turns instead of refusing them. Every refusal is logged — an
252
+ // unattended denial that appears nowhere reads like an agent that decided
253
+ // not to bother.
254
+ const onDecision = (decision) => {
255
+ if (decision.allowed) {
256
+ // A call that ran because somebody once said "always" is the one
257
+ // allowed decision the trace records: it is how something happened
258
+ // unattended, which is what an incident reconstruction needs to tell
259
+ // apart from a tool that was simply safe. Name and date, never input.
260
+ if (decision.grant) {
261
+ const by = decision.grant.grantedBy ? ` by ${decision.grant.grantedBy}` : '';
262
+ log(`${decision.agentId}: ${decision.toolName} ran under a standing grant (${describeToolGrant(decision.grant)}, granted ${decision.grant.grantedAt}${by}) (session ${decision.sessionId})`);
263
+ }
264
+ return;
265
+ }
266
+ warn(`${decision.agentId}: ${decision.reason} (session ${decision.sessionId})`);
267
+ };
268
+ // A factory, not a policy: remote mode parks turns on a transport the
269
+ // gateway owns, so the policy cannot exist until the gateway is building
270
+ // it. Headless takes the same path so there is one construction site.
271
+ // The command-scope engine, which only has a caller once a shell pack is
272
+ // installed. Wired unconditionally because it costs nothing without one:
273
+ // a tool that carries no command string is judged by its risk exactly as
274
+ // before. The whitelist lives beside the agent's soul, per agent.
275
+ const commands = {
276
+ whitelist: grantStore,
277
+ onScopeRemembered: ({ agentId, scope }) => {
278
+ // An approval that widens what runs unattended, for every future
279
+ // session, is precisely the decision that must not be the one leaving
280
+ // no trace.
281
+ log(`${agentId}: "${describeCommandScope(scope)}" now runs without asking`);
282
+ },
283
+ };
284
+ // The origin-scope engine, whose grants live in the same file as the
285
+ // command scopes: one place an operator looks to see what an agent may
286
+ // do unattended. Wired unconditionally for the same reason — a tool that
287
+ // names no origin is judged by its risk exactly as before.
288
+ const origins = {
289
+ whitelist: grantStore,
290
+ onScopeRemembered: ({ agentId, scope }) => {
291
+ log(`${agentId}: ${describeOriginScope(scope)} is now acted on without asking`);
292
+ },
293
+ };
294
+ const approvals = (transport) => {
295
+ // The standing-grant engine, in the same file again — and the tool's
296
+ // contributor from the gateway, so a grant records which package's
297
+ // tool the operator said yes to and stops applying when that changes.
298
+ const grants = {
299
+ store: grantStore,
300
+ contributorOf: transport.contributorOf,
301
+ onGranted: ({ agentId, grant }) => {
302
+ log(`${agentId}: ${describeToolGrant(grant)} now runs without asking, until revoked${grant.grantedBy ? ` (granted by ${grant.grantedBy})` : ''}`);
303
+ },
304
+ };
305
+ return createPermissionPolicy(
306
+ // The destination scope rides along in BOTH modes — it is what lets a
307
+ // scheduled turn report to the channel a human approved with the
308
+ // schedule, and headless (where every other gated call is refused) is
309
+ // exactly the deployment it exists for. So do the grants: a standing
310
+ // grant is the only path a scope-less gated tool has to running
311
+ // unattended, and headless is where that matters.
312
+ approvalMode === 'remote'
313
+ ? { mode: 'remote', request: transport.request, onDecision, commands, origins, grants, destinations: transport.destinations }
314
+ : { mode: 'headless', onDecision, commands, origins, grants, destinations: transport.destinations });
315
+ };
316
+ if (approvalMode === 'remote') {
317
+ // Only agents whose channel actually came up can be asked: tokens on
318
+ // disk with the Slack package missing means nothing renders the
319
+ // request, and the turn discovers that by hanging.
320
+ const askable = slackAdapterUp ? slackAgents.map(([agentId]) => agentId) : [];
321
+ log(`approvals: remote — gated calls are parked and asked in Slack (${describeApprovers(approvalsConfig, askable)})`);
322
+ }
323
+ if (slackAdapterUp) {
324
+ // Said at startup, because the failure it names is silent otherwise: a
325
+ // daemon with no principals serves every Slack message as `unknown`,
326
+ // and the operator finds out when their agent's memory reads that way.
327
+ log(`provenance: ${describePrincipals(principalsConfig, slackAgents.map(([agentId]) => agentId))}`);
328
+ }
329
+ /**
330
+ * The one signal handler this daemon has, for the whole of its life —
331
+ * installed by the wait below, removed in the finally after the drain.
332
+ * See the wait for why it is never `once` and never removed sooner.
333
+ */
334
+ let stopSignal;
335
+ let repeatWarned = false;
336
+ // The gateway's restart hands the process back here once it has stopped:
337
+ // the outcome is kept and the wait below released, and the tail of this
338
+ // function decides what "come back" means for this process.
339
+ let restart;
340
+ /** A signal or the host's abort asked for a stop — set when the wait ends for that reason. */
341
+ let stopRequested = false;
342
+ let requestShutdown = () => { };
343
+ const shutdownRequested = new Promise((resolve) => {
344
+ requestShutdown = resolve;
345
+ });
346
+ const gateway = createGateway({
347
+ env,
348
+ approvals,
349
+ onRestart: (outcome) => {
350
+ restart = outcome;
351
+ requestShutdown();
352
+ },
353
+ ...(Object.keys(pluginsConfig).length > 0
354
+ ? {
355
+ plugins: pluginsConfig,
356
+ // Resolved from *here*, not from inside the gateway.
357
+ // `import.meta.resolve` answers relative to the module that calls
358
+ // it, and a plugin is installed alongside the thing the operator
359
+ // installed — this CLI. Letting the gateway resolve from its own
360
+ // location works only where the layout happens to be flat.
361
+ pluginHost: {
362
+ resolve: (specifier) => import.meta.resolve(specifier),
363
+ import: (specifier) => import(__rewriteRelativeImportExtension(specifier)),
364
+ },
365
+ }
366
+ : {}),
367
+ ...(approvalsConfig.timeoutMs !== undefined ? { approvalTimeoutMs: approvalsConfig.timeoutMs } : {}),
368
+ ...(command.configPath ? { selection: { configPath: command.configPath } } : {}),
369
+ ...(command.idleTimeoutMs !== undefined ? { idleTimeoutMs: command.idleTimeoutMs } : {}),
370
+ ...(channels.length > 0 ? { channels } : {}),
371
+ log,
372
+ warn,
373
+ });
374
+ if (command.events) {
375
+ gateway.bus.subscribe((event) => {
376
+ const line = formatEvent(event);
377
+ if (line) {
378
+ writeLine(streams.stdout, line);
379
+ }
380
+ });
381
+ }
382
+ if (logWriter) {
383
+ // Only session.created carries the agent id, so it seeds a map the
384
+ // later events in that session read from. A session resumed after a
385
+ // restart never re-creates, so an unmapped id falls back to the
386
+ // durable store — which is exactly the case where attribution matters.
387
+ const agentBySession = new Map();
388
+ // EventBus.emit awaits its subscribers, and a streaming provider awaits
389
+ // the delta sink — so anything awaited here lands on the critical path
390
+ // of every streamed token. This handler is deliberately synchronous:
391
+ // provider.delta is dropped outright (it carries no detail worth
392
+ // keeping, one record per token), the timestamp is taken now, and the
393
+ // write is queued without awaiting it.
394
+ gateway.bus.subscribe((event) => {
395
+ if (event.type === 'provider.delta') {
396
+ return;
397
+ }
398
+ const ts = new Date().toISOString();
399
+ if (event.type === 'session.created') {
400
+ agentBySession.set(event.sessionId, event.agentId);
401
+ }
402
+ const detail = eventDetail(event);
403
+ const base = {
404
+ ts,
405
+ level: 'event',
406
+ event: event.type,
407
+ sessionId: event.sessionId,
408
+ ...(detail ? { detail } : {}),
409
+ };
410
+ const known = agentBySession.get(event.sessionId);
411
+ if (known) {
412
+ void logWriter.write({ ...base, agentId: known });
413
+ }
414
+ else {
415
+ // A session resumed after a restart never re-creates, so its agent
416
+ // is only in the store. That lookup is deferred off this path; the
417
+ // timestamp above keeps ordering honest.
418
+ void gateway.store.get(event.sessionId)
419
+ .then((session) => {
420
+ const agentId = session?.agent.id;
421
+ if (agentId) {
422
+ agentBySession.set(event.sessionId, agentId);
423
+ }
424
+ return logWriter.write({ ...base, ...(agentId ? { agentId } : {}) });
425
+ })
426
+ .catch(() => logWriter.write(base));
427
+ }
428
+ if (event.type === 'session.completed' || event.type === 'session.failed') {
429
+ agentBySession.delete(event.sessionId);
430
+ }
431
+ });
432
+ }
433
+ await gateway.start();
434
+ // Read now, while the API is bound: its stop forgets the address, and
435
+ // a restart's respawn needs it (see ServeOutcome).
436
+ const boundApiPort = boundApi?.url !== undefined ? Number(new URL(boundApi.url).port) : undefined;
437
+ if (supervised && boundApiPort !== undefined && Number.isInteger(boundApiPort) && boundApiPort > 0) {
438
+ link.send({ type: 'stratusd.bound-api-port', port: boundApiPort });
439
+ }
440
+ // Under one finally from here: a throw anywhere after the start — a
441
+ // host's writable refusing a line, say — must still stop the gateway
442
+ // before the claim on the home is released, or a live gateway would be
443
+ // left behind a lock the next daemon can take.
444
+ let redirectTimer;
445
+ try {
446
+ // The roster is only known once the gateway has loaded it, and in remote
447
+ // mode an agent no channel can ask for is the quietest failure this
448
+ // feature has: its gated calls park with nobody rendering them and wait
449
+ // out the whole timeout before being denied. No channel can detect this
450
+ // on its own — a request is a broadcast, and no adapter knows whether
451
+ // another one is about to answer — so it is reported here, where the
452
+ // roster and the channel list are both in view.
453
+ if (approvalMode === 'remote') {
454
+ const askable = new Set(slackAdapterUp ? slackAgents.map(([agentId]) => agentId) : []);
455
+ const unreachable = gateway.agents().map((agent) => agent.id).filter((id) => !askable.has(id));
456
+ if (unreachable.length > 0) {
457
+ warn(`no channel can ask for ${unreachable.join(', ')}, so their gated calls will wait out the `
458
+ + 'approval timeout and then be denied. Connect a Slack app for them, or run with --approvals headless.');
459
+ }
460
+ }
461
+ writeLine(streams.stdout, 'Press Ctrl+C to stop.');
462
+ // And periodically, for a long-running daemon that warns steadily
463
+ // without ever writing enough records to rotate. Unref'd, so it never
464
+ // holds the process open. Armed only once the daemon is actually
465
+ // serving: every step above can throw, and runServe is an exported
466
+ // function as much as a process entry point — in a host that survives
467
+ // the failure, a timer armed before the throw would outlive the call
468
+ // and go on truncating that environment's redirect logs. The finally
469
+ // below takes it down on every other exit path.
470
+ if (logWriter) {
471
+ redirectTimer = setInterval(() => void truncateRedirectLogs(logsDirPath(env)), 5 * 60_000);
472
+ redirectTimer.unref?.();
473
+ }
474
+ // Hold the event loop open until a shutdown request, then drain: new
475
+ // dispatches are refused while in-flight turns finish.
476
+ await new Promise((resolve) => {
477
+ const keepAlive = setInterval(() => { }, 2_147_000_000);
478
+ let settled = false;
479
+ const shutdown = () => {
480
+ if (settled) {
481
+ return;
482
+ }
483
+ settled = true;
484
+ clearInterval(keepAlive);
485
+ resolve();
486
+ };
487
+ stopSignal = () => {
488
+ if (!settled) {
489
+ shutdown();
490
+ return;
491
+ }
492
+ // A signal while a drain is already running — a repeat, or a stop
493
+ // arriving during a restart's drain. Either way the drain goes on,
494
+ // and a daemon told to stop does not come back.
495
+ stopRequested = true;
496
+ if (!repeatWarned) {
497
+ repeatWarned = true;
498
+ // Said from signal dispatch, outside the promise and its finally:
499
+ // a stream that throws on write (a host's injected stderr) would
500
+ // otherwise end the process from here — mid-drain, the very
501
+ // thing this handler exists to prevent. The word is best effort.
502
+ try {
503
+ warn('stop signal received while draining; still draining, and this daemon will not come back (SIGKILL ends it at once)');
504
+ }
505
+ catch {
506
+ // Nothing to say it to; the drain is what matters.
507
+ }
508
+ }
509
+ };
510
+ // `on`, never `once`, and not removed until the drain is over (the
511
+ // finally below). `once` drops the listener before running it, Node
512
+ // uninstalls its native handler the moment no listener is left, and
513
+ // a second SIGTERM landing in that window ends the process by the
514
+ // default action — mid-drain, with nothing said. The second signal
515
+ // is the normal case, not an edge: a stop delivered to the process
516
+ // group, as systemd's KillMode=control-group and a terminal's Ctrl+C
517
+ // deliver it, reaches a supervised daemon once from the kernel and
518
+ // once more forwarded by its supervisor. Reproduced two runs in
519
+ // three: the replacement died and the supervisor exited 1 on a
520
+ // `stratus service stop` after a restart. SIGKILL still ends the
521
+ // process at once.
522
+ process.on('SIGTERM', stopSignal);
523
+ process.on('SIGINT', stopSignal);
524
+ void shutdownRequested.then(shutdown);
525
+ if (env.shutdownSignal?.aborted) {
526
+ shutdown();
527
+ }
528
+ else {
529
+ env.shutdownSignal?.addEventListener('abort', shutdown, { once: true });
530
+ }
531
+ });
532
+ // Decided now, before the stop below: a restart's drain can still be
533
+ // running when a stop signal releases this wait, and `onRestart` then
534
+ // fires during that stop. A daemon told to stop does not come back,
535
+ // whatever it was told before.
536
+ if (!restart) {
537
+ stopRequested = true;
538
+ }
539
+ if (restart) {
540
+ // Already stopped: the gateway drained and closed before handing the
541
+ // process over, and the stop() below finds nothing to do. Said here,
542
+ // while the structured log still takes writes — the next lines
543
+ // belong to a process that has none.
544
+ if (!restart.drained) {
545
+ // A turn that ignored its abort is still running in this process,
546
+ // possibly still writing sessions. Starting a fresh daemon beside
547
+ // it would be two processes on one store; exiting instead leaves
548
+ // the service manager, where there is one, to bring it back.
549
+ warn(`restart: something did not let go; exiting with status ${UNDRAINED_RESTART_EXIT_CODE} for the service manager to restart, instead of starting a new daemon beside it`);
550
+ }
551
+ else {
552
+ log(`restarting stratusd${restart.reason ? ` (${restart.reason})` : ''}`);
553
+ }
554
+ }
555
+ else {
556
+ writeLine(streams.stdout, 'Stopping — draining in-flight turns.');
557
+ }
558
+ }
559
+ finally {
560
+ try {
561
+ await gateway.stop();
562
+ // Writes are queued and dropped on the hot path so logging never sits
563
+ // on a streamed token. That makes the tail of the log the part most
564
+ // likely to be lost — and the tail is the shutdown reason, the last
565
+ // warning, the line explaining a restart.
566
+ await logWriter?.flush();
567
+ }
568
+ finally {
569
+ // The shutdown is over, the flush included: a stop signal from here
570
+ // on is the process's to handle by default again — and a host that
571
+ // calls runServe repeatedly (the tests) must not accumulate handlers.
572
+ // Last, and under its own finally, because the listener is on the
573
+ // global process: taken off before the flush, a repeated signal
574
+ // landing during it would end the process by the default action
575
+ // (which a supervisor reports as a failure, and a service manager
576
+ // set to restart on failure would then bring back a daemon an
577
+ // operator just stopped); left on by a stop() that rejects (its last
578
+ // log line can throw through an injected stream), a settled handler
579
+ // would swallow the host's next signal.
580
+ if (stopSignal) {
581
+ process.off('SIGTERM', stopSignal);
582
+ process.off('SIGINT', stopSignal);
583
+ }
584
+ if (redirectTimer) {
585
+ clearInterval(redirectTimer);
586
+ }
587
+ }
588
+ }
589
+ const bound = boundApiPort !== undefined && Number.isInteger(boundApiPort) && boundApiPort > 0
590
+ ? { boundApiPort }
591
+ : {};
592
+ if (!restart || stopRequested) {
593
+ return { code: 0, ...bound, sessions: [] };
594
+ }
595
+ if (!restart.drained) {
596
+ (env.exitProcess ?? process.exit)(UNDRAINED_RESTART_EXIT_CODE);
597
+ return { code: UNDRAINED_RESTART_EXIT_CODE, ...bound, sessions: [] };
598
+ }
599
+ // Coming back: the browser sessions live at the stop go to the
600
+ // replacement — up the channel to the supervisor when this daemon has
601
+ // one, else with the outcome to the supervisor this process becomes.
602
+ const sessions = boundApi?.sessionsAtStop() ?? [];
603
+ if (supervised && sessions.length > 0) {
604
+ link.send({ type: 'stratusd.sessions', sessions });
605
+ }
606
+ // Asked to come back. Whether this process starts the next daemon or
607
+ // exits for its supervisor to is `runServe`'s decision, after the home
608
+ // is released: the claim is held until this returns, and a daemon
609
+ // started before that would be refused as a second one on the home.
610
+ return { code: RESTART_EXIT_CODE, ...bound, sessions };
611
+ };
612
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"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"}