@illuminis/comprism 0.1.2 → 0.1.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 (131) hide show
  1. package/README.md +98 -36
  2. package/out/agent/command.d.ts +75 -4
  3. package/out/agent/command.js +220 -25
  4. package/out/agent/render.d.ts +17 -2
  5. package/out/agent/render.js +157 -14
  6. package/out/agent/session.d.ts +141 -2
  7. package/out/agent/session.js +735 -149
  8. package/out/commands/agents.d.ts +2 -0
  9. package/out/commands/agents.js +79 -0
  10. package/out/commands/ask.d.ts +1 -1
  11. package/out/commands/ask.js +78 -11
  12. package/out/commands/commands-thin.js +79 -17
  13. package/out/commands/config.d.ts +1 -0
  14. package/out/commands/config.js +138 -0
  15. package/out/commands/cost.d.ts +1 -0
  16. package/out/commands/cost.js +167 -0
  17. package/out/commands/hooks.d.ts +1 -0
  18. package/out/commands/hooks.js +83 -0
  19. package/out/commands/install.d.ts +44 -1
  20. package/out/commands/install.js +198 -4
  21. package/out/commands/instructions.d.ts +1 -0
  22. package/out/commands/instructions.js +113 -0
  23. package/out/commands/integrations.d.ts +3 -0
  24. package/out/commands/integrations.js +215 -0
  25. package/out/commands/jobs.d.ts +5 -0
  26. package/out/commands/jobs.js +157 -0
  27. package/out/commands/login.js +188 -36
  28. package/out/commands/memory.d.ts +3 -0
  29. package/out/commands/memory.js +113 -0
  30. package/out/commands/permissions.d.ts +1 -0
  31. package/out/commands/permissions.js +94 -0
  32. package/out/commands/plugins.d.ts +4 -0
  33. package/out/commands/plugins.js +192 -0
  34. package/out/commands/privacy.d.ts +1 -0
  35. package/out/commands/privacy.js +57 -0
  36. package/out/commands/providerKey.d.ts +32 -0
  37. package/out/commands/providerKey.js +108 -0
  38. package/out/commands/repl.d.ts +8 -1
  39. package/out/commands/repl.js +1207 -118
  40. package/out/commands/report.d.ts +39 -0
  41. package/out/commands/report.js +115 -0
  42. package/out/commands/review.d.ts +5 -0
  43. package/out/commands/review.js +223 -0
  44. package/out/commands/sessions.d.ts +23 -0
  45. package/out/commands/sessions.js +115 -0
  46. package/out/commands/settings.d.ts +3 -1
  47. package/out/commands/settings.js +18 -16
  48. package/out/commands/skills.d.ts +21 -0
  49. package/out/commands/skills.js +207 -0
  50. package/out/commands/unattended.d.ts +7 -0
  51. package/out/commands/unattended.js +351 -0
  52. package/out/commands/update.d.ts +1 -0
  53. package/out/commands/update.js +123 -0
  54. package/out/commands/worktrees.d.ts +5 -0
  55. package/out/commands/worktrees.js +186 -0
  56. package/out/executor/browser.d.ts +14 -0
  57. package/out/executor/browser.js +270 -0
  58. package/out/executor/diagnostics.d.ts +2 -0
  59. package/out/executor/diagnostics.js +181 -0
  60. package/out/executor/files.js +270 -40
  61. package/out/executor/git.js +42 -29
  62. package/out/executor/hooks.d.ts +42 -58
  63. package/out/executor/hooks.js +89 -182
  64. package/out/executor/index.d.ts +21 -5
  65. package/out/executor/index.js +160 -14
  66. package/out/executor/paths.d.ts +6 -1
  67. package/out/executor/paths.js +34 -6
  68. package/out/executor/sandbox.d.ts +40 -0
  69. package/out/executor/sandbox.js +299 -0
  70. package/out/executor/shell.d.ts +49 -4
  71. package/out/executor/shell.js +302 -56
  72. package/out/executor/toolservers.d.ts +20 -0
  73. package/out/executor/toolservers.js +189 -0
  74. package/out/executor/worktree.d.ts +9 -0
  75. package/out/executor/worktree.js +119 -0
  76. package/out/graph/read-python.js +2 -1
  77. package/out/lib/attach.d.ts +56 -12
  78. package/out/lib/attach.js +230 -63
  79. package/out/lib/clipboard.d.ts +23 -0
  80. package/out/lib/clipboard.js +182 -0
  81. package/out/lib/commandlist.d.ts +20 -0
  82. package/out/lib/commandlist.js +58 -0
  83. package/out/lib/decision.d.ts +22 -0
  84. package/out/lib/decision.js +50 -0
  85. package/out/lib/fingerprint.d.ts +25 -0
  86. package/out/lib/fingerprint.js +58 -0
  87. package/out/lib/gateway.d.ts +186 -2
  88. package/out/lib/gateway.js +59 -4
  89. package/out/lib/history.d.ts +24 -0
  90. package/out/lib/history.js +137 -0
  91. package/out/lib/ide.d.ts +19 -0
  92. package/out/lib/ide.js +131 -0
  93. package/out/lib/keyboard.d.ts +95 -0
  94. package/out/lib/keyboard.js +383 -0
  95. package/out/lib/machine.d.ts +21 -0
  96. package/out/lib/machine.js +91 -0
  97. package/out/lib/notify.d.ts +4 -0
  98. package/out/lib/notify.js +52 -0
  99. package/out/lib/output.d.ts +48 -0
  100. package/out/lib/output.js +108 -0
  101. package/out/lib/project-ops.d.ts +19 -0
  102. package/out/lib/project-ops.js +146 -0
  103. package/out/lib/project.d.ts +28 -0
  104. package/out/lib/project.js +114 -0
  105. package/out/lib/prompt.js +15 -2
  106. package/out/lib/queue.d.ts +13 -0
  107. package/out/lib/queue.js +116 -0
  108. package/out/lib/readiness.d.ts +19 -0
  109. package/out/lib/readiness.js +170 -1
  110. package/out/lib/self.d.ts +23 -0
  111. package/out/lib/self.js +124 -0
  112. package/out/lib/sessions.d.ts +19 -0
  113. package/out/lib/sessions.js +221 -0
  114. package/out/lib/stdin.d.ts +32 -0
  115. package/out/lib/stdin.js +117 -0
  116. package/out/lib/store.d.ts +40 -0
  117. package/out/lib/store.js +138 -0
  118. package/out/lib/sync.d.ts +18 -0
  119. package/out/lib/sync.js +81 -0
  120. package/out/lib/ui.d.ts +2 -4
  121. package/out/lib/ui.js +31 -25
  122. package/out/lib/voice.js +24 -0
  123. package/out/postinstall.js +42 -14
  124. package/out/providers/anthropic.d.ts +22 -0
  125. package/out/providers/anthropic.js +80 -0
  126. package/out/providers/index.d.ts +8 -0
  127. package/out/providers/index.js +83 -0
  128. package/out/providers/openai.d.ts +11 -0
  129. package/out/providers/openai.js +57 -0
  130. package/out/thin.js +609 -21
  131. package/package.json +9 -49
@@ -0,0 +1,299 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Sandbox = void 0;
37
+ exports.availability = availability;
38
+ exports.hostAllowed = hostAllowed;
39
+ /**
40
+ * Commands run inside the operating system's sandbox (manual 4.12).
41
+ *
42
+ * The service decides whether a job is sandboxed and which internet addresses
43
+ * are allowed; this file only adapts the facility the operating system
44
+ * provides, which the service cannot reach:
45
+ *
46
+ * - macOS: `sandbox-exec` with a generated profile. Writes are allowed only in
47
+ * the project, the added folders and the temporary folders. The network is
48
+ * closed except to this machine, where a small gatekeeper answers as the
49
+ * command's web proxy and lets through only the allowed addresses.
50
+ * - Linux: bubblewrap (`bwrap`). The whole machine is mounted read only except
51
+ * the project, the added folders and the temporary folder, and the command
52
+ * gets a network of its own with nothing on it. A small relay inside that
53
+ * network passes web traffic to the same gatekeeper, through a socket file,
54
+ * so only the allowed addresses are reached there too.
55
+ *
56
+ * Anywhere else `--sandbox` refuses to start rather than running without it.
57
+ * A blocked attempt is reported as blocked by the sandbox, which is different
58
+ * from refused by the person or by a rule.
59
+ */
60
+ const child_process_1 = require("child_process");
61
+ const fs = __importStar(require("fs"));
62
+ const http = __importStar(require("http"));
63
+ const net = __importStar(require("net"));
64
+ const os = __importStar(require("os"));
65
+ const self_1 = require("../lib/self");
66
+ /** Which sandbox this machine offers, or why none. */
67
+ function availability() {
68
+ const has = (file, args) => {
69
+ try {
70
+ (0, child_process_1.execFileSync)(file, args, { stdio: "ignore", timeout: 5000 });
71
+ return true;
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ };
77
+ if (process.platform === "darwin") {
78
+ return fs.existsSync("/usr/bin/sandbox-exec")
79
+ ? { system: "macOS", why: "" }
80
+ : { system: null, why: "the macOS sandbox (sandbox-exec) is not on this machine" };
81
+ }
82
+ if (process.platform === "linux") {
83
+ if (!has("bwrap", ["--version"])) {
84
+ return { system: null, why: "bubblewrap (bwrap) is not installed; install it to use --sandbox" };
85
+ }
86
+ // A working sandbox, not merely an installed one: some systems forbid the
87
+ // namespaces bubblewrap needs.
88
+ return has("bwrap", ["--ro-bind", "/", "/", "--unshare-net", "true"])
89
+ ? { system: "Linux", why: "" }
90
+ : { system: null, why: "bubblewrap is installed but this system does not let it start" };
91
+ }
92
+ return { system: null, why: `there is no supported sandbox on ${process.platform}` };
93
+ }
94
+ function real(p) {
95
+ try {
96
+ return fs.realpathSync(p);
97
+ }
98
+ catch {
99
+ return p;
100
+ }
101
+ }
102
+ function quote(p) {
103
+ return `"${p.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
104
+ }
105
+ /** Does this host match an allowed address: exact, or `*.example.com`. */
106
+ function hostAllowed(host, allow) {
107
+ const h = host.toLowerCase().replace(/\.$/, "");
108
+ return allow.some((raw) => {
109
+ const a = raw.toLowerCase().trim();
110
+ if (!a)
111
+ return false;
112
+ if (a === "*")
113
+ return true;
114
+ if (a.startsWith("*."))
115
+ return h.endsWith(a.slice(1)) || h === a.slice(2);
116
+ return h === a;
117
+ });
118
+ }
119
+ /** The port the relay listens on inside a Linux sandbox's own network. Any
120
+ * port would do: that network holds nothing else. */
121
+ const LINUX_RELAY_PORT = 18080;
122
+ /** The relay, run by the same Node inside the sandbox: every connection to
123
+ * its port is passed to the gatekeeper's socket file, and it marks itself
124
+ * ready once listening. It decides nothing. */
125
+ const RELAY = [
126
+ 'const net=require("net"),fs=require("fs");',
127
+ "net.createServer((c)=>{const u=net.connect(process.env.COMPRISM_GATE);",
128
+ 'c.pipe(u);u.pipe(c);u.on("error",()=>c.destroy());c.on("error",()=>u.destroy());})',
129
+ `.listen(${LINUX_RELAY_PORT},"127.0.0.1",()=>fs.writeFileSync(process.env.COMPRISM_READY,""));`,
130
+ ].join("");
131
+ class Sandbox {
132
+ system;
133
+ writable;
134
+ allow = [];
135
+ proxy = null;
136
+ port = 0;
137
+ /** Hosts refused since the last `takeBlocked`, for the result to name. */
138
+ blocked = [];
139
+ constructor(system, root, added) {
140
+ this.system = system;
141
+ // This user's own temporary folder and the system one, and no wider: the
142
+ // parent of a user's temporary folder holds other programs' caches.
143
+ const tmp = [os.tmpdir(), "/tmp", "/var/tmp"];
144
+ this.writable = [...new Set([root, ...added, ...tmp].map(real))];
145
+ }
146
+ /** The allowed internet addresses, as the service sent them. */
147
+ setAllowed(allow) {
148
+ this.allow = allow.filter((a) => typeof a === "string" && a.trim());
149
+ }
150
+ /** Where the gatekeeper listens on Linux: a socket file the relay inside
151
+ * the sandbox connects to, and a folder for the relay's ready marks. */
152
+ socketPath = "";
153
+ marks = "";
154
+ calls = 0;
155
+ /** Start the gatekeeper. Idempotent. */
156
+ async start() {
157
+ if (this.proxy)
158
+ return;
159
+ const server = http.createServer((req, res) => {
160
+ // A plain http:// request through the proxy.
161
+ let target;
162
+ try {
163
+ target = new URL(req.url ?? "");
164
+ }
165
+ catch {
166
+ res.writeHead(400);
167
+ res.end();
168
+ return;
169
+ }
170
+ if (!hostAllowed(target.hostname, this.allow)) {
171
+ this.blocked.push(target.hostname);
172
+ res.writeHead(403, { "content-type": "text/plain" });
173
+ res.end(`blocked by the sandbox: network access to ${target.hostname} is not allowed\n`);
174
+ return;
175
+ }
176
+ const upstream = http.request(target, { method: req.method, headers: req.headers }, (up) => {
177
+ res.writeHead(up.statusCode ?? 502, up.headers);
178
+ up.pipe(res);
179
+ });
180
+ upstream.on("error", () => { res.writeHead(502); res.end(); });
181
+ req.pipe(upstream);
182
+ });
183
+ server.on("connect", (req, client, head) => {
184
+ // https:// and anything else tunnelled with CONNECT host:port.
185
+ const [host, portText] = String(req.url ?? "").split(":");
186
+ if (!host || !hostAllowed(host, this.allow)) {
187
+ if (host)
188
+ this.blocked.push(host);
189
+ client.end("HTTP/1.1 403 Forbidden\r\n\r\n");
190
+ return;
191
+ }
192
+ const upstream = net.connect(Number(portText) || 443, host, () => {
193
+ client.write("HTTP/1.1 200 Connection Established\r\n\r\n");
194
+ if (head.length)
195
+ upstream.write(head);
196
+ upstream.pipe(client);
197
+ client.pipe(upstream);
198
+ });
199
+ upstream.on("error", () => client.destroy());
200
+ client.on("error", () => upstream.destroy());
201
+ });
202
+ if (this.system === "Linux") {
203
+ // A socket file in the temporary folder, which the sandbox can see.
204
+ this.marks = fs.mkdtempSync(`${real(os.tmpdir())}/comprism-gate-`);
205
+ this.socketPath = `${this.marks}/gate.sock`;
206
+ await new Promise((resolve) => server.listen(this.socketPath, () => resolve()));
207
+ }
208
+ else {
209
+ await new Promise((resolve) => server.listen(0, "127.0.0.1", () => resolve()));
210
+ this.port = server.address().port;
211
+ }
212
+ this.proxy = server;
213
+ server.unref();
214
+ }
215
+ close() {
216
+ this.proxy?.close();
217
+ this.proxy = null;
218
+ if (this.marks)
219
+ fs.rmSync(this.marks, { recursive: true, force: true });
220
+ this.marks = "";
221
+ }
222
+ /** The hosts refused since the last call. */
223
+ takeBlocked() {
224
+ const out = [...new Set(this.blocked)];
225
+ this.blocked = [];
226
+ return out;
227
+ }
228
+ profile() {
229
+ const writes = this.writable.map((p) => ` (subpath ${quote(p)})`).join("\n");
230
+ return [
231
+ "(version 1)",
232
+ "(allow default)",
233
+ "(deny file-write*)",
234
+ "(allow file-write*",
235
+ writes,
236
+ ' (literal "/dev/null") (literal "/dev/zero") (literal "/dev/stdout")',
237
+ ' (literal "/dev/stderr") (literal "/dev/dtracehelper")',
238
+ ' (regex #"^/dev/tty") (regex #"^/dev/fd/"))',
239
+ "(deny network*)",
240
+ '(allow network* (remote ip "localhost:*"))',
241
+ '(allow network* (local ip "localhost:*"))',
242
+ ].join("\n");
243
+ }
244
+ /** The program and arguments that run `command` inside the sandbox, and
245
+ * the variables that send its web traffic to the gatekeeper. */
246
+ wrap(command, cwd) {
247
+ if (this.system === "macOS") {
248
+ const proxy = `http://127.0.0.1:${this.port}`;
249
+ return {
250
+ file: "/usr/bin/sandbox-exec",
251
+ args: ["-p", this.profile(), "/bin/sh", "-c", command],
252
+ env: {
253
+ HTTP_PROXY: proxy, HTTPS_PROXY: proxy, http_proxy: proxy, https_proxy: proxy,
254
+ ALL_PROXY: proxy, all_proxy: proxy, NO_PROXY: "", no_proxy: "",
255
+ },
256
+ };
257
+ }
258
+ const binds = this.writable.filter((p) => fs.existsSync(p)).flatMap((p) => ["--bind", p, p]);
259
+ // Inside the sandbox's own network, a relay on this port passes every
260
+ // connection to the gatekeeper's socket file, which decides.
261
+ const proxy = `http://127.0.0.1:${LINUX_RELAY_PORT}`;
262
+ const ready = this.marks ? `${this.marks}/ready-${++this.calls}` : "";
263
+ const script = this.socketPath
264
+ ? `${(0, self_1.isStandalone)() ? '"$COMPRISM_NODE" __relay' : '"$COMPRISM_NODE" -e "$COMPRISM_RELAY"'} & relay=$!; i=0; `
265
+ + `while [ ! -e "$COMPRISM_READY" ] && [ $i -lt 150 ]; do sleep 0.02; i=$((i+1)); done; `
266
+ + `/bin/sh -c "$COMPRISM_CMD"; rc=$?; kill $relay 2>/dev/null; exit $rc`
267
+ : `/bin/sh -c "$COMPRISM_CMD"`;
268
+ return {
269
+ file: "bwrap",
270
+ args: ["--ro-bind", "/", "/", "--dev", "/dev", "--proc", "/proc", ...binds,
271
+ "--unshare-net", "--die-with-parent", "--chdir", cwd, "/bin/sh", "-c", script],
272
+ env: {
273
+ COMPRISM_CMD: command, COMPRISM_NODE: process.execPath, COMPRISM_RELAY: RELAY,
274
+ COMPRISM_GATE: this.socketPath, COMPRISM_READY: ready,
275
+ ...(this.socketPath ? {
276
+ HTTP_PROXY: proxy, HTTPS_PROXY: proxy, http_proxy: proxy, https_proxy: proxy,
277
+ ALL_PROXY: proxy, all_proxy: proxy, NO_PROXY: "", no_proxy: "",
278
+ } : {}),
279
+ },
280
+ };
281
+ }
282
+ /** What was blocked, in the manual's words, or null (manual 4.12). */
283
+ explain(output, hosts) {
284
+ if (hosts.length)
285
+ return `blocked by the sandbox: network access to ${hosts.join(", ")} is not allowed`;
286
+ const write = /(?:touch: |cannot touch )?'?([^'\n:]+?)'?: (?:Operation not permitted|Read-only file system)/.exec(output);
287
+ if (write) {
288
+ return `blocked by the sandbox: writing to ${write[1].trim()} is not allowed, `
289
+ + "only the project and temporary folders can be written";
290
+ }
291
+ const offline = /Could not resolve host: (\S+)|getaddrinfo \w+ (\S+)|Network is unreachable/.exec(output);
292
+ if (offline) {
293
+ const host = offline[1] ?? offline[2] ?? "the internet";
294
+ return `blocked by the sandbox: network access to ${host} is not allowed`;
295
+ }
296
+ return null;
297
+ }
298
+ }
299
+ exports.Sandbox = Sandbox;
@@ -2,8 +2,18 @@ export interface RunResult {
2
2
  content: string;
3
3
  isError?: boolean;
4
4
  summary?: string;
5
+ /** Counts the service turns into the action line: the lines read, the
6
+ * matches found and how many were left out (manual 5.3, 5.4). Numbers only;
7
+ * the wording is the service's. */
8
+ facts?: Record<string, number | string>;
5
9
  }
6
10
  export declare function safeEnvironment(from?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
11
+ /** The default time limit on a command (manual 5.12). */
12
+ export declare const DEFAULT_TIMEOUT_MS = 120000;
13
+ export declare function keptOutput(n: number): {
14
+ command: string;
15
+ text: string;
16
+ } | undefined;
7
17
  export interface ShellOptions {
8
18
  root: string;
9
19
  cwd?: string;
@@ -16,6 +26,14 @@ export interface ShellOptions {
16
26
  * Still filtered by `safeEnvironment`, so a hook cannot be handed a
17
27
  * credential this way either. */
18
28
  extraEnv?: Record<string, string>;
29
+ /** What the command is called in `output N`. */
30
+ label?: string;
31
+ /** Written to the command's standard input, then closed. Hooks read their
32
+ * details this way (manual 10.9). Absent, standard input is closed. */
33
+ input?: string;
34
+ /** The operating system's sandbox, when the service turned it on for this
35
+ * job (manual 4.12). Every command then runs inside it. */
36
+ sandbox?: import("./sandbox").Sandbox;
19
37
  }
20
38
  /** Run a command and wait for it.
21
39
  *
@@ -23,14 +41,41 @@ export interface ShellOptions {
23
41
  * RESULT: it is usually the most useful thing that can happen, because it is
24
42
  * how the agent learns what is wrong.
25
43
  */
44
+ /**
45
+ * The shell a command runs in: the system shell on macOS and Linux, and
46
+ * PowerShell on Windows (manual 1.2), which is what a Windows developer types
47
+ * into and what the agent is told it is writing for.
48
+ */
49
+ export declare function shellFor(command: string): [string, string[], boolean];
26
50
  export declare function runCommand(command: string, opts: ShellOptions): Promise<RunResult>;
51
+ /** Run one program with its arguments as a list, and no shell in between.
52
+ *
53
+ * For commands this tool builds itself, such as git. A shell would have to be
54
+ * told how to quote each argument, and the quoting differs by shell: the POSIX
55
+ * single quotes that kept a commit message whole on macOS and Linux reached
56
+ * git on Windows as literal characters, so a commit read `'fix` and a branch
57
+ * name no longer matched. With no shell there is nothing to quote, on any
58
+ * system, and a model written message cannot become a second command. */
59
+ export declare function runProgram(file: string, args: string[], opts: ShellOptions): Promise<RunResult>;
60
+ /** Stop every foreground command and everything it started. */
61
+ export declare function stopForeground(): void;
27
62
  export declare function startBackground(command: string, opts: ShellOptions): RunResult;
28
63
  export declare function readOutput(id: string): RunResult;
64
+ /** Stop one process this tool started, and everything it started, by the
65
+ * number it was given. Never by name or by port (manual 5.13). */
29
66
  export declare function stopProcess(id: string): RunResult;
30
- /** Everything still running, stopped. Called when a session ends, so a job that
31
- * started a dev server does not leave it holding a port after the person has
32
- * closed the terminal. */
33
- export declare function stopEverything(): void;
67
+ /** What this session started and is still tracking, for `processes`. */
68
+ export declare function listProcesses(): Array<{
69
+ id: string;
70
+ command: string;
71
+ running: boolean;
72
+ seconds: number;
73
+ port?: number;
74
+ }>;
75
+ /** Everything still running, stopped, and what was stopped. Called when a
76
+ * session ends, so a job that started a dev server does not leave it holding
77
+ * a port after the person has closed the terminal (manual 5.13). */
78
+ export declare function stopEverything(): string[];
34
79
  export declare function guessTestCommand(root: string): string | null;
35
80
  export declare function runTests(opts: ShellOptions & {
36
81
  command?: string;