@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.
- package/README.md +13 -7
- package/dist/approvals.d.ts +87 -0
- package/dist/approvals.d.ts.map +1 -0
- package/dist/approvals.js +315 -0
- package/dist/approvals.js.map +1 -0
- package/dist/commands/agent-new.d.ts +22 -0
- package/dist/commands/agent-new.d.ts.map +1 -0
- package/dist/commands/agent-new.js +154 -0
- package/dist/commands/agent-new.js.map +1 -0
- package/dist/commands/agents.d.ts +4 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +90 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/chat.d.ts +4 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +224 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/credential.d.ts +22 -0
- package/dist/commands/credential.d.ts.map +1 -0
- package/dist/commands/credential.js +93 -0
- package/dist/commands/credential.js.map +1 -0
- package/dist/commands/dashboard.d.ts +14 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +195 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/doctor.d.ts +40 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +357 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/grants.d.ts +19 -0
- package/dist/commands/grants.d.ts.map +1 -0
- package/dist/commands/grants.js +128 -0
- package/dist/commands/grants.js.map +1 -0
- package/dist/commands/logs.d.ts +9 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +58 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/memory.d.ts +20 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +110 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/plugins.d.ts +91 -0
- package/dist/commands/plugins.d.ts.map +1 -0
- package/dist/commands/plugins.js +359 -0
- package/dist/commands/plugins.js.map +1 -0
- package/dist/commands/restart.d.ts +4 -0
- package/dist/commands/restart.d.ts.map +1 -0
- package/dist/commands/restart.js +25 -0
- package/dist/commands/restart.js.map +1 -0
- package/dist/commands/schedules.d.ts +11 -0
- package/dist/commands/schedules.d.ts.map +1 -0
- package/dist/commands/schedules.js +50 -0
- package/dist/commands/schedules.js.map +1 -0
- package/dist/commands/serve.d.ts +4 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +612 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/service.d.ts +9 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +97 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/session.d.ts +9 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +25 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/setup.d.ts +5 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +2412 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/skills.d.ts +15 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +272 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/template.d.ts +4 -0
- package/dist/commands/template.d.ts.map +1 -0
- package/dist/commands/template.js +575 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/update.d.ts +21 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +291 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/daemon.d.ts +74 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +192 -0
- package/dist/daemon.js.map +1 -0
- package/dist/environment.d.ts +108 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +2 -0
- package/dist/environment.js.map +1 -0
- package/dist/events.d.ts +17 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +87 -0
- package/dist/events.js.map +1 -0
- package/dist/help.d.ts +2 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +266 -0
- package/dist/help.js.map +1 -0
- package/dist/index.d.ts +31 -624
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -6981
- package/dist/index.js.map +1 -1
- package/dist/io.d.ts +16 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +45 -0
- package/dist/io.js.map +1 -0
- package/dist/loaders.d.ts +31 -0
- package/dist/loaders.d.ts.map +1 -0
- package/dist/loaders.js +56 -0
- package/dist/loaders.js.map +1 -0
- package/dist/main.d.ts +8 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +214 -0
- package/dist/main.js.map +1 -0
- package/dist/npm.d.ts +66 -0
- package/dist/npm.d.ts.map +1 -0
- package/dist/npm.js +201 -0
- package/dist/npm.js.map +1 -0
- package/dist/parse.d.ts +231 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +1082 -0
- package/dist/parse.js.map +1 -0
- package/dist/plugin-catalog.d.ts +35 -0
- package/dist/plugin-catalog.d.ts.map +1 -0
- package/dist/plugin-catalog.js +58 -0
- package/dist/plugin-catalog.js.map +1 -0
- package/dist/preflight.d.ts +60 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +102 -0
- package/dist/preflight.js.map +1 -0
- package/dist/prompter.d.ts +84 -0
- package/dist/prompter.d.ts.map +1 -0
- package/dist/prompter.js +347 -0
- package/dist/prompter.js.map +1 -0
- package/dist/roster.d.ts +57 -0
- package/dist/roster.d.ts.map +1 -0
- package/dist/roster.js +78 -0
- package/dist/roster.js.map +1 -0
- package/dist/runtime.d.ts +59 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +266 -0
- package/dist/runtime.js.map +1 -0
- package/dist/slack.d.ts +26 -0
- package/dist/slack.d.ts.map +1 -0
- package/dist/slack.js +113 -0
- package/dist/slack.js.map +1 -0
- package/dist/source.d.ts +24 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +80 -0
- package/dist/source.js.map +1 -0
- package/dist/supervisor.d.ts +69 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +218 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/trusted-config.d.ts +71 -0
- package/dist/trusted-config.d.ts.map +1 -0
- package/dist/trusted-config.js +118 -0
- package/dist/trusted-config.js.map +1 -0
- package/package.json +25 -23
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { matchesToolAllowlist, raiseRiskTo, toolScopesOverlap, } from '@stratusagent/core';
|
|
2
|
+
import { declaredRiskFor, isFirstPartyPackage, parseToolRiskOverrides, preflightPlugin, readPluginManifest, riskFloorFor, } from '@stratusagent/plugins';
|
|
3
|
+
import { workspacesDirPath } from '@stratusagent/state';
|
|
4
|
+
import { describeUnattendedReach } from "../approvals.js";
|
|
5
|
+
import { writeLine } from "../io.js";
|
|
6
|
+
import { packageInstalled } from "../loaders.js";
|
|
7
|
+
import { PLUGIN_MARKETPLACE_URL, FIRST_PARTY_CAPABILITY_PACKAGES, KERNEL_TOOL_NAMES, } from "../plugin-catalog.js";
|
|
8
|
+
import { soulGrantsTool, rosterSoulsWithConfigured } from "../roster.js";
|
|
9
|
+
import { loadServeApprovals, loadServeApi, loadServePlugins } from "../trusted-config.js";
|
|
10
|
+
/**
|
|
11
|
+
* What this machine's plugins are, and where the chain from installed to
|
|
12
|
+
* callable breaks.
|
|
13
|
+
*
|
|
14
|
+
* Four things have to be true before an agent can call a plugin's tool —
|
|
15
|
+
* the package is installed, a trusted config enables it, the agent's
|
|
16
|
+
* `tools:` names it, and the approval policy lets the call through — and
|
|
17
|
+
* every one of them fails silently on its own. A listing of installed
|
|
18
|
+
* packages answers the first and reads as an answer to all four, which is
|
|
19
|
+
* how an agent ends up with a persona describing tools it never had.
|
|
20
|
+
*
|
|
21
|
+
* Manifests rather than a load: `readPluginManifest` imports nothing, so
|
|
22
|
+
* this never runs a plugin's `setup` — which for the MCP bridge would spawn
|
|
23
|
+
* every configured server's subprocess to answer a question about a
|
|
24
|
+
* daemon that is not running.
|
|
25
|
+
*/
|
|
26
|
+
export const collectPluginsReport = async (command, env, warn) => {
|
|
27
|
+
const pluginsConfig = await loadServePlugins(env, command.configPath, warn);
|
|
28
|
+
const approvals = await loadServeApprovals(env, command.configPath, warn);
|
|
29
|
+
// What the loader would fold in, so the validation below is against the
|
|
30
|
+
// object a daemon on this machine would build.
|
|
31
|
+
const workspaceRoot = workspacesDirPath(env);
|
|
32
|
+
// Read the same way the daemon reads it: installed, and not switched off
|
|
33
|
+
// by the trusted config's `api` block.
|
|
34
|
+
const api = await loadServeApi(env, command.configPath, warn);
|
|
35
|
+
const apiReachable = packageInstalled('@stratusagent/control-api', env) && api.enabled !== false;
|
|
36
|
+
// Who grants what, from the roster a dispatch actually serves — the same
|
|
37
|
+
// resolution `stratus skills` uses, so the two commands cannot disagree
|
|
38
|
+
// about which souls are live.
|
|
39
|
+
let roster = [];
|
|
40
|
+
let rosterUnreadable = false;
|
|
41
|
+
try {
|
|
42
|
+
const resolved = await rosterSoulsWithConfigured(env, warn, {
|
|
43
|
+
...(command.configPath !== undefined ? { configPath: command.configPath } : {}),
|
|
44
|
+
includeBuiltIn: true,
|
|
45
|
+
});
|
|
46
|
+
roster = resolved.entries;
|
|
47
|
+
rosterUnreadable = !resolved.complete;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
rosterUnreadable = true;
|
|
51
|
+
warn(`cannot say who is granted what — the roster did not load: ${error instanceof Error ? error.message : String(error)}`);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Which agents a declared name reaches. A soul with no `tools:` key
|
|
55
|
+
* grants every registered tool, which is the opposite of an empty list —
|
|
56
|
+
* so an absent allowlist matches everything here too, or this would
|
|
57
|
+
* report the most permissive agents as the least.
|
|
58
|
+
*/
|
|
59
|
+
const grantedTo = (name, discovered) => roster
|
|
60
|
+
.filter((entry) => soulGrantsTool(entry.soul.agent.tools, name, discovered))
|
|
61
|
+
.map((entry) => entry.soul.agent.id);
|
|
62
|
+
// Configured first, in the operator's own order, then the first-party
|
|
63
|
+
// packages they have not configured — the second group is why an install
|
|
64
|
+
// that granted nothing is visible at all.
|
|
65
|
+
const configured = Object.keys(pluginsConfig);
|
|
66
|
+
const packages = [
|
|
67
|
+
...configured,
|
|
68
|
+
...FIRST_PARTY_CAPABILITY_PACKAGES.filter((name) => !configured.includes(name)),
|
|
69
|
+
];
|
|
70
|
+
const plugins = [];
|
|
71
|
+
// Which package claimed each literal tool name, across the whole loop.
|
|
72
|
+
// `loadPlugins` keeps the same map and rejects the *later* plugin whole
|
|
73
|
+
// when a registration collides, so a per-plugin check would report two
|
|
74
|
+
// packages ready to serve one name that only one of them will get.
|
|
75
|
+
//
|
|
76
|
+
// Literal declarations only: the registry claims names as they register,
|
|
77
|
+
// and a namespace has none until its server connects.
|
|
78
|
+
// Qualified skill ids, tracked the same way and for the same reason.
|
|
79
|
+
const claimedSkills = new Map();
|
|
80
|
+
/**
|
|
81
|
+
* Every name or namespace some plugin may register, in config order.
|
|
82
|
+
*
|
|
83
|
+
* One list rather than a map of literals, because a collision is an
|
|
84
|
+
* *overlap* and overlap has no preferred direction: a later literal falls
|
|
85
|
+
* under an earlier namespace exactly as a later namespace covers an
|
|
86
|
+
* earlier literal. Two one-way passes is what this was, and it missed
|
|
87
|
+
* whichever direction was written second.
|
|
88
|
+
*
|
|
89
|
+
* The daemon's own tools are *registered*, unconditionally, before any
|
|
90
|
+
* plugin loads; a plugin's entry is only a declaration, which is why the
|
|
91
|
+
* two produce different warnings.
|
|
92
|
+
*/
|
|
93
|
+
const claims = KERNEL_TOOL_NAMES
|
|
94
|
+
.map((name) => ({ pattern: name, owner: 'the daemon itself', registered: true }));
|
|
95
|
+
for (const specifier of packages) {
|
|
96
|
+
const block = pluginsConfig[specifier] ?? {};
|
|
97
|
+
const isConfigured = configured.includes(specifier);
|
|
98
|
+
const base = {
|
|
99
|
+
package: specifier,
|
|
100
|
+
installed: packageInstalled(specifier, env),
|
|
101
|
+
configured: isConfigured,
|
|
102
|
+
enabled: isConfigured && block.enabled !== false,
|
|
103
|
+
tools: [],
|
|
104
|
+
};
|
|
105
|
+
// Nothing below runs for a plugin the loader would skip. It skips an
|
|
106
|
+
// absent or switched-off block before it reads a manifest, parses an
|
|
107
|
+
// override, or validates anything — so doing any of that here invents a
|
|
108
|
+
// failure for a plugin that has none, and the renderer shows no tools
|
|
109
|
+
// for one either way. Gating the whole block rather than each call is
|
|
110
|
+
// deliberate: gating them one at a time is what left the override parse
|
|
111
|
+
// unconditional after the preflight moved.
|
|
112
|
+
if (!base.installed || !base.enabled) {
|
|
113
|
+
plugins.push(base);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const { manifest, directory } = await readPluginManifest(specifier, {
|
|
118
|
+
resolve: (target) => import.meta.resolve(target),
|
|
119
|
+
});
|
|
120
|
+
const floor = riskFloorFor(isFirstPartyPackage(manifest.packageName));
|
|
121
|
+
const overrides = parseToolRiskOverrides(manifest, block);
|
|
122
|
+
// Everything the loader checks before importing, through the loader's
|
|
123
|
+
// own function — a plugin whose settings or skill files it rejects
|
|
124
|
+
// registers nothing, and reading here as enabled is the false clean
|
|
125
|
+
// bill this command exists to stop giving.
|
|
126
|
+
//
|
|
127
|
+
// Only for a plugin the loader would actually reach, though: it skips
|
|
128
|
+
// an absent or switched-off block before validating anything, so
|
|
129
|
+
// preflighting one would report `plugin-mcp` that nobody configured as
|
|
130
|
+
// broken settings instead of as the install to enable.
|
|
131
|
+
if (base.enabled) {
|
|
132
|
+
await preflightPlugin(manifest, directory, block, workspaceRoot);
|
|
133
|
+
}
|
|
134
|
+
// One row per tool the report will name, tracked as they are emitted.
|
|
135
|
+
// A concrete name can be reached more than one way — declared outright
|
|
136
|
+
// *and* covered by a namespace, or covered by two nested namespaces
|
|
137
|
+
// like `mcp.*` and `mcp.linear.*` — and every one of those is a single
|
|
138
|
+
// runtime tool. Filtering each source against the others is what
|
|
139
|
+
// produced two rounds of duplicate rows; one set, checked as rows are
|
|
140
|
+
// added, cannot miss a path.
|
|
141
|
+
const seen = new Set();
|
|
142
|
+
const declared = [];
|
|
143
|
+
const emit = (row) => {
|
|
144
|
+
if (seen.has(row.name)) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
seen.add(row.name);
|
|
148
|
+
declared.push(row);
|
|
149
|
+
};
|
|
150
|
+
// Literal declarations first: a name the manifest states outright is
|
|
151
|
+
// described best by its own entry, not by a namespace that covers it.
|
|
152
|
+
// Risk through `declaredRiskFor`, never the declaration in hand: with
|
|
153
|
+
// overlapping namespaces (`mcp.*` and `mcp.linear.*`) it is the *first*
|
|
154
|
+
// match that registration uses, so reading each entry's own risk would
|
|
155
|
+
// show a narrower namespace at a risk none of its tools will have.
|
|
156
|
+
const riskOf = (name, fallback) => declaredRiskFor(manifest, name) ?? fallback;
|
|
157
|
+
for (const tool of manifest.contributes.tools) {
|
|
158
|
+
emit({ name: tool.name, discovered: false, namespace: false, declared: riskOf(tool.name, tool.risk) });
|
|
159
|
+
}
|
|
160
|
+
for (const entry of manifest.contributes.toolsDiscovered) {
|
|
161
|
+
emit({
|
|
162
|
+
name: entry.namespace,
|
|
163
|
+
discovered: true,
|
|
164
|
+
namespace: true,
|
|
165
|
+
declared: riskOf(entry.namespace, entry.risk),
|
|
166
|
+
});
|
|
167
|
+
// An override under a declared namespace names a concrete tool
|
|
168
|
+
// (`mcp.linear.get_issue`), which is the whole point of the key for
|
|
169
|
+
// a bridge — and it can never equal the namespace, so the namespace
|
|
170
|
+
// row alone would report the default risk for a tool the operator
|
|
171
|
+
// has deliberately re-rated. Listed beside it rather than folded in:
|
|
172
|
+
// they are different risks, and which tools carry the override is
|
|
173
|
+
// the thing worth seeing.
|
|
174
|
+
for (const name of overrides.keys()) {
|
|
175
|
+
// Any wildcard key, not merely the declared namespace itself: the
|
|
176
|
+
// registry applies an override by each concrete *registered*
|
|
177
|
+
// name, so a nested `mcp.linear.*` is exactly as inert as
|
|
178
|
+
// `mcp.*`. Excluding only the equal case left the nested one
|
|
179
|
+
// advertising a re-rating no call gets.
|
|
180
|
+
if (name.endsWith('.*')) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (matchesToolAllowlist(name, [entry.namespace])) {
|
|
184
|
+
emit({ name, discovered: true, namespace: false, declared: riskOf(name, entry.risk) });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// A warning, not a failure. Ownership is claimed at registration —
|
|
189
|
+
// `view.commit(owners)` records what `setup()` actually registered —
|
|
190
|
+
// so a name two manifests both declare collides only if both plugins
|
|
191
|
+
// go on to register it, which nothing here can know. Reporting it as
|
|
192
|
+
// a load failure would condemn a plugin that loads perfectly well
|
|
193
|
+
// because its tool is optional.
|
|
194
|
+
// Keyed by config entry, never by package name: the same package
|
|
195
|
+
// configured through two specifiers is two entries the loader treats
|
|
196
|
+
// as two plugins, and exempting them for sharing a `packageName`
|
|
197
|
+
// would hide the collision an operator is likeliest to create by
|
|
198
|
+
// accident.
|
|
199
|
+
//
|
|
200
|
+
// A plugin never collides with itself: everything it declares is
|
|
201
|
+
// gathered first, checked against what came before, and only then
|
|
202
|
+
// added. That ordering is what makes a manifest declaring both
|
|
203
|
+
// `mcp.ping` and `mcp.*` silent — it registers that name once — and
|
|
204
|
+
// it is load-bearing, so adding claims inside the loop below would
|
|
205
|
+
// reintroduce a warning telling operators to fix a working config.
|
|
206
|
+
const declaredHere = [
|
|
207
|
+
...manifest.contributes.tools.map((tool) => tool.name),
|
|
208
|
+
...manifest.contributes.toolsDiscovered.map((entry) => entry.namespace),
|
|
209
|
+
];
|
|
210
|
+
for (const pattern of declaredHere) {
|
|
211
|
+
for (const claim of claims) {
|
|
212
|
+
if (!toolScopesOverlap(pattern, claim.pattern)) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
const subject = pattern === claim.pattern
|
|
216
|
+
? `${pattern} is`
|
|
217
|
+
: `${pattern} overlaps ${claim.pattern}, which is`;
|
|
218
|
+
// One sentence for every collision, because a manifest cannot
|
|
219
|
+
// tell when a name registers and the cost turns entirely on
|
|
220
|
+
// that. `ManifestBoundToolRegistry` stages while `owners` is
|
|
221
|
+
// unset and registers live once `commit` sets it, so a clash
|
|
222
|
+
// before the plugin commits rolls it back whole and a clash
|
|
223
|
+
// after refuses that one registration. Neither side of the
|
|
224
|
+
// declaration says which: a bridge's first connect happens
|
|
225
|
+
// inside `setup()` when its server is up and on a reconnect
|
|
226
|
+
// when it is not, and a plugin may hold `context.tools` and
|
|
227
|
+
// register a plainly-named tool from a timer long after.
|
|
228
|
+
//
|
|
229
|
+
// Three rounds of review went into splitting this by
|
|
230
|
+
// declaration kind, then by which side of the pair held the
|
|
231
|
+
// namespace. Both splits claimed knowledge the manifest does
|
|
232
|
+
// not have. Do not reintroduce one.
|
|
233
|
+
base.warnings = [
|
|
234
|
+
...(base.warnings ?? []),
|
|
235
|
+
`${subject} ${claim.registered ? 'already registered by' : 'also declared by'} ${claim.owner}; `
|
|
236
|
+
+ 'if both register that name, a daemon keeps the first and refuses the second registration — '
|
|
237
|
+
+ 'the whole plugin, tools and skills together, if it happens before that plugin finishes loading, '
|
|
238
|
+
+ 'or just that one tool if it happens after',
|
|
239
|
+
];
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
for (const pattern of declaredHere) {
|
|
243
|
+
claims.push({ pattern, owner: specifier, registered: false });
|
|
244
|
+
}
|
|
245
|
+
// Skills collide on the qualified `packageName:id`, so a clash means
|
|
246
|
+
// one package configured twice — the two-specifier case again. Firmer
|
|
247
|
+
// than the tool warning and worded that way: the loader stages skills
|
|
248
|
+
// from the manifest and refuses the second entry outright rather than
|
|
249
|
+
// waiting to see what `setup()` does. Still "if it loads", since a
|
|
250
|
+
// plugin that fails to import never reaches the check.
|
|
251
|
+
for (const skill of manifest.contributes.skills) {
|
|
252
|
+
const qualified = `${manifest.packageName}:${skill.id}`;
|
|
253
|
+
const owner = claimedSkills.get(qualified);
|
|
254
|
+
if (owner !== undefined) {
|
|
255
|
+
base.warnings = [
|
|
256
|
+
...(base.warnings ?? []),
|
|
257
|
+
`skill ${qualified} is already declared by ${owner}; if both load, a daemon keeps the first `
|
|
258
|
+
+ 'and refuses this one whole, tools and skills together',
|
|
259
|
+
];
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
claimedSkills.set(qualified, specifier);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
base.tools = declared.map((tool) => {
|
|
266
|
+
// Never on the namespace row. `parseToolRiskOverrides` accepts a
|
|
267
|
+
// namespace-shaped key, but the registry looks an override up by
|
|
268
|
+
// each concrete *registered* name — so `toolRisks: { "mcp.*": … }`
|
|
269
|
+
// changes no call, and showing the row at that risk would advertise
|
|
270
|
+
// a re-rating the daemon will not honour.
|
|
271
|
+
const override = tool.namespace ? undefined : overrides.get(tool.name);
|
|
272
|
+
return {
|
|
273
|
+
name: tool.name,
|
|
274
|
+
discovered: tool.discovered,
|
|
275
|
+
risk: override !== undefined
|
|
276
|
+
? raiseRiskTo(override, floor)
|
|
277
|
+
: raiseRiskTo(tool.declared, floor),
|
|
278
|
+
grantedTo: grantedTo(tool.name, tool.discovered),
|
|
279
|
+
};
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
// Reported per plugin rather than thrown: one package with a broken
|
|
284
|
+
// manifest must not take down the listing that would have shown it.
|
|
285
|
+
base.problem = error instanceof Error ? error.message : String(error);
|
|
286
|
+
}
|
|
287
|
+
plugins.push(base);
|
|
288
|
+
}
|
|
289
|
+
const mode = approvals.mode ?? 'headless';
|
|
290
|
+
return {
|
|
291
|
+
approvals: mode,
|
|
292
|
+
approvalsSummary: await describeUnattendedReach(mode, approvals, env, rosterUnreadable ? undefined : roster.map((entry) => entry.soul.agent.id), apiReachable),
|
|
293
|
+
rosterUnreadable,
|
|
294
|
+
plugins,
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
/** `stratus plugins` — the chain from installed to callable, per plugin. */
|
|
298
|
+
export const runPlugins = async (command, streams, env = {}) => {
|
|
299
|
+
const report = await collectPluginsReport(command, env, (line) => {
|
|
300
|
+
writeLine(streams.stderr, `Warning: ${line}`);
|
|
301
|
+
});
|
|
302
|
+
if (command.format === 'json') {
|
|
303
|
+
writeLine(streams.stdout, JSON.stringify(report, null, 2));
|
|
304
|
+
return 0;
|
|
305
|
+
}
|
|
306
|
+
writeLine(streams.stdout, `approvals: ${report.approvalsSummary}`);
|
|
307
|
+
writeLine(streams.stdout);
|
|
308
|
+
for (const plugin of report.plugins) {
|
|
309
|
+
const state = !plugin.installed
|
|
310
|
+
? 'not installed'
|
|
311
|
+
: !plugin.configured
|
|
312
|
+
? 'installed, not enabled'
|
|
313
|
+
: !plugin.enabled
|
|
314
|
+
? 'installed, switched off'
|
|
315
|
+
// Enabled and loadable are separate: a plugin whose settings its
|
|
316
|
+
// own schema rejects is enabled and registers nothing, and saying
|
|
317
|
+
// only "enabled" here is the false clean bill this command exists
|
|
318
|
+
// to stop giving.
|
|
319
|
+
: plugin.problem !== undefined ? 'installed, enabled, will not load' : 'installed, enabled';
|
|
320
|
+
// Padded to a column, but never run together: a package name longer
|
|
321
|
+
// than the column would otherwise touch its own status.
|
|
322
|
+
writeLine(streams.stdout, `${plugin.package.padEnd(29)} ${state}`);
|
|
323
|
+
if (plugin.problem !== undefined) {
|
|
324
|
+
writeLine(streams.stdout, ` a daemon would register nothing for it: ${plugin.problem}`);
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (!plugin.installed) {
|
|
328
|
+
writeLine(streams.stdout, ` install it: npm install -g ${plugin.package}`);
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
// Nothing is registered for a plugin that will not load, so its tools
|
|
332
|
+
// are not listed: a grant column beside a name no agent can call reads
|
|
333
|
+
// as capability this machine has.
|
|
334
|
+
if (!plugin.configured) {
|
|
335
|
+
writeLine(streams.stdout, ` installing granted nothing — add "${plugin.package}" to the plugins block of a trusted config to load it`);
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
if (!plugin.enabled) {
|
|
339
|
+
writeLine(streams.stdout, ' switched off — remove "enabled": false to load it');
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
for (const warning of plugin.warnings ?? []) {
|
|
343
|
+
writeLine(streams.stdout, ` warning: ${warning}`);
|
|
344
|
+
}
|
|
345
|
+
for (const tool of plugin.tools) {
|
|
346
|
+
const granted = report.rosterUnreadable
|
|
347
|
+
? ''
|
|
348
|
+
: tool.grantedTo.length > 0
|
|
349
|
+
? ` → ${tool.grantedTo.join(', ')}`
|
|
350
|
+
: ' → nobody, until a soul’s tools: list names it';
|
|
351
|
+
const shape = tool.discovered ? ' (names arrive at connect)' : '';
|
|
352
|
+
writeLine(streams.stdout, ` ${tool.name.padEnd(28)}${tool.risk}${shape}${granted}`);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
writeLine(streams.stdout);
|
|
356
|
+
writeLine(streams.stdout, `More plugins — ${PLUGIN_MARKETPLACE_URL}`);
|
|
357
|
+
return 0;
|
|
358
|
+
};
|
|
359
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/commands/plugins.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CliStreams, CliEnvironment } from '../environment.ts';
|
|
2
|
+
import type { ParsedRestartCommand } from '../parse.ts';
|
|
3
|
+
export declare const runRestart: (command: ParsedRestartCommand, streams: CliStreams, env?: CliEnvironment) => Promise<number>;
|
|
4
|
+
//# sourceMappingURL=restart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart.d.ts","sourceRoot":"","sources":["../../src/commands/restart.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,eAAO,MAAM,UAAU,GACrB,SAAS,oBAAoB,EAC7B,SAAS,UAAU,EACnB,MAAK,cAAmB,KACvB,OAAO,CAAC,MAAM,CAwBhB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { runningGatewayBase, callRunningGateway, gatewayErrorMessage, noRunningDaemonMessage, } from "../daemon.js";
|
|
2
|
+
import { writeLine } from "../io.js";
|
|
3
|
+
export const runRestart = async (command, streams, env = {}) => {
|
|
4
|
+
const base = await runningGatewayBase(env, command);
|
|
5
|
+
if (!base) {
|
|
6
|
+
writeLine(streams.stderr, `Error: ${noRunningDaemonMessage(env)}`);
|
|
7
|
+
return 1;
|
|
8
|
+
}
|
|
9
|
+
const response = await callRunningGateway(env, command, base, '/api/v1/restart', {
|
|
10
|
+
reason: command.reason ?? 'stratus restart',
|
|
11
|
+
...(command.drainTimeoutMs !== undefined ? { drainTimeoutMs: command.drainTimeoutMs } : {}),
|
|
12
|
+
});
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
writeLine(streams.stderr, `Error: ${await gatewayErrorMessage(response)}`);
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
const status = await response.json();
|
|
18
|
+
const inflight = status.inflight ?? 0;
|
|
19
|
+
const window = Math.round((status.drainTimeoutMs ?? 0) / 1000);
|
|
20
|
+
writeLine(streams.stdout, `restart announced to the daemon at ${base} — new turns are refused; ${inflight} turn(s) in flight `
|
|
21
|
+
+ `get up to ${window}s to finish, then it comes back.`);
|
|
22
|
+
writeLine(streams.stdout, 'Watch it come back: stratus logs -f');
|
|
23
|
+
return 0;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=restart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart.js","sourceRoot":"","sources":["../../src/commands/restart.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,OAA6B,EAC7B,OAAmB,EACnB,MAAsB,EAAE,EACP,EAAE;IACnB,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE;QAC/E,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,iBAAiB;QAC3C,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5F,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,MAAM,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC3E,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAoD,CAAC;IACvF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC/D,SAAS,CACP,OAAO,CAAC,MAAM,EACd,sCAAsC,IAAI,6BAA6B,QAAQ,qBAAqB;UAClG,aAAa,MAAM,kCAAkC,CACxD,CAAC;IACF,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,qCAAqC,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC;AACX,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CliStreams, CliEnvironment } from '../environment.ts';
|
|
2
|
+
import type { ParsedSchedulesCommand } from '../parse.ts';
|
|
3
|
+
/**
|
|
4
|
+
* List and cancel what the fleet has scheduled — against the daemon's own
|
|
5
|
+
* database, the way `stratus logs` reads the daemon's own log. WAL makes a
|
|
6
|
+
* second process on the file routine; a running daemon re-reads due rows
|
|
7
|
+
* every tick and the destination grant on every send, so a cancel from
|
|
8
|
+
* here takes effect without asking it anything.
|
|
9
|
+
*/
|
|
10
|
+
export declare const runSchedules: (command: ParsedSchedulesCommand, streams: CliStreams, env?: CliEnvironment) => Promise<number>;
|
|
11
|
+
//# sourceMappingURL=schedules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedules.d.ts","sourceRoot":"","sources":["../../src/commands/schedules.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEpE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GACvB,SAAS,sBAAsB,EAC/B,SAAS,UAAU,EACnB,MAAK,cAAmB,KACvB,OAAO,CAAC,MAAM,CAuChB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { canonicalDestination, describeCadence, describeSchedule } from '@stratusagent/agents';
|
|
2
|
+
import { writeLine } from "../io.js";
|
|
3
|
+
/**
|
|
4
|
+
* List and cancel what the fleet has scheduled — against the daemon's own
|
|
5
|
+
* database, the way `stratus logs` reads the daemon's own log. WAL makes a
|
|
6
|
+
* second process on the file routine; a running daemon re-reads due rows
|
|
7
|
+
* every tick and the destination grant on every send, so a cancel from
|
|
8
|
+
* here takes effect without asking it anything.
|
|
9
|
+
*/
|
|
10
|
+
export const runSchedules = async (command, streams, env = {}) => {
|
|
11
|
+
// Lazy like the serve path: node:sqlite loads only for the command that
|
|
12
|
+
// needs it.
|
|
13
|
+
const { SqliteScheduleStore, defaultSessionDbPath } = await import('@stratusagent/gateway');
|
|
14
|
+
const store = new SqliteScheduleStore(defaultSessionDbPath(env));
|
|
15
|
+
try {
|
|
16
|
+
if (command.action === 'cancel') {
|
|
17
|
+
const id = command.scheduleId ?? '';
|
|
18
|
+
const record = store.get(id);
|
|
19
|
+
if (!record || !store.delete(id)) {
|
|
20
|
+
writeLine(streams.stderr, `No schedule with id ${id}. \`stratus schedules\` lists what exists.`);
|
|
21
|
+
return 1;
|
|
22
|
+
}
|
|
23
|
+
writeLine(streams.stdout, `Cancelled ${id} (${record.agentId}, ${describeCadence(record.cadence)}).`);
|
|
24
|
+
if (record.destination) {
|
|
25
|
+
writeLine(streams.stdout, `Its pre-authorized destination ${canonicalDestination(record.destination)} is revoked with it.`);
|
|
26
|
+
}
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
const schedules = store.list();
|
|
30
|
+
if (command.format === 'json') {
|
|
31
|
+
writeLine(streams.stdout, JSON.stringify({ schedules: schedules.map(describeSchedule) }, null, 2));
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
if (schedules.length === 0) {
|
|
35
|
+
writeLine(streams.stdout, 'No schedules set. An agent sets one with the schedule.every / schedule.at tools.');
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
for (const record of schedules) {
|
|
39
|
+
const destination = record.destination ? ` → ${canonicalDestination(record.destination)}` : '';
|
|
40
|
+
writeLine(streams.stdout, `${record.id} [${record.agentId}] ${describeCadence(record.cadence)}${destination}`);
|
|
41
|
+
writeLine(streams.stdout, ` next: ${record.nextFireAt ?? '(spent — awaiting cleanup)'}${record.lastFiredAt ? ` last: ${record.lastFiredAt}` : ''}`);
|
|
42
|
+
writeLine(streams.stdout, ` prompt: ${record.prompt}`);
|
|
43
|
+
}
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
store.close();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=schedules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedules.js","sourceRoot":"","sources":["../../src/commands/schedules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CliStreams, CliEnvironment } from '../environment.ts';
|
|
2
|
+
import type { ParsedServeCommand } from '../parse.ts';
|
|
3
|
+
export declare const runServe: (command: ParsedServeCommand, streams: CliStreams, env?: CliEnvironment) => Promise<number>;
|
|
4
|
+
//# sourceMappingURL=serve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAoB,MAAM,mBAAmB,CAAC;AAItF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAiBtD,eAAO,MAAM,QAAQ,GACnB,SAAS,kBAAkB,EAC3B,SAAS,UAAU,EACnB,MAAK,cAAmB,KACvB,OAAO,CAAC,MAAM,CAuDhB,CAAC"}
|