@aragon-agent/cli 0.6.3 → 0.6.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.
- package/CHANGELOG.md +105 -0
- package/README.md +95 -2
- package/dist/agent/controller.d.ts +119 -0
- package/dist/agent/controller.js +275 -1
- package/dist/agent/reducer.d.ts +69 -0
- package/dist/agent/reducer.js +100 -0
- package/dist/agent/system-prompt.d.ts +14 -0
- package/dist/agent/system-prompt.js +2 -0
- package/dist/cli.js +84 -22
- package/dist/commands/builtins.js +92 -1
- package/dist/compaction/child.js +5 -0
- package/dist/compaction/command.js +14 -1
- package/dist/compaction/compactor.d.ts +34 -0
- package/dist/compaction/compactor.js +158 -37
- package/dist/compaction/types.d.ts +36 -0
- package/dist/compaction/wiring.d.ts +9 -0
- package/dist/compaction/wiring.js +22 -1
- package/dist/config/env.d.ts +1 -1
- package/dist/config/env.js +48 -1
- package/dist/config/load.d.ts +11 -0
- package/dist/config/load.js +39 -1
- package/dist/config/schema.d.ts +85 -0
- package/dist/config/schema.js +33 -0
- package/dist/config/store.js +21 -1
- package/dist/input/limits.d.ts +72 -0
- package/dist/input/limits.js +63 -0
- package/dist/input/paste-parse.d.ts +71 -0
- package/dist/input/paste-parse.js +95 -0
- package/dist/input/stdin-filter.d.ts +81 -0
- package/dist/input/stdin-filter.js +379 -0
- package/dist/logging/install.d.ts +2 -0
- package/dist/logging/install.js +53 -1
- package/dist/proc/classify.d.ts +52 -0
- package/dist/proc/classify.js +143 -0
- package/dist/proc/kill-tree.d.ts +42 -0
- package/dist/proc/kill-tree.js +119 -0
- package/dist/proc/limits.d.ts +84 -0
- package/dist/proc/limits.js +84 -0
- package/dist/proc/log-ring.d.ts +68 -0
- package/dist/proc/log-ring.js +102 -0
- package/dist/proc/prompt.d.ts +24 -0
- package/dist/proc/prompt.js +49 -0
- package/dist/proc/readiness.d.ts +102 -0
- package/dist/proc/readiness.js +219 -0
- package/dist/proc/supervisor.d.ts +103 -0
- package/dist/proc/supervisor.js +465 -0
- package/dist/proc/types.d.ts +175 -0
- package/dist/proc/types.js +15 -0
- package/dist/session/persist.js +36 -1
- package/dist/tools/bash-tool.d.ts +51 -2
- package/dist/tools/bash-tool.js +321 -51
- package/dist/tools/fs-tools.d.ts +17 -0
- package/dist/tools/index.d.ts +55 -2
- package/dist/tools/index.js +39 -1
- package/dist/tools/proc-tools.d.ts +25 -0
- package/dist/tools/proc-tools.js +102 -0
- package/dist/ui/App.d.ts +15 -2
- package/dist/ui/App.js +256 -7
- package/dist/ui/Composer.d.ts +54 -1
- package/dist/ui/Composer.js +50 -6
- package/dist/ui/PromptInput.d.ts +49 -3
- package/dist/ui/PromptInput.js +184 -52
- package/dist/ui/StatusBar.d.ts +19 -0
- package/dist/ui/StatusBar.js +5 -2
- package/dist/ui/Transcript.js +29 -1
- package/dist/ui/composer-limits.d.ts +31 -0
- package/dist/ui/composer-limits.js +50 -0
- package/dist/ui/composer-rows.d.ts +73 -0
- package/dist/ui/composer-rows.js +201 -0
- package/dist/ui/editor-reducer.d.ts +37 -0
- package/dist/ui/editor-reducer.js +88 -12
- package/dist/ui/entries/ServiceCard.d.ts +66 -0
- package/dist/ui/entries/ServiceCard.js +116 -0
- package/dist/ui/entries/UserEntry.d.ts +17 -3
- package/dist/ui/entries/UserEntry.js +34 -5
- package/dist/ui/layout/budget.d.ts +34 -6
- package/dist/ui/layout/budget.js +32 -7
- package/dist/ui/layout/virtual-window.js +51 -1
- package/dist/ui/overlays/HelpOverlay.js +3 -0
- package/dist/ui/overlays/PlanReviewOverlay.js +10 -2
- package/dist/ui/overlays/QuestionOverlay.js +5 -1
- package/dist/ui/overlays/SettingsScreen.js +14 -1
- package/dist/ui/paste-frames.d.ts +87 -0
- package/dist/ui/paste-frames.js +112 -0
- package/dist/ui/paste-tokens.d.ts +90 -0
- package/dist/ui/paste-tokens.js +147 -0
- package/dist/ui/screen.d.ts +16 -0
- package/dist/ui/screen.js +45 -2
- package/dist/ui/selection/selection-controller.d.ts +1 -1
- package/dist/ui/transcript-text.js +49 -0
- package/dist/ui/use-wheel-routing.d.ts +1 -1
- package/package.json +2 -2
- package/dist/input/stdin-mouse-filter.d.ts +0 -47
- package/dist/input/stdin-mouse-filter.js +0 -153
package/dist/tools/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { type AgentTool, type ToolPolicyDecision, type ToolPolicyVerdict } from
|
|
|
12
12
|
import type { AgentMode } from '../agent/agent-mode.js';
|
|
13
13
|
import type { ToolPermission } from '../exec/permission.js';
|
|
14
14
|
import type { FilePatch } from './patch.js';
|
|
15
|
+
import type { ProcSupervisorPort } from '../proc/types.js';
|
|
15
16
|
export interface ConfirmRequest {
|
|
16
17
|
tool: string;
|
|
17
18
|
summary: string;
|
|
@@ -151,6 +152,58 @@ export interface BuiltinToolsOptions {
|
|
|
151
152
|
* `--no-skills` is.
|
|
152
153
|
*/
|
|
153
154
|
teamTools?: AgentTool[];
|
|
155
|
+
/**
|
|
156
|
+
* The process supervisor (background-service-supervision §3.5).
|
|
157
|
+
*
|
|
158
|
+
* THE TWO-INTERFACE RULE: it is declared on `ToolDeps` as well, and adding it
|
|
159
|
+
* to only one of the two type-checks and forwards nothing — `bash` never sees
|
|
160
|
+
* a supervisor and every long-running command keeps hanging, with nothing
|
|
161
|
+
* anywhere erroring. Both, or neither.
|
|
162
|
+
*
|
|
163
|
+
* The conditional spread below is what makes I-2 true at this layer: with
|
|
164
|
+
* background services off the controller passes no key, so no property is
|
|
165
|
+
* added and `deps` is the object it is today.
|
|
166
|
+
*/
|
|
167
|
+
procs?: ProcSupervisorPort;
|
|
168
|
+
/**
|
|
169
|
+
* `bash_output` / `bash_kill`, appended verbatim.
|
|
170
|
+
*
|
|
171
|
+
* THROUGH THE FACTORY FOR THE REASON `teamTools` AND `todoTools` EACH RECORD
|
|
172
|
+
* IN CAPITALS (P0-2): `tools.test.ts::C7` asserts `HOST_TOOL_NAMES` equals
|
|
173
|
+
* what this factory PRODUCES, so appending these two in `AgentController`
|
|
174
|
+
* after the factory returned would turn C7 red with a message about two lists
|
|
175
|
+
* of names that says nothing about background services.
|
|
176
|
+
*
|
|
177
|
+
* An empty array (`bash.background: false`) leaves the tool list
|
|
178
|
+
* byte-identical to the pre-feature build — I-2, provable by object identity
|
|
179
|
+
* exactly as `--no-skills` and `--no-team` are.
|
|
180
|
+
*/
|
|
181
|
+
procTools?: AgentTool[];
|
|
182
|
+
/**
|
|
183
|
+
* `cfg.bash.autoBackground`, READ AT CALL TIME.
|
|
184
|
+
*
|
|
185
|
+
* Never cached: `aragon config set bash.autoBackground false` takes effect in
|
|
186
|
+
* the running session, and a cached `true` would go on backgrounding commands
|
|
187
|
+
* the user just told it not to.
|
|
188
|
+
*/
|
|
189
|
+
autoBackground?: () => boolean;
|
|
190
|
+
/** `cfg.bash.startupSettleMs`, read at call time for the same reason. */
|
|
191
|
+
startupSettleMs?: () => number;
|
|
192
|
+
/**
|
|
193
|
+
* Whether this session can render a service card and keep a service alive
|
|
194
|
+
* (D-15 / P1-8).
|
|
195
|
+
*
|
|
196
|
+
* FALSE UNDER `aragon exec` AND `-p`. It suppresses only the CLASSIFIER: an
|
|
197
|
+
* explicit `background: true` is still honoured, and its result then says the
|
|
198
|
+
* service dies with the run. Without it `aragon -p "npm run dev"` would
|
|
199
|
+
* background a server, return in `startupSettleMs`, and reap it at process
|
|
200
|
+
* exit with nothing anywhere saying so.
|
|
201
|
+
*
|
|
202
|
+
* It is the SAME SIGNAL `planTools` already uses to decide that no overlay can
|
|
203
|
+
* be rendered, so this costs one boolean rather than a new capability probe.
|
|
204
|
+
* Absent means interactive, which is what every existing caller is.
|
|
205
|
+
*/
|
|
206
|
+
interactive?: boolean;
|
|
154
207
|
/**
|
|
155
208
|
* Tool names that skip the CEILING wrapper only (never the plan gate, never
|
|
156
209
|
* confirmation).
|
|
@@ -199,7 +252,7 @@ export interface BuiltinToolsOptions {
|
|
|
199
252
|
* is the whole of what this mechanism is worth, and saying so plainly beats
|
|
200
253
|
* implying it covers more.
|
|
201
254
|
*/
|
|
202
|
-
export declare const SKILL_TOOL_FLOOR: readonly ["read_file", "list_dir", "glob", "grep", "skill", "skill_find", "ask_user", "submit_plan", "task", "todo_write"];
|
|
255
|
+
export declare const SKILL_TOOL_FLOOR: readonly ["read_file", "list_dir", "glob", "grep", "skill", "skill_find", "ask_user", "submit_plan", "task", "todo_write", "bash_output"];
|
|
203
256
|
/**
|
|
204
257
|
* The five tools plan mode refuses: exactly the complement of `SKILL_TOOL_FLOOR`
|
|
205
258
|
* within `HOST_TOOL_NAMES` — "the five that change something", the set this file
|
|
@@ -232,5 +285,5 @@ export declare const PLAN_MODE_BLOCKED_TOOLS: ReadonlySet<string>;
|
|
|
232
285
|
* declaration MEANS, and that reading must not change with how the CLI was
|
|
233
286
|
* started.
|
|
234
287
|
*/
|
|
235
|
-
export declare const HOST_TOOL_NAMES: readonly ["read_file", "write_file", "edit_file", "list_dir", "glob", "grep", "bash", "skill", "skill_find", "skill_install", "skill_create", "ask_user", "submit_plan", "todo_write", "task"];
|
|
288
|
+
export declare const HOST_TOOL_NAMES: readonly ["read_file", "write_file", "edit_file", "list_dir", "glob", "grep", "bash", "skill", "skill_find", "skill_install", "skill_create", "ask_user", "submit_plan", "todo_write", "bash_output", "bash_kill", "task"];
|
|
236
289
|
export declare function createBuiltinTools(options: BuiltinToolsOptions): AgentTool[];
|
package/dist/tools/index.js
CHANGED
|
@@ -59,6 +59,12 @@ export const SKILL_TOOL_FLOOR = [
|
|
|
59
59
|
// inside that skill's frame — the identical dead end that put `ask_user` /
|
|
60
60
|
// `submit_plan` / `task` here.
|
|
61
61
|
'todo_write',
|
|
62
|
+
// `bash_output` joins the FLOOR rather than the blocked set (D-12), and the
|
|
63
|
+
// partition test below is what forces that choice to be conscious. It READS A
|
|
64
|
+
// BUFFER: it cannot write to disk or run a shell, which is the floor's stated
|
|
65
|
+
// membership test. Blocking it in plan mode would also let the agent start a
|
|
66
|
+
// service it then could not read — the dead end the floor exists to prevent.
|
|
67
|
+
'bash_output',
|
|
62
68
|
];
|
|
63
69
|
/**
|
|
64
70
|
* The five tools plan mode refuses: exactly the complement of `SKILL_TOOL_FLOOR`
|
|
@@ -77,6 +83,11 @@ export const PLAN_MODE_BLOCKED_TOOLS = new Set([
|
|
|
77
83
|
'bash',
|
|
78
84
|
'skill_install',
|
|
79
85
|
'skill_create',
|
|
86
|
+
// `bash_kill` joins the BLOCKED set (D-12). It TERMINATES A PROCESS, which is
|
|
87
|
+
// a mutation of the world and the complement's stated membership test. Nothing
|
|
88
|
+
// is dead-ended by it: `Ctrl+C` and `/bg stop` both remain available to the
|
|
89
|
+
// USER in plan mode, so the person can always stop what the agent started.
|
|
90
|
+
'bash_kill',
|
|
80
91
|
]);
|
|
81
92
|
/**
|
|
82
93
|
* Every tool name this host CAN register (7 built-ins + 4 skill tools).
|
|
@@ -113,6 +124,13 @@ export const HOST_TOOL_NAMES = [
|
|
|
113
124
|
'ask_user',
|
|
114
125
|
'submit_plan',
|
|
115
126
|
'todo_write',
|
|
127
|
+
// Both names are here even though `bash.background: false` registers NEITHER,
|
|
128
|
+
// and that is the constant's documented meaning rather than an inconsistency:
|
|
129
|
+
// it is the SUPERSET of what this host CAN register, answering "can a skill's
|
|
130
|
+
// `allowed-tools` declaration ever take effect?" — the same relationship
|
|
131
|
+
// `skills doctor` already has with `--no-skills`.
|
|
132
|
+
'bash_output',
|
|
133
|
+
'bash_kill',
|
|
116
134
|
// `team_send` / `team_wait` are DELIBERATELY ABSENT (P2-5). This constant
|
|
117
135
|
// answers "can a skill's `allowed-tools` declaration ever take effect?", and
|
|
118
136
|
// those two are never registered on a lead — so a skill naming them genuinely
|
|
@@ -221,6 +239,10 @@ export function createBuiltinTools(options) {
|
|
|
221
239
|
...(options.recordChange ? { recordChange: options.recordChange } : {}),
|
|
222
240
|
// Added in the same shape and for the same reason (P1-1).
|
|
223
241
|
...(options.recordOutput ? { recordOutput: options.recordOutput } : {}),
|
|
242
|
+
// And the third, in the same shape and for the same reason. The FORWARD half
|
|
243
|
+
// of the two-interface note on `procs` above: without this line the field is
|
|
244
|
+
// on both interfaces, nothing errors, and `bash` still hangs.
|
|
245
|
+
...(options.procs ? { procs: options.procs } : {}),
|
|
224
246
|
};
|
|
225
247
|
let tools = [
|
|
226
248
|
makeReadFile(deps),
|
|
@@ -229,7 +251,18 @@ export function createBuiltinTools(options) {
|
|
|
229
251
|
makeListDir(deps),
|
|
230
252
|
makeGlob(deps),
|
|
231
253
|
makeGrep(deps),
|
|
232
|
-
|
|
254
|
+
// The second argument is spread CONDITIONALLY on the supervisor being
|
|
255
|
+
// present, so with background services off `makeBash` receives its default
|
|
256
|
+
// `{}` and produces the pre-feature tool: no `background` property in the
|
|
257
|
+
// schema, the pre-feature description string, no supervisor call (I-2).
|
|
258
|
+
makeBash(deps, options.procs
|
|
259
|
+
? {
|
|
260
|
+
supervisor: options.procs,
|
|
261
|
+
...(options.autoBackground ? { autoBackground: options.autoBackground } : {}),
|
|
262
|
+
...(options.startupSettleMs ? { startupSettleMs: options.startupSettleMs } : {}),
|
|
263
|
+
...(options.interactive !== undefined ? { interactive: options.interactive } : {}),
|
|
264
|
+
}
|
|
265
|
+
: {}),
|
|
233
266
|
];
|
|
234
267
|
if (options.confirmTools && options.confirm) {
|
|
235
268
|
const confirm = options.confirm;
|
|
@@ -246,6 +279,11 @@ export function createBuiltinTools(options) {
|
|
|
246
279
|
if (options.todoTools && options.todoTools.length > 0) {
|
|
247
280
|
tools = [...tools, ...options.todoTools];
|
|
248
281
|
}
|
|
282
|
+
// AFTER `todoTools`, BEFORE `teamTools`, so a lead's `task` stays last and
|
|
283
|
+
// `HOST_TOOL_NAMES` changes by two insertions rather than a reshuffle.
|
|
284
|
+
if (options.procTools && options.procTools.length > 0) {
|
|
285
|
+
tools = [...tools, ...options.procTools];
|
|
286
|
+
}
|
|
249
287
|
// BEFORE both wrappers, so the lead's `task` is covered by the plan gate and
|
|
250
288
|
// the ceiling like everything else, and a child's comm tools are covered by
|
|
251
289
|
// everything except the ceiling (see `policyExempt`).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `bash_output` and `bash_kill` — the model's two handles on a supervised
|
|
3
|
+
* service (background-service-supervision §5.1).
|
|
4
|
+
*
|
|
5
|
+
* REGISTERED THROUGH A FACTORY OPTION, NEVER APPENDED AFTER THE FACT
|
|
6
|
+
* (`tools/index.ts::procTools`). `tools.test.ts::C7` asserts `HOST_TOOL_NAMES`
|
|
7
|
+
* equals what `createBuiltinTools` PRODUCES, so appending these in
|
|
8
|
+
* `AgentController` after the factory returned would turn that test red with a
|
|
9
|
+
* message about two lists of names that says nothing about background services —
|
|
10
|
+
* the trap `teamTools` and `todoTools` each record in capitals.
|
|
11
|
+
*
|
|
12
|
+
* NEITHER JOINS `MUTATING_TOOLS` (P2-5). `bash_output` is a read. `bash_kill`
|
|
13
|
+
* stops something THIS SESSION STARTED and is showing on screen, and the plan
|
|
14
|
+
* gate already refuses it in plan mode; putting a `--confirm` modal between the
|
|
15
|
+
* user and stopping their own runaway server is the wrong trade. `bash` itself
|
|
16
|
+
* stays in `MUTATING_TOOLS` unchanged, including when `background: true` — the
|
|
17
|
+
* command is still arbitrary.
|
|
18
|
+
*/
|
|
19
|
+
import { type AgentTool } from '@aragon-agent/core';
|
|
20
|
+
import type { ProcSupervisorPort } from '../proc/types.js';
|
|
21
|
+
export interface ProcToolDeps {
|
|
22
|
+
supervisor: ProcSupervisorPort;
|
|
23
|
+
}
|
|
24
|
+
export declare function makeBashOutput(deps: ProcToolDeps): AgentTool;
|
|
25
|
+
export declare function makeBashKill(deps: ProcToolDeps): AgentTool;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `bash_output` and `bash_kill` — the model's two handles on a supervised
|
|
3
|
+
* service (background-service-supervision §5.1).
|
|
4
|
+
*
|
|
5
|
+
* REGISTERED THROUGH A FACTORY OPTION, NEVER APPENDED AFTER THE FACT
|
|
6
|
+
* (`tools/index.ts::procTools`). `tools.test.ts::C7` asserts `HOST_TOOL_NAMES`
|
|
7
|
+
* equals what `createBuiltinTools` PRODUCES, so appending these in
|
|
8
|
+
* `AgentController` after the factory returned would turn that test red with a
|
|
9
|
+
* message about two lists of names that says nothing about background services —
|
|
10
|
+
* the trap `teamTools` and `todoTools` each record in capitals.
|
|
11
|
+
*
|
|
12
|
+
* NEITHER JOINS `MUTATING_TOOLS` (P2-5). `bash_output` is a read. `bash_kill`
|
|
13
|
+
* stops something THIS SESSION STARTED and is showing on screen, and the plan
|
|
14
|
+
* gate already refuses it in plan mode; putting a `--confirm` modal between the
|
|
15
|
+
* user and stopping their own runaway server is the wrong trade. `bash` itself
|
|
16
|
+
* stays in `MUTATING_TOOLS` unchanged, including when `background: true` — the
|
|
17
|
+
* command is still arbitrary.
|
|
18
|
+
*/
|
|
19
|
+
import { defineTool, errorResult, textResult } from '@aragon-agent/core';
|
|
20
|
+
import { PROC_LIMITS } from '../proc/limits.js';
|
|
21
|
+
/** One line of status, shared by both tools so the two can never disagree. */
|
|
22
|
+
function statusLine(service) {
|
|
23
|
+
const bits = [`service ${service.id} ${service.status}`];
|
|
24
|
+
if (service.url)
|
|
25
|
+
bits.push(service.url);
|
|
26
|
+
if (service.exitCode !== null)
|
|
27
|
+
bits.push(`exit code ${service.exitCode}`);
|
|
28
|
+
else if (service.signal)
|
|
29
|
+
bits.push(`signal ${service.signal}`);
|
|
30
|
+
if (service.killIncomplete)
|
|
31
|
+
bits.push('(may have left a detached child)');
|
|
32
|
+
return `${bits.join(' ')}\n$ ${service.command}`;
|
|
33
|
+
}
|
|
34
|
+
export function makeBashOutput(deps) {
|
|
35
|
+
return defineTool({
|
|
36
|
+
name: 'bash_output',
|
|
37
|
+
label: 'Service log',
|
|
38
|
+
description: 'Read a background service log tail and its current status. Pass the ' +
|
|
39
|
+
'`since` cursor returned by a previous call to read only what is new. ' +
|
|
40
|
+
'Use this to verify a service actually started, and to read a build or ' +
|
|
41
|
+
'test watcher as it runs.',
|
|
42
|
+
parameters: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
service: { type: 'string', description: 'The service id, e.g. "s1".' },
|
|
46
|
+
since: {
|
|
47
|
+
type: 'number',
|
|
48
|
+
description: 'Cursor from a previous call; omit to read the whole tail.',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
required: ['service'],
|
|
52
|
+
},
|
|
53
|
+
async execute(_id, rawParams) {
|
|
54
|
+
const params = rawParams;
|
|
55
|
+
const service = deps.supervisor.get(params.service);
|
|
56
|
+
if (!service) {
|
|
57
|
+
return errorResult(`No service "${params.service}". Start one with bash({ command, background: true }).`);
|
|
58
|
+
}
|
|
59
|
+
const page = deps.supervisor.read(params.service, params.since);
|
|
60
|
+
const lines = [statusLine(service)];
|
|
61
|
+
if (page?.truncated) {
|
|
62
|
+
lines.push(`[note] older rows were dropped - the tail keeps the last ` +
|
|
63
|
+
`${PROC_LIMITS.serviceTailRows} rows.`);
|
|
64
|
+
}
|
|
65
|
+
if (!page || page.rows.length === 0) {
|
|
66
|
+
lines.push('(no new output)');
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
lines.push(...page.rows);
|
|
70
|
+
}
|
|
71
|
+
lines.push(`[cursor ${page?.cursor ?? service.rowsSeen}]`);
|
|
72
|
+
return textResult(lines.join('\n'));
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export function makeBashKill(deps) {
|
|
77
|
+
return defineTool({
|
|
78
|
+
name: 'bash_kill',
|
|
79
|
+
label: 'Stop service',
|
|
80
|
+
description: 'Stop a background service by id, or every service with "all". Stop the ' +
|
|
81
|
+
'services you started once you are finished with them, unless the user ' +
|
|
82
|
+
'asked for them to stay up.',
|
|
83
|
+
parameters: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: {
|
|
86
|
+
service: { type: 'string', description: 'The service id, or "all".' },
|
|
87
|
+
},
|
|
88
|
+
required: ['service'],
|
|
89
|
+
},
|
|
90
|
+
async execute(_id, rawParams) {
|
|
91
|
+
const params = rawParams;
|
|
92
|
+
if (params.service !== 'all' && !deps.supervisor.get(params.service)) {
|
|
93
|
+
return errorResult(`No service "${params.service}".`);
|
|
94
|
+
}
|
|
95
|
+
const stopped = await deps.supervisor.stop(params.service);
|
|
96
|
+
if (stopped.length === 0)
|
|
97
|
+
return textResult('Nothing to stop.');
|
|
98
|
+
const lines = stopped.map((s) => statusLine(s));
|
|
99
|
+
return textResult(`Stopped ${stopped.length} service${stopped.length === 1 ? '' : 's'}.\n${lines.join('\n')}`);
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
package/dist/ui/App.d.ts
CHANGED
|
@@ -10,7 +10,8 @@ import type { ConfirmRequest } from '../tools/index.js';
|
|
|
10
10
|
import { type Overlay, type ToastLevel } from '../agent/reducer.js';
|
|
11
11
|
import type { UpdateBridge } from '../update/types.js';
|
|
12
12
|
import { type RenderMode } from './layout/frame.js';
|
|
13
|
-
import type { MouseSource } from '../input/stdin-
|
|
13
|
+
import type { MouseSource } from '../input/stdin-filter.js';
|
|
14
|
+
import type { PasteBridge } from '../input/limits.js';
|
|
14
15
|
import type { SelectionBridge } from './selection/selection-controller.js';
|
|
15
16
|
import type { HumanInputBridge } from '../tools/human-input.js';
|
|
16
17
|
export interface ConfirmBridge {
|
|
@@ -73,6 +74,18 @@ export interface AppProps {
|
|
|
73
74
|
* 'off'`, on a non-TTY, in CI, and in every test that does not exercise it.
|
|
74
75
|
*/
|
|
75
76
|
updateBridge?: UpdateBridge;
|
|
77
|
+
/**
|
|
78
|
+
* The stdin filter's channel for a refused paste (tui-paste-handling section
|
|
79
|
+
* 5.1.2 / I-15).
|
|
80
|
+
*
|
|
81
|
+
* A BRIDGE for the reason `updateBridge` above is one: the filter is built in
|
|
82
|
+
* `cli.tsx` BEFORE `render()`, so it has no `dispatch`. Its only other outlet
|
|
83
|
+
* is the logger, and a limit that writes only to a log file is
|
|
84
|
+
* indistinguishable — from the user's chair — from a paste that silently did
|
|
85
|
+
* nothing, which is what D-11 exists to rule out. Absent under `--no-paste`,
|
|
86
|
+
* on a non-TTY, and in every test that does not exercise it.
|
|
87
|
+
*/
|
|
88
|
+
pasteBridge?: PasteBridge;
|
|
76
89
|
/**
|
|
77
90
|
* The terminal-facing services `cli.tsx` owns and this component cannot build
|
|
78
91
|
* (tui-selection-and-scroll-follow §4.4).
|
|
@@ -120,4 +133,4 @@ export interface TerminalBridge {
|
|
|
120
133
|
writeForeign?: (text: string) => void;
|
|
121
134
|
selection?: SelectionBridge;
|
|
122
135
|
}
|
|
123
|
-
export declare function App({ controller, version, mode, initialOverlay, initialPrompt, confirmBridge, humanInputBridge, mouseSource, vtInputWarning, updateBridge, terminal, }: AppProps): React.ReactElement;
|
|
136
|
+
export declare function App({ controller, version, mode, initialOverlay, initialPrompt, confirmBridge, humanInputBridge, mouseSource, vtInputWarning, updateBridge, pasteBridge, terminal, }: AppProps): React.ReactElement;
|