@stratusagent/cli 0.11.2 → 0.11.4

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 +14 -8
  2. package/dist/approvals.d.ts +93 -0
  3. package/dist/approvals.d.ts.map +1 -0
  4. package/dist/approvals.js +368 -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 +159 -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 +227 -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 +376 -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 +103 -0
  43. package/dist/commands/plugins.d.ts.map +1 -0
  44. package/dist/commands/plugins.js +386 -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 +633 -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 +2467 -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 +593 -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 +114 -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 +272 -0
  97. package/dist/help.js.map +1 -0
  98. package/dist/index.d.ts +32 -624
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +39 -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 +218 -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 +245 -0
  119. package/dist/parse.d.ts.map +1 -0
  120. package/dist/parse.js +1098 -0
  121. package/dist/parse.js.map +1 -0
  122. package/dist/plugin-catalog.d.ts +44 -0
  123. package/dist/plugin-catalog.d.ts.map +1 -0
  124. package/dist/plugin-catalog.js +70 -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 +76 -0
  139. package/dist/runtime.d.ts.map +1 -0
  140. package/dist/runtime.js +372 -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 +84 -0
  155. package/dist/trusted-config.d.ts.map +1 -0
  156. package/dist/trusted-config.js +159 -0
  157. package/dist/trusted-config.js.map +1 -0
  158. package/package.json +27 -23
@@ -0,0 +1,372 @@
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 { randomUUID } from 'node:crypto';
10
+ import { AgentRunner, ContributionRegistry, createRoutedMemoryStore, EventBus, SkillRegistry, ToolRegistry, missingSkillRequirements, describeToolAllowlistFinding, unmatchedToolAllowlist, } from '@stratusagent/core';
11
+ import { createLocalCommandExecutor } from '@stratusagent/executor-local';
12
+ import { loadPlugins } from '@stratusagent/plugins';
13
+ import { createForgetTool, createRecallTool, createRememberTool, GATEWAY_ONLY_TOOL_NAMES, } from '@stratusagent/agents';
14
+ import { BUILTIN_EXECUTOR_NAME, BUILTIN_MEMORY_STORE_NAME, createDemoTool, createFileCredentialResolver, createFileMemoryStore, createRuntimeProvider, defaultApiKeyEnvName, DEFAULT_STRATUS_AGENT, isSignedInRuntime, loadCredentials, loadOperatorSkills, memoryFilePath, migrateLegacyMemory, readNonEmptyString, readProcessEnv, resolveRuntimeConfig as resolveStateRuntimeConfig, withLegacyDefaultMemories, workspacesDirPath, } from '@stratusagent/state';
15
+ import { createApprovalPolicy } from "./approvals.js";
16
+ import { formatEvent } from "./events.js";
17
+ import { writeLine, stringifyValue } from "./io.js";
18
+ import { quoteShellArg } from "./prompter.js";
19
+ import { loadServePlugins, loadServeRuntimeSelection } from "./trusted-config.js";
20
+ /**
21
+ * Kept with its historical CLI signature: a parsed run command is a
22
+ * RuntimeSelection plus CLI-only fields the resolver ignores.
23
+ *
24
+ * Those fields are *permitted*, not required. Demanding a whole
25
+ * `ParsedRunCommand` made the type claim the resolver cared about
26
+ * `approvals`, `format`, and `events` — it reads none of them — so every
27
+ * caller with a selection in hand had to invent values to get past it.
28
+ */
29
+ export const resolveRuntimeConfig = (command, env = {}) => resolveStateRuntimeConfig(command, env);
30
+ /**
31
+ * Says, once the run is up, what an auto-discovered project config asked
32
+ * for and did not get. The resolver only records it — nothing is logging
33
+ * while a run resolves — and a persona that silently failed to apply would
34
+ * read as the agent ignoring its instructions rather than as the trust
35
+ * decision it is.
36
+ */
37
+ export const warnOnUntrustedConfig = (runtime, streams, soulFlag = true) => {
38
+ warnOnIgnoredConfig(runtime.ignoredFromUntrustedConfig, streams, soulFlag);
39
+ };
40
+ /** The environment variable that names each refused key, as the resolver reads it. */
41
+ const ENV_FOR_PROMPT_KEY = {
42
+ soul: 'STRATUS_SOUL',
43
+ systemPrompt: 'STRATUS_SYSTEM_PROMPT',
44
+ };
45
+ /**
46
+ * The way out of a refused persona, as one sentence. `--config` trusts the
47
+ * file; the other way is the operator's own channel for the key — the
48
+ * `--soul` flag where the command takes one (`run` and `chat`; `serve` and
49
+ * `doctor` do not, and a notice sending the operator to a flag the daemon
50
+ * refuses is a notice that cost a restart), the environment otherwise.
51
+ * Never "move the key to ~/.stratus/config.json": the project file that
52
+ * caused this shadows the global one in discovery, so a key moved there
53
+ * would go on being unset for every run started here.
54
+ */
55
+ export const ignoredConfigRemedy = (ignored, soulFlag) => {
56
+ const environment = (keys) => `set ${keys.map((key) => ENV_FOR_PROMPT_KEY[key]).join(' / ')}`;
57
+ const rest = ignored.keys.filter((key) => key !== 'soul');
58
+ // The flag restores only the soul: when the preamble was refused too,
59
+ // a remedy that stopped at --soul would leave it silently unset.
60
+ const otherWay = soulFlag && ignored.keys.includes('soul')
61
+ ? (rest.length === 0 ? 'pass --soul <path>' : `pass --soul <path> and ${environment(rest)}`)
62
+ : environment(ignored.keys);
63
+ return `Run with --config ${quoteShellArg(ignored.path)} to trust that file, or ${otherWay}.`;
64
+ };
65
+ /** `soulFlag`: whether the command printing this takes `--soul` — see {@link ignoredConfigRemedy}. */
66
+ export const warnOnIgnoredConfig = (ignored, streams, soulFlag = true) => {
67
+ if (!ignored) {
68
+ return;
69
+ }
70
+ const keys = ignored.keys.join(' and ');
71
+ writeLine(streams.stderr, `ignoring ${keys} in ${ignored.path}: what an agent is told is not a decision an auto-discovered config gets to make. `
72
+ + ignoredConfigRemedy(ignored, soulFlag));
73
+ };
74
+ /**
75
+ * A saved subscription sign-in silently demoted to per-token billing is the
76
+ * one config surprise that costs money — an API key in the environment
77
+ * outranks the stored credential, and the run otherwise looks identical.
78
+ * Detected from the resolved config: an apiKey where the stored credential
79
+ * is a subscription token means the environment won.
80
+ */
81
+ export const warnOnCredentialOverride = async (runtime, streams, env = {}) => {
82
+ if (runtime.provider === 'demo') {
83
+ return;
84
+ }
85
+ const credentials = await loadCredentials(env);
86
+ const processEnv = readProcessEnv(env);
87
+ // The resolver records the variable that actually won — guessing it here
88
+ // would name the wrong one whenever a custom apiKeyEnv supplied the key,
89
+ // sending the reader to unset something that was never the cause.
90
+ const primaryOverride = isSignedInRuntime(runtime) && runtime.apiKey !== undefined
91
+ ? { provider: runtime.provider, envVar: runtime.apiKeyEnvVar }
92
+ : undefined;
93
+ // Both subscription sign-ins demote the same way: a Claude setup token
94
+ // and the codex ChatGPT marker each lose to an environment API key, and
95
+ // the run otherwise looks identical while billing per token.
96
+ for (const target of ['anthropic', 'codex']) {
97
+ if (credentials[target]?.type !== 'oauth_token') {
98
+ continue;
99
+ }
100
+ const planName = target === 'anthropic'
101
+ ? 'Claude subscription sign-in'
102
+ : 'ChatGPT (codex login) sign-in';
103
+ const primary = primaryOverride?.provider === target ? primaryOverride.envVar : undefined;
104
+ // A fallback demoted the same way costs exactly as much, and only bites
105
+ // once the primary is already failing — the worst moment to discover it.
106
+ // The fallback path consults the provider's own conventional variable.
107
+ const conventionalVar = defaultApiKeyEnvName(target);
108
+ const fallbackVar = runtime.fallback?.provider === target
109
+ && runtime.fallback.apiKey !== undefined
110
+ && readNonEmptyString(processEnv[conventionalVar]) === runtime.fallback.apiKey
111
+ ? conventionalVar
112
+ : undefined;
113
+ const culprit = primary ?? fallbackVar;
114
+ if (!culprit) {
115
+ continue;
116
+ }
117
+ writeLine(streams.stderr, `Warning: ${culprit} in your environment outranks the ${planName} saved by \`stratus setup\`, `
118
+ + `so ${primary ? 'this run is' : 'a fallback retry would be'} billed per token instead of through your plan. `
119
+ + 'Unset it to use the subscription, or run `stratus doctor` to see everything that is being overridden.');
120
+ }
121
+ };
122
+ // The shared wiring behind every conversational command: memory (with
123
+ // legacy migration), tools, events, provider (with fallback), and the
124
+ // agent the runtime resolved. run uses it for one shot; chat keeps the
125
+ // runner alive and resumes the same session turn after turn.
126
+ export const createAgentRuntime = async (streams, options) => {
127
+ const runEnv = options.env ?? {};
128
+ await migrateLegacyMemory(runEnv);
129
+ // Routed, as the daemon's is: the memory tools register before the
130
+ // plugins load (so a plugin cannot claim their names), and the store
131
+ // they hold answers per call with whichever the trusted config selected
132
+ // once the plugins are up.
133
+ const fileMemory = withLegacyDefaultMemories(createFileMemoryStore(memoryFilePath(runEnv)));
134
+ let selectedMemory = fileMemory;
135
+ const memory = createRoutedMemoryStore(() => selectedMemory);
136
+ const tools = new ToolRegistry();
137
+ tools.register(createDemoTool());
138
+ tools.register(createRememberTool(memory));
139
+ tools.register(createRecallTool(memory));
140
+ tools.register(createForgetTool(memory));
141
+ // The same skills the daemon would serve, from the same directory, for
142
+ // the same reason the plugins below match: a skill that routes in
143
+ // `stratus run` routes in `stratus serve`, and one that is broken is
144
+ // broken (and warned about) in both. The runner registers `skill.read`
145
+ // itself, gated on the soul enabling any skill.
146
+ const skills = new SkillRegistry();
147
+ await loadOperatorSkills(runEnv, skills, (line) => {
148
+ writeLine(streams.stderr, `Warning: ${line}`);
149
+ });
150
+ const bus = new EventBus({
151
+ onError: (error) => {
152
+ writeLine(streams.stderr, `Warning: event handler failed: ${error instanceof Error ? error.message : String(error)}`);
153
+ },
154
+ });
155
+ if (options.onEvent) {
156
+ const onEvent = options.onEvent;
157
+ bus.subscribe(async (event) => {
158
+ onEvent(event);
159
+ });
160
+ }
161
+ else if (options.events ?? true) {
162
+ bus.subscribe(async (event) => {
163
+ const line = formatEvent(event);
164
+ if (line) {
165
+ writeLine(streams.stdout, line);
166
+ }
167
+ });
168
+ }
169
+ // The same plugins the daemon would load, from the same trusted config,
170
+ // so a tool that works in `stratus run` works in `stratus serve` and a
171
+ // tool that is missing is missing in both. A local test that silently ran
172
+ // a different toolset than the daemon would be worse than no local test.
173
+ const pluginsConfig = await loadServePlugins(runEnv, options.configPath, (line) => {
174
+ writeLine(streams.stderr, `Warning: ${line}`);
175
+ });
176
+ const loadedPlugins = [];
177
+ const providers = new ContributionRegistry();
178
+ const memoryStores = new ContributionRegistry();
179
+ const executors = new ContributionRegistry();
180
+ if (Object.keys(pluginsConfig).length > 0) {
181
+ const result = await loadPlugins({
182
+ config: pluginsConfig,
183
+ host: {
184
+ resolve: (specifier) => import.meta.resolve(specifier),
185
+ import: (specifier) => import(__rewriteRelativeImportExtension(specifier)),
186
+ },
187
+ tools,
188
+ skills,
189
+ bus,
190
+ providers,
191
+ memory: memoryStores,
192
+ executors,
193
+ // No channel registry and no transport secrets: a local run has no
194
+ // channels, so a channel plugin's registration is recorded and goes
195
+ // nowhere, and its request for its secrets is refused with a message
196
+ // that says so rather than answered with an empty roster.
197
+ credentials: createFileCredentialResolver(runEnv),
198
+ workspaceRoot: workspacesDirPath(runEnv),
199
+ });
200
+ loadedPlugins.push(...result.loaded);
201
+ for (const failure of result.failures) {
202
+ writeLine(streams.stderr, `Warning: plugin ${failure.package} did not load: ${failure.reason}`);
203
+ }
204
+ }
205
+ // Handed back so a command can release what a plugin acquired — a browser
206
+ // above all. A one-shot `stratus run` that left a Chromium behind would
207
+ // be a leak per invocation. Defined before anything after the load can
208
+ // fail, because a refusal below — a selection nothing registers, a
209
+ // provider factory that throws — has the same plugins to release and no
210
+ // caller yet to release them: the callers' `finally` only begins once
211
+ // this returns.
212
+ const disposePlugins = async () => {
213
+ for (const plugin of loadedPlugins) {
214
+ try {
215
+ await plugin.instance.dispose?.();
216
+ }
217
+ catch (error) {
218
+ writeLine(streams.stderr, `Warning: plugin ${plugin.package} failed to shut down: ${error instanceof Error ? error.message : String(error)}`);
219
+ }
220
+ }
221
+ };
222
+ try {
223
+ // The same selections the daemon makes, from the same trusted keys, and
224
+ // the same refusal: a run that quietly fell back to the host's executor
225
+ // when the operator selected a sandbox would be the local test lying
226
+ // about what the daemon does.
227
+ const warnTrusted = (line) => {
228
+ writeLine(streams.stderr, `Warning: ${line}`);
229
+ };
230
+ const executorName = (await loadServeRuntimeSelection('executor', runEnv, options.configPath, warnTrusted)) ?? BUILTIN_EXECUTOR_NAME;
231
+ let executor;
232
+ if (executorName !== BUILTIN_EXECUTOR_NAME) {
233
+ const contribution = executors.get(executorName);
234
+ if (!contribution) {
235
+ throw new Error(`The config selects executor ${executorName}, which no loaded plugin registers`
236
+ + (executors.names().length > 0 ? ` (registered: ${executors.names().join(', ')})` : '')
237
+ + `. Enable the plugin that contributes it, or set executor to ${BUILTIN_EXECUTOR_NAME}.`);
238
+ }
239
+ executor = contribution.executor;
240
+ }
241
+ const memoryName = (await loadServeRuntimeSelection('memoryStore', runEnv, options.configPath, warnTrusted)) ?? BUILTIN_MEMORY_STORE_NAME;
242
+ if (memoryName !== BUILTIN_MEMORY_STORE_NAME) {
243
+ const contribution = memoryStores.get(memoryName);
244
+ if (!contribution) {
245
+ throw new Error(`The config selects memoryStore ${memoryName}, which no loaded plugin registers`
246
+ + (memoryStores.names().length > 0 ? ` (registered: ${memoryStores.names().join(', ')})` : '')
247
+ + `. Enable the plugin that contributes it, or set memoryStore to ${BUILTIN_MEMORY_STORE_NAME}.`);
248
+ }
249
+ selectedMemory = contribution.store;
250
+ }
251
+ // The Claude Code runtime executes kernel tools by calling back into the
252
+ // runner built just below — late-bound because the runner needs the
253
+ // provider first.
254
+ let hostedRunner;
255
+ const runtimeProvider = createRuntimeProvider(options.runtime, (error) => {
256
+ const fallback = options.runtime.provider === 'demo' ? undefined : options.runtime.fallback;
257
+ writeLine(streams.stderr, `Warning: the default model failed (${error instanceof Error ? error.message : String(error)}); falling back to ${fallback?.model ?? 'the fallback model'}.`);
258
+ }, async (session, call, context) => {
259
+ if (!hostedRunner) {
260
+ throw new Error('The Stratus runtime is not ready to execute tools yet.');
261
+ }
262
+ return hostedRunner.executeHostedToolCall(session, call, context);
263
+ }, options.maxTurns, undefined, providers);
264
+ const runner = new AgentRunner({
265
+ provider: runtimeProvider,
266
+ tools,
267
+ executor: executor ?? createLocalCommandExecutor(),
268
+ approvals: createApprovalPolicy(options.approvals ?? 'always', streams, options.env ?? {}, options.askApproval, options.approvalsDefaulted ?? false),
269
+ bus,
270
+ skills,
271
+ memory,
272
+ ...(options.maxTurns !== undefined ? { maxTurns: options.maxTurns } : {}),
273
+ });
274
+ hostedRunner = runner;
275
+ await runner.initialize();
276
+ // A soul is a full identity — without one, every provider serves the
277
+ // same built-in Stratus persona.
278
+ const agent = options.runtime.soul?.agent ?? DEFAULT_STRATUS_AGENT;
279
+ // The same advisory the daemon gives at roster load, from the same
280
+ // kernel check: a soul enabling a skill whose `requires:` its `tools:`
281
+ // does not cover must warn here too, or the local test stays silent
282
+ // about a configuration `stratus serve` flags.
283
+ for (const { skill, missing } of missingSkillRequirements(agent, skills)) {
284
+ writeLine(streams.stderr, `Warning: agent ${agent.id} enables skill ${skill.id}, which expects tools the agent is not allowed: ${missing.join(', ')}`);
285
+ }
286
+ // And the same for the tools themselves, after `initialize()` so the
287
+ // plugins have registered theirs: an allowlist entry naming a tool
288
+ // nothing provides grants nothing and says nothing, and a soul made only
289
+ // of those runs with no tools while its persona still talks about them.
290
+ const finding = unmatchedToolAllowlist(agent, tools.describe().map((tool) => tool.name), {
291
+ mayRegister: loadedPlugins.flatMap((plugin) => plugin.manifest.contributes.toolsDiscovered.map((declared) => declared.namespace)),
292
+ // A local run has no dispatcher, store, or channels, so it registers
293
+ // none of the daemon's tools. A soul written for `stratus serve` is
294
+ // not wrong for naming them here — it is in the wrong process.
295
+ elsewhere: GATEWAY_ONLY_TOOL_NAMES,
296
+ });
297
+ for (const line of finding ? describeToolAllowlistFinding(agent.id, finding) : []) {
298
+ writeLine(streams.stderr, `Warning: ${line}`);
299
+ }
300
+ // The kernel leaves this one to the host, because only the host knows
301
+ // which process it is not.
302
+ if (finding && finding.elsewhere.length > 0) {
303
+ writeLine(streams.stderr, `Warning: agent ${agent.id} lists ${finding.elsewhere.join(', ')}, which only the daemon provides`
304
+ + ' — the names are right, but stratus run cannot call them; stratus serve can');
305
+ }
306
+ // The built-in executor keeps the name it has always recorded; a
307
+ // contributed one records the name it registered under — on every
308
+ // provider's session, since where a command ran is not a question only
309
+ // demo runs get to answer.
310
+ const executorRecord = executor ? executorName : 'local-command';
311
+ const metadata = options.runtime.provider === 'demo'
312
+ ? { provider: 'demo', executor: executorRecord }
313
+ : {
314
+ provider: options.runtime.provider,
315
+ // A contributed provider may leave the model to its own default.
316
+ ...(options.runtime.model !== undefined ? { model: options.runtime.model } : {}),
317
+ ...(options.runtime.provider === 'openai' ? { baseUrl: options.runtime.baseUrl } : {}),
318
+ executor: executorRecord,
319
+ };
320
+ return { runner, agent, metadata, disposePlugins };
321
+ }
322
+ catch (error) {
323
+ await disposePlugins();
324
+ throw error;
325
+ }
326
+ };
327
+ export const runSingleLoop = async (prompt, streams, options) => {
328
+ const { runner, agent, metadata, disposePlugins } = await createAgentRuntime(streams, options);
329
+ try {
330
+ return await runner.run({
331
+ sessionId: randomUUID(),
332
+ agent,
333
+ userMessage: prompt,
334
+ metadata,
335
+ });
336
+ }
337
+ finally {
338
+ // Even when the run failed: a plugin that started a browser started it
339
+ // before the turn could fail.
340
+ await disposePlugins();
341
+ }
342
+ };
343
+ export const printSessionSummary = (session, streams) => {
344
+ writeLine(streams.stdout);
345
+ writeLine(streams.stdout, 'Messages');
346
+ for (const message of session.messages) {
347
+ if (message.role === 'assistant' && message.toolCalls && message.toolCalls.length > 0) {
348
+ const calls = message.toolCalls
349
+ .map((call) => `${call.toolName}(${JSON.stringify(call.input)})`)
350
+ .join(', ');
351
+ const prefix = message.content ? `${message.content} ` : '';
352
+ writeLine(streams.stdout, `[assistant] ${prefix}→ tool call ${calls}`);
353
+ continue;
354
+ }
355
+ if (message.role === 'assistant' && message.content.length === 0) {
356
+ // A turn nobody asked for that said nothing — see `RunInput.addressed`.
357
+ continue;
358
+ }
359
+ const nameSuffix = message.name ? `:${message.name}` : '';
360
+ const content = message.role === 'tool' ? stringifyValue(JSON.parse(message.content)) : message.content;
361
+ writeLine(streams.stdout, `[${message.role}${nameSuffix}] ${content}`);
362
+ }
363
+ };
364
+ export const formatRuntimeBanner = (runtime) => {
365
+ const soulSuffix = runtime.soul ? ` as ${runtime.soul.agent.name}` : '';
366
+ if (runtime.provider === 'demo') {
367
+ return `Starting Stratus Agent local loop with provider=demo${soulSuffix}`;
368
+ }
369
+ const fallbackSuffix = runtime.fallback ? ` fallback=${runtime.fallback.model}` : '';
370
+ return `Starting Stratus Agent local loop with provider=${runtime.provider} model=${runtime.model}${fallbackSuffix}${soulSuffix}`;
371
+ };
372
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ interface SlackIdentity {
2
+ botUserId?: string;
3
+ teamName?: string;
4
+ teamId?: string;
5
+ }
6
+ type SlackVerdict = {
7
+ status: 'ok';
8
+ identity: SlackIdentity;
9
+ } | {
10
+ status: 'rejected';
11
+ detail: string;
12
+ } | {
13
+ status: 'unreachable';
14
+ detail: string;
15
+ };
16
+ /** Verifies a bot token and reports the identity it belongs to. */
17
+ export declare const verifySlackBotToken: (token: string, fetchImpl: typeof fetch | undefined) => Promise<SlackVerdict>;
18
+ /**
19
+ * Verifies an app-level token by opening a Socket Mode URL. The URL is
20
+ * discarded — this only proves the token carries connections:write, which
21
+ * is the failure the daemon would otherwise hit at start time.
22
+ */
23
+ export declare const verifySlackAppToken: (token: string, fetchImpl: typeof fetch | undefined) => Promise<SlackVerdict>;
24
+ export declare const slackAppManifest: (agentName: string) => string;
25
+ export {};
26
+ //# sourceMappingURL=slack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"AAMA,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,YAAY,GACb;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GACzC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAiC9C,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,GAAU,OAAO,MAAM,EAAE,WAAW,OAAO,KAAK,GAAG,SAAS,KAAG,OAAO,CAAC,YAAY,CAalH,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAU,OAAO,MAAM,EAAE,WAAW,OAAO,KAAK,GAAG,SAAS,KAAG,OAAO,CAAC,YAAY,CAGlH,CAAC;AAqCF,eAAO,MAAM,gBAAgB,GAAI,WAAW,MAAM,KAAG,MAsB1C,CAAC"}
package/dist/slack.js ADDED
@@ -0,0 +1,113 @@
1
+ // Slack verification talks to the Web API over plain fetch rather than
2
+ // through @stratusagent/channel-slack. Setup must stay usable before that
3
+ // optional package is installed, and the CLI deliberately does not depend
4
+ // on it (or on the ~9 MB of Slack SDKs underneath).
5
+ const SLACK_API_ROOT = 'https://slack.com/api';
6
+ const callSlack = async (method, token, fetchImpl) => {
7
+ if (typeof fetchImpl !== 'function') {
8
+ return { ok: false, verdict: { status: 'unreachable', detail: 'fetch is unavailable' } };
9
+ }
10
+ try {
11
+ const response = await fetchImpl(`${SLACK_API_ROOT}/${method}`, {
12
+ method: 'POST',
13
+ headers: {
14
+ authorization: `Bearer ${token}`,
15
+ 'content-type': 'application/x-www-form-urlencoded',
16
+ },
17
+ });
18
+ if (!response.ok) {
19
+ return { ok: false, verdict: { status: 'unreachable', detail: `HTTP ${response.status}` } };
20
+ }
21
+ const body = await response.json();
22
+ if (body.ok === true) {
23
+ return { ok: true, body };
24
+ }
25
+ // Slack answers 200 with { ok: false, error } for bad credentials, so
26
+ // the error string — not the status — is what condemns a token.
27
+ return { ok: false, verdict: { status: 'rejected', detail: String(body.error ?? 'unknown error') } };
28
+ }
29
+ catch (error) {
30
+ return { ok: false, verdict: { status: 'unreachable', detail: error instanceof Error ? error.message : String(error) } };
31
+ }
32
+ };
33
+ /** Verifies a bot token and reports the identity it belongs to. */
34
+ export const verifySlackBotToken = async (token, fetchImpl) => {
35
+ const result = await callSlack('auth.test', token, fetchImpl);
36
+ if (!result.ok) {
37
+ return result.verdict;
38
+ }
39
+ return {
40
+ status: 'ok',
41
+ identity: {
42
+ ...(typeof result.body.user_id === 'string' ? { botUserId: result.body.user_id } : {}),
43
+ ...(typeof result.body.team === 'string' ? { teamName: result.body.team } : {}),
44
+ ...(typeof result.body.team_id === 'string' ? { teamId: result.body.team_id } : {}),
45
+ },
46
+ };
47
+ };
48
+ /**
49
+ * Verifies an app-level token by opening a Socket Mode URL. The URL is
50
+ * discarded — this only proves the token carries connections:write, which
51
+ * is the failure the daemon would otherwise hit at start time.
52
+ */
53
+ export const verifySlackAppToken = async (token, fetchImpl) => {
54
+ const result = await callSlack('apps.connections.open', token, fetchImpl);
55
+ return result.ok ? { status: 'ok', identity: {} } : result.verdict;
56
+ };
57
+ // Scopes and events the adapter needs. Kept in step with the manifest
58
+ // shipped by @stratusagent/channel-slack (a test pins them together) so
59
+ // setup can hand over a ready-to-paste manifest without depending on that
60
+ // package being installed.
61
+ const SLACK_BOT_SCOPES = [
62
+ 'app_mentions:read',
63
+ // The history family is what lets an agent stay in a conversation it was
64
+ // brought into: without it Slack delivers only mentions, and a reply in
65
+ // the agent's own thread never reaches it. It is the workspace's switch
66
+ // for that — an app installed without these scopes answers mentions and
67
+ // nothing else, exactly as it always did.
68
+ 'channels:history',
69
+ // The conversations read family backs outbound destination validation
70
+ // (conversations.info): whether a channel a schedule wants to report to
71
+ // exists, and whether this app is a member of it.
72
+ 'channels:read',
73
+ 'chat:write',
74
+ // What lets an agent be shown a screenshot: file bytes sit behind an
75
+ // authenticated URL that answers a token without this scope with a
76
+ // sign-in page. An app installed without it still hears about the
77
+ // attachment, by name, and is told it cannot open it.
78
+ 'files:read',
79
+ 'files:write',
80
+ 'groups:history',
81
+ 'groups:read',
82
+ 'im:history',
83
+ 'im:read',
84
+ 'im:write',
85
+ 'mpim:history',
86
+ 'mpim:read',
87
+ 'users:read',
88
+ ];
89
+ const SLACK_BOT_EVENTS = ['app_mention', 'message.channels', 'message.groups', 'message.im', 'message.mpim'];
90
+ export const slackAppManifest = (agentName) => JSON.stringify({
91
+ display_information: {
92
+ name: agentName,
93
+ description: 'A Stratus agent',
94
+ background_color: '#1a1d21',
95
+ },
96
+ features: {
97
+ bot_user: { display_name: agentName, always_online: true },
98
+ },
99
+ oauth_config: { scopes: { bot: SLACK_BOT_SCOPES } },
100
+ settings: {
101
+ event_subscriptions: { bot_events: SLACK_BOT_EVENTS },
102
+ // Required for remote approval: Allow / Always allow / Deny arrive as
103
+ // block_actions, and Slack delivers none of them to an app that has
104
+ // interactivity switched off. Enabled unconditionally rather than per
105
+ // mode — an app is created once, and discovering months later that the
106
+ // buttons do nothing means editing the manifest and reinstalling.
107
+ interactivity: { is_enabled: true },
108
+ org_deploy_enabled: false,
109
+ socket_mode_enabled: true,
110
+ token_rotation_enabled: false,
111
+ },
112
+ }, null, 2);
113
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { CliEnvironment } from './environment.ts';
2
+ /**
3
+ * What a `skill add` source string means, in order: a directory on this
4
+ * machine, a GitHub `owner/repo` shorthand, or a URL git can clone. The
5
+ * shorthand is the form skills.sh and its CLI print, so a skill published
6
+ * there installs by the name its listing shows.
7
+ */
8
+ export declare const resolveSource: (source: string, env: CliEnvironment, what: "skill" | "template") => Promise<{
9
+ kind: "local";
10
+ directory: string;
11
+ } | {
12
+ kind: "git";
13
+ url: string;
14
+ }>;
15
+ /**
16
+ * A source URL safe to print: userinfo stripped. A token travels in exactly
17
+ * this position (`https://user:token@host/repo.git`), stdout is commonly
18
+ * retained in CI logs, and git's own stderr already redacts — only the
19
+ * unredacted URL is handed to git itself.
20
+ */
21
+ export declare const redactedSourceUrl: (url: string) => string;
22
+ /** Shallow-clone a source repository. Git owns every transport we would otherwise re-implement. */
23
+ export declare const cloneSource: (url: string, destination: string) => Promise<void>;
24
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,KAAK,cAAc,EACnB,MAAM,OAAO,GAAG,UAAU,KACzB,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAsB7E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,MAa/C,CAAC;AAEF,mGAAmG;AACnG,eAAO,MAAM,WAAW,GAAU,KAAK,MAAM,EAAE,aAAa,MAAM,KAAG,OAAO,CAAC,IAAI,CAuBhF,CAAC"}