@mu-crew/mu 3.1.0 → 3.2.1
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/AGENTS.md +203 -588
- package/README.md +80 -308
- package/dist/cli.js +6106 -4716
- package/dist/cli.js.map +1 -1
- package/dist/extension/mu-pi.js +786 -0
- package/dist/extension/mu-pi.js.map +1 -0
- package/dist/index.d.ts +738 -536
- package/dist/index.js +6617 -5785
- package/dist/index.js.map +1 -1
- package/docs/ARCHITECTURE.md +178 -1008
- package/docs/ROADMAP.md +88 -169
- package/docs/VISION.md +206 -407
- package/docs/VOCABULARY.md +202 -455
- package/docs/architecture/control-socket.md +119 -0
- package/docs/architecture/dag.md +113 -0
- package/docs/architecture/mux.md +163 -0
- package/docs/architecture/ops-log.md +140 -0
- package/docs/architecture/sdk.md +185 -0
- package/docs/architecture/sync.md +129 -0
- package/docs/architecture/tui.md +146 -0
- package/docs/guide/README.md +25 -0
- package/docs/guide/backends.md +61 -0
- package/docs/guide/cleanup.md +74 -0
- package/docs/guide/delegate.md +87 -0
- package/docs/guide/dispatch.md +137 -0
- package/docs/guide/getting-started.md +177 -0
- package/docs/guide/recovery.md +133 -0
- package/docs/guide/remote.md +74 -0
- package/docs/guide/sql.md +76 -0
- package/docs/guide/stop-a-worker.md +64 -0
- package/docs/guide/sync.md +78 -0
- package/docs/guide/tui.md +98 -0
- package/docs/guide/upgrade.md +76 -0
- package/docs/history/CHANGELOG-pre-3.md +4866 -0
- package/docs/reference/env.md +87 -0
- package/docs/reference/naming.md +82 -0
- package/docs/specs/2026-09-28-agent-state-from-murmur.md +1 -1
- package/docs/specs/2026-09-29-task-substates.md +1 -1
- package/package.json +4 -4
- package/skills/mu/REMOTE_WORKERS.md +186 -491
- package/skills/mu/SKILL.md +142 -217
- package/docs/HANDOVER.md +0 -486
- package/docs/USAGE_GUIDE.md +0 -2637
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
import { Database } from 'better-sqlite3';
|
|
2
2
|
|
|
3
|
+
type CtlState = "busy" | "idle" | "needs_input";
|
|
4
|
+
|
|
3
5
|
type RuntimeState = "busy" | "needs_input" | "needs_permission" | "unknown";
|
|
4
|
-
type StateSource = "murmur" | "herdr" | "none";
|
|
6
|
+
type StateSource = "murmur" | "herdr" | "ctl" | "none";
|
|
7
|
+
/** How a pi agent's control socket answered; "n/a" for non-pi agents. */
|
|
8
|
+
type CtlLink = "ok" | "missing" | "refused" | "n/a";
|
|
5
9
|
interface StateReading {
|
|
6
10
|
state: RuntimeState;
|
|
7
11
|
source: StateSource;
|
|
8
12
|
since: number | null;
|
|
9
13
|
alive: boolean;
|
|
10
14
|
reason?: string;
|
|
15
|
+
/** Set for agents that expect a control socket. */
|
|
16
|
+
ctl?: Exclude<CtlLink, "n/a">;
|
|
11
17
|
}
|
|
12
18
|
interface StateAgentRef {
|
|
13
19
|
name: string;
|
|
14
20
|
workstreamName: string;
|
|
15
21
|
paneId: string;
|
|
22
|
+
/** When set and it names pi, the control socket is the state source. */
|
|
23
|
+
cli?: string;
|
|
16
24
|
}
|
|
25
|
+
/** ctl's idle maps to needs_input, the same as murmur's idle. */
|
|
26
|
+
declare function ctlRuntimeState(state: CtlState): RuntimeState;
|
|
17
27
|
declare const UNKNOWN_REASON: {
|
|
18
28
|
readonly murmurMissing: "murmur not installed";
|
|
19
29
|
readonly extensionMissing: "murmur pi extension not linked";
|
|
@@ -21,14 +31,24 @@ declare const UNKNOWN_REASON: {
|
|
|
21
31
|
readonly stale: "remote snapshot stale";
|
|
22
32
|
readonly herdrNone: "herdr reports no state";
|
|
23
33
|
readonly paneGone: "pane gone";
|
|
34
|
+
readonly ctlMissing: "ctl missing";
|
|
35
|
+
readonly ctlRefused: "ctl refused";
|
|
24
36
|
};
|
|
25
37
|
declare function agentKey(a: {
|
|
26
38
|
name: string;
|
|
27
39
|
workstreamName: string;
|
|
28
40
|
}): string;
|
|
29
41
|
declare function murmurAvailable(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Read the runtime state of each agent. Order per agent: control socket
|
|
44
|
+
* (pi agents) → murmur pane option → murmur remote → herdr. A pi agent
|
|
45
|
+
* whose socket does not answer reads `unknown` with reason `ctl missing`
|
|
46
|
+
* or `ctl refused`, never a murmur reading, so the gap stays visible.
|
|
47
|
+
* `stateDir` roots the derived socket path (spawn uses the DB's directory).
|
|
48
|
+
*/
|
|
30
49
|
declare function readAgentStates(agents: readonly StateAgentRef[], opts?: {
|
|
31
50
|
now?: number;
|
|
51
|
+
stateDir?: string;
|
|
32
52
|
}): Promise<Map<string, StateReading>>;
|
|
33
53
|
|
|
34
54
|
/**
|
|
@@ -1101,429 +1121,96 @@ interface ReconcileReport {
|
|
|
1101
1121
|
}
|
|
1102
1122
|
declare function reconcile(db: Db, opts: ReconcileOptions): Promise<ReconcileReport>;
|
|
1103
1123
|
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
paneId: string;
|
|
1107
|
-
/** Workstream to adopt the pane into. The pane MUST be in the
|
|
1108
|
-
* matching tmux session (`mu-<workstream>`); cross-session adopt is
|
|
1109
|
-
* rejected. */
|
|
1124
|
+
type AbortResult = {
|
|
1125
|
+
agent: string;
|
|
1110
1126
|
workstream: string;
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1127
|
+
before: CtlState;
|
|
1128
|
+
after: CtlState;
|
|
1129
|
+
/** True when pi settled (or was never busy). */
|
|
1130
|
+
settled: boolean;
|
|
1131
|
+
/** False when the agent was not busy, so no abort was sent. */
|
|
1132
|
+
aborted: boolean;
|
|
1133
|
+
elapsedMs: number;
|
|
1134
|
+
};
|
|
1135
|
+
type AbortAgentOptions = {
|
|
1136
|
+
workstream: string;
|
|
1137
|
+
timeoutMs?: number;
|
|
1138
|
+
/** Control socket path. Default: derived from the agent's identity. */
|
|
1139
|
+
socket?: string;
|
|
1140
|
+
};
|
|
1141
|
+
declare function abortAgent(db: Db, name: string, opts: AbortAgentOptions): Promise<AbortResult>;
|
|
1142
|
+
|
|
1143
|
+
type VcsBackendName = "jj" | "sl" | "git" | "none";
|
|
1144
|
+
interface RebaseResult {
|
|
1145
|
+
/** The ref the workspace was actually rebased onto (resolved
|
|
1146
|
+
* symbolic-or-revset → concrete name). For git that is the
|
|
1147
|
+
* resolveGitMainRef() symbolic ref; for jj/sl it's the literal
|
|
1148
|
+
* `trunk()` revset (or whatever the operator passed via fromRef). */
|
|
1149
|
+
fromRef: string;
|
|
1150
|
+
/** Commit subjects (or descriptions) that got replayed, oldest-first.
|
|
1151
|
+
* Empty when the workspace was already at fromRef (no-op). */
|
|
1152
|
+
replayed: string[];
|
|
1153
|
+
/** Files / commits that conflicted during the rebase. Always
|
|
1154
|
+
* empty for a successful rebase — a non-empty conflicts list
|
|
1155
|
+
* means we threw WorkspaceConflictError before returning. The
|
|
1156
|
+
* field exists so the error's serialised payload can carry it. */
|
|
1157
|
+
conflicts: string[];
|
|
1120
1158
|
}
|
|
1121
|
-
interface
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
/**
|
|
1127
|
-
|
|
1128
|
-
/**
|
|
1129
|
-
|
|
1130
|
-
|
|
1159
|
+
interface CommitSummary {
|
|
1160
|
+
/** Full commit / change id. */
|
|
1161
|
+
sha: string;
|
|
1162
|
+
/** First-line description / subject. */
|
|
1163
|
+
subject: string;
|
|
1164
|
+
/** Remainder of the commit message (may be empty). */
|
|
1165
|
+
body: string;
|
|
1166
|
+
/** Author display name, when the backend exposes one. */
|
|
1167
|
+
author: string;
|
|
1168
|
+
/** ISO-8601 author / commit timestamp. */
|
|
1169
|
+
authorDate: string;
|
|
1170
|
+
/** Compact relative author time (e.g. "3m", "2d"). */
|
|
1171
|
+
relTime: string;
|
|
1131
1172
|
}
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
* - When `name` is omitted, the pane's existing title becomes the
|
|
1140
|
-
* agent name verbatim. Adopting a pane titled 'pi' would fail name
|
|
1141
|
-
* validation — caller must supply --name in that case.
|
|
1142
|
-
*
|
|
1143
|
-
* Idempotent: adopting the same pane twice with the same name is a
|
|
1144
|
-
* no-op (returns alreadyAdopted=true). Adopting a different pane under
|
|
1145
|
-
* an existing agent name throws AgentExistsError.
|
|
1146
|
-
*
|
|
1147
|
-
* Validation order (matches the design in note #100):
|
|
1148
|
-
* 1. Pane id format -> assertValidPaneId via paneExists / setPaneTitle
|
|
1149
|
-
* 2. Pane exists -> PaneNotFoundError
|
|
1150
|
-
* 3. Pane is in session -> AgentNotInWorkstreamError (cross-session)
|
|
1151
|
-
* 4. Resolved name OK -> isValidAgentName / Error('agent name invalid')
|
|
1152
|
-
* 5. Idempotent check -> if pane already owned by an agent of this
|
|
1153
|
-
* name, return alreadyAdopted=true
|
|
1154
|
-
* 6. Name not taken -> AgentExistsError (else)
|
|
1155
|
-
* 7. Insert + retitle.
|
|
1156
|
-
*
|
|
1157
|
-
* Status starts at 'free' — reconcile/detect will update it on the next
|
|
1158
|
-
* `mu agent list` based on actual pane content (the pi prompt yields
|
|
1159
|
-
* 'free'; an agent mid-thought yields 'busy'; etc.). We don't run
|
|
1160
|
-
* detection inline here because the caller may not have $TMUX, and
|
|
1161
|
-
* adoption shouldn't depend on a captured-pane probe succeeding.
|
|
1162
|
-
*/
|
|
1163
|
-
declare function adoptAgent(db: Db, opts: AdoptAgentOptions): Promise<AdoptAgentResult>;
|
|
1164
|
-
|
|
1165
|
-
/**
|
|
1166
|
-
* Pre-flight failure: the command mu would have spawned in the new
|
|
1167
|
-
* pane doesn't resolve to a binary on PATH (and isn't an absolute /
|
|
1168
|
-
* relative path that exists + is executable). Thrown by `spawnAgent`
|
|
1169
|
-
* BEFORE `prestageWorkspace` so a typo in `--cli` never leaves an
|
|
1170
|
-
* orphan workspace dir behind.
|
|
1171
|
-
*
|
|
1172
|
-
* Source: feedback ws task `fb_agent_spawn_no_validation`. Live
|
|
1173
|
-
* dogfood report: `mu agent spawn worker-1 --cli pi-meta` on a host
|
|
1174
|
-
* where the `pi-meta` binary wasn't on PATH printed `Spawned worker-1
|
|
1175
|
-
* (pi-meta)` and the pane immediately died with `command not found`;
|
|
1176
|
-
* the existing 1.5s liveness check sometimes missed it (the shell
|
|
1177
|
-
* stays alive after the failed exec). Pre-flighting the PATH lookup
|
|
1178
|
-
* surfaces the typo before any side effects (workspace, pane, DB row).
|
|
1179
|
-
*
|
|
1180
|
-
* Distinct from `AgentSpawnStartupError` (pane alive but parked at an
|
|
1181
|
-
* error prompt) and `AgentDiedOnSpawnError` (pane vanished within the
|
|
1182
|
-
* liveness window). All three carry different remediation hints, so
|
|
1183
|
-
* they're separate types.
|
|
1184
|
-
*/
|
|
1185
|
-
declare class AgentSpawnCliNotFoundError extends Error implements HasNextSteps {
|
|
1186
|
-
readonly cli: string;
|
|
1187
|
-
/** First whitespace-separated token of the resolved command — the
|
|
1188
|
-
* thing actually missing on PATH. Surfaced verbatim in the
|
|
1189
|
-
* message so the operator sees what mu searched for (which may
|
|
1190
|
-
* differ from `cli` when `$MU_<UPPER_CLI>_COMMAND` rewrites it). */
|
|
1191
|
-
readonly binary: string;
|
|
1192
|
-
/** Name of the env var that mu consulted before falling back to
|
|
1193
|
-
* the bare `cli` value (e.g. `MU_PI_META_COMMAND`). Always set
|
|
1194
|
-
* to the conventional name so the nextSteps hint can recommend
|
|
1195
|
-
* exporting it. */
|
|
1196
|
-
readonly envVarChecked: string;
|
|
1197
|
-
readonly name = "AgentSpawnCliNotFoundError";
|
|
1198
|
-
constructor(cli: string,
|
|
1199
|
-
/** First whitespace-separated token of the resolved command — the
|
|
1200
|
-
* thing actually missing on PATH. Surfaced verbatim in the
|
|
1201
|
-
* message so the operator sees what mu searched for (which may
|
|
1202
|
-
* differ from `cli` when `$MU_<UPPER_CLI>_COMMAND` rewrites it). */
|
|
1203
|
-
binary: string,
|
|
1204
|
-
/** Name of the env var that mu consulted before falling back to
|
|
1205
|
-
* the bare `cli` value (e.g. `MU_PI_META_COMMAND`). Always set
|
|
1206
|
-
* to the conventional name so the nextSteps hint can recommend
|
|
1207
|
-
* exporting it. */
|
|
1208
|
-
envVarChecked: string);
|
|
1209
|
-
errorNextSteps(): NextStep[];
|
|
1173
|
+
interface ShowCommitResult {
|
|
1174
|
+
/** Captured VCS show output (possibly truncated). Empty string on error. */
|
|
1175
|
+
text: string;
|
|
1176
|
+
/** True when stdout exceeded SHOW_COMMIT_MAX_CHARS and was clipped. */
|
|
1177
|
+
truncated: boolean;
|
|
1178
|
+
/** Human-readable error message; omitted on success. */
|
|
1179
|
+
error?: string;
|
|
1210
1180
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1181
|
+
interface CreateWorkspaceOptions$1 {
|
|
1182
|
+
/** The repository being branched from. Absolute path. */
|
|
1183
|
+
projectRoot: string;
|
|
1184
|
+
/** Where to place the new workspace. Absolute path; must NOT exist. */
|
|
1185
|
+
workspacePath: string;
|
|
1186
|
+
/** Optional commit / branch / changeset id to base off. Backend-specific:
|
|
1187
|
+
* git uses it as a `git worktree add`'s ref, jj as a revset, sl as a
|
|
1188
|
+
* rev. Undefined = current head. */
|
|
1189
|
+
parentRef?: string;
|
|
1216
1190
|
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
*
|
|
1221
|
-
* (e.g. `
|
|
1222
|
-
|
|
1223
|
-
* call sites that only know the agent name keep their original
|
|
1224
|
-
* one-line message. */
|
|
1225
|
-
readonly workstream?: string | undefined;
|
|
1226
|
-
readonly name = "AgentNotFoundError";
|
|
1227
|
-
constructor(agentName: string,
|
|
1228
|
-
/** Optional workstream context. When set, the message is enriched
|
|
1229
|
-
* with `(in workstream <ws>)` so the verb that hit the miss
|
|
1230
|
-
* (e.g. `mu workspace path <agent> -w <ws>`) doesn't leave the
|
|
1231
|
-
* operator guessing which scope was searched. Optional so existing
|
|
1232
|
-
* call sites that only know the agent name keep their original
|
|
1233
|
-
* one-line message. */
|
|
1234
|
-
workstream?: string | undefined);
|
|
1235
|
-
errorNextSteps(): NextStep[];
|
|
1191
|
+
interface CreateWorkspaceResult {
|
|
1192
|
+
/** The actual ref the workspace points at (resolved to a stable id
|
|
1193
|
+
* when possible). Stored on the row; useful for `mu workspace list`
|
|
1194
|
+
* and for `--commit` flows. May be null for backends that don't
|
|
1195
|
+
* expose a meaningful parent (e.g. `none`). */
|
|
1196
|
+
parentRef: string | null;
|
|
1236
1197
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
*/
|
|
1245
|
-
|
|
1246
|
-
readonly agentName: string;
|
|
1247
|
-
readonly expectedWorkstream: string;
|
|
1248
|
-
readonly actualWorkstream: string;
|
|
1249
|
-
readonly name = "AgentNotInWorkstreamError";
|
|
1250
|
-
constructor(agentName: string, expectedWorkstream: string, actualWorkstream: string);
|
|
1251
|
-
errorNextSteps(): NextStep[];
|
|
1198
|
+
interface FreeWorkspaceOptions$1 {
|
|
1199
|
+
workspacePath: string;
|
|
1200
|
+
/** If true, attempt to commit any pending changes BEFORE removal.
|
|
1201
|
+
* Backend-specific: jj auto-commits via `jj describe + jj new`, git
|
|
1202
|
+
* needs an explicit commit on the worktree, sl needs `sl commit`,
|
|
1203
|
+
* none has nothing to commit. If pending changes exist and `commit`
|
|
1204
|
+
* is false, the on-disk directory still gets removed and changes are
|
|
1205
|
+
* lost — the verb prints a clear warning. */
|
|
1206
|
+
commit: boolean;
|
|
1252
1207
|
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
* scrollback (when capturable) is attached to help diagnose.
|
|
1260
|
-
*/
|
|
1261
|
-
declare class AgentDiedOnSpawnError extends Error implements HasNextSteps {
|
|
1262
|
-
readonly agentName: string;
|
|
1263
|
-
readonly paneId: string;
|
|
1264
|
-
readonly scrollback: string | undefined;
|
|
1265
|
-
readonly name = "AgentDiedOnSpawnError";
|
|
1266
|
-
constructor(agentName: string, paneId: string, scrollback: string | undefined);
|
|
1267
|
-
errorNextSteps(): NextStep[];
|
|
1268
|
-
}
|
|
1269
|
-
/**
|
|
1270
|
-
* Thrown when an agent's pane is alive AND staying alive after the
|
|
1271
|
-
* liveness window, but its first burst of output matches a known
|
|
1272
|
-
* provider-startup-failure pattern (missing API key, auth rejected, …).
|
|
1273
|
-
* Source: feedback ws task `agent_spawn_model_auth_failure_counts_as_live`.
|
|
1274
|
-
* Live dogfood report: `pi-meta --no-solo --model sonnet:high` printed
|
|
1275
|
-
* `Error: No API key found for amazon-bedrock` and parked at a prompt.
|
|
1276
|
-
* The pane stayed alive (1.5s liveness check passed) but the worker
|
|
1277
|
-
* could never do work — the orchestrator only discovered this when
|
|
1278
|
-
* `mu task wait` stalled minutes later.
|
|
1279
|
-
*
|
|
1280
|
-
* Distinct from `AgentDiedOnSpawnError`:
|
|
1281
|
-
* - `AgentDiedOnSpawnError` → pane vanished within the liveness window
|
|
1282
|
-
* (CLI exited fast).
|
|
1283
|
-
* - `AgentSpawnStartupError` → pane alive, but the captured scrollback
|
|
1284
|
-
* tail contains a curated provider-auth-failure pattern.
|
|
1285
|
-
* The two carry different remediation hints (CLI override vs. fix the
|
|
1286
|
-
* env var), so they're separate types instead of one with a flag.
|
|
1287
|
-
*
|
|
1288
|
-
* The pattern list is curated and short to keep false-positive risk low
|
|
1289
|
-
* — the scan only looks at the last ~30 lines of the 50-line capture
|
|
1290
|
-
* taken right after the liveness sleep, so matches naturally come from
|
|
1291
|
-
* the CLI's first ~1.5s of output (not arbitrary later prompts the
|
|
1292
|
-
* agent might type into).
|
|
1293
|
-
*/
|
|
1294
|
-
declare class AgentSpawnStartupError extends Error implements HasNextSteps {
|
|
1295
|
-
readonly agentName: string;
|
|
1296
|
-
readonly paneId: string;
|
|
1297
|
-
/** The single scrollback line that matched a known startup-error
|
|
1298
|
-
* pattern. Surfaced verbatim in the message so the operator sees
|
|
1299
|
-
* what mu saw. */
|
|
1300
|
-
readonly matchedLine: string;
|
|
1301
|
-
/** Full captured scrollback (tail-trimmed already by
|
|
1302
|
-
* awaitSpawnLiveness). Attached to the message for context. */
|
|
1303
|
-
readonly scrollback: string;
|
|
1304
|
-
readonly name = "AgentSpawnStartupError";
|
|
1305
|
-
constructor(agentName: string, paneId: string,
|
|
1306
|
-
/** The single scrollback line that matched a known startup-error
|
|
1307
|
-
* pattern. Surfaced verbatim in the message so the operator sees
|
|
1308
|
-
* what mu saw. */
|
|
1309
|
-
matchedLine: string,
|
|
1310
|
-
/** Full captured scrollback (tail-trimmed already by
|
|
1311
|
-
* awaitSpawnLiveness). Attached to the message for context. */
|
|
1312
|
-
scrollback: string);
|
|
1313
|
-
errorNextSteps(): NextStep[];
|
|
1314
|
-
}
|
|
1315
|
-
/**
|
|
1316
|
-
* Thrown when `closeAgent` is called on an agent that has an associated
|
|
1317
|
-
* workspace AND the caller didn't explicitly opt into discarding it.
|
|
1318
|
-
*
|
|
1319
|
-
* Background: the FK on `vcs_workspaces.agent` cascades on agent
|
|
1320
|
-
* delete, so a naive `closeAgent` drops the workspace registry row
|
|
1321
|
-
* but leaves the on-disk dir orphaned (mu can't see it via
|
|
1322
|
-
* `mu workspace list / free / path` afterwards). Surfaced during
|
|
1323
|
-
* the multi-agent dogfood teardown when three workspaces went
|
|
1324
|
-
* orphaned silently.
|
|
1325
|
-
*
|
|
1326
|
-
* The fix: refuse close if a workspace exists; force the caller to
|
|
1327
|
-
* decide. Two actionable resolutions:
|
|
1328
|
-
* - `mu workspace free <agent>` first, then close cleanly.
|
|
1329
|
-
* - `mu agent close <agent> --discard-workspace` to free the
|
|
1330
|
-
* workspace AND close the agent in one shot (lossy: pending
|
|
1331
|
-
* changes in the workspace are gone).
|
|
1332
|
-
*
|
|
1333
|
-
* Maps to exit code 4 (conflict) via the cli.ts handler.
|
|
1334
|
-
*/
|
|
1335
|
-
declare class WorkspacePreservedError extends Error implements HasNextSteps {
|
|
1336
|
-
readonly agentName: string;
|
|
1337
|
-
readonly workspacePath: string;
|
|
1338
|
-
readonly name = "WorkspacePreservedError";
|
|
1339
|
-
constructor(agentName: string, workspacePath: string);
|
|
1340
|
-
errorNextSteps(): NextStep[];
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
/** The signal set kick supports. SIGINT is graceful (matches Ctrl-C
|
|
1344
|
-
* semantics — what the operator probably wanted in the first place);
|
|
1345
|
-
* SIGTERM is the polite escalation; SIGKILL is the unblockable
|
|
1346
|
-
* hammer. We deliberately don't expose arbitrary signals — the
|
|
1347
|
-
* three above are the actionable ones for "interrupt a wedged
|
|
1348
|
-
* foreground tool subprocess." */
|
|
1349
|
-
type KickSignal = "SIGINT" | "SIGTERM" | "SIGKILL";
|
|
1350
|
-
declare function isKickSignal(s: string): s is KickSignal;
|
|
1351
|
-
/**
|
|
1352
|
-
* Thrown when the foreground pgid lookup on a pane's TTY yields
|
|
1353
|
-
* either no rows at all (the pane is sitting at an idle shell with
|
|
1354
|
-
* no foreground job) or only the wrapping shell itself (the LLM CLI
|
|
1355
|
-
* — pi/claude/codex — is the foreground; signalling it would close
|
|
1356
|
-
* the agent, which is what `mu agent close` is for).
|
|
1357
|
-
*
|
|
1358
|
-
* Maps to the generic exit code 1 in handle.ts (this is a
|
|
1359
|
-
* runtime-state condition, not a typed not-found / conflict).
|
|
1360
|
-
*/
|
|
1361
|
-
declare class NoForegroundProcessError extends Error implements HasNextSteps {
|
|
1362
|
-
readonly agentName: string;
|
|
1363
|
-
readonly tty: string;
|
|
1364
|
-
readonly reason: "no-foreground" | "shell-only";
|
|
1365
|
-
readonly name = "NoForegroundProcessError";
|
|
1366
|
-
constructor(agentName: string, tty: string, reason: "no-foreground" | "shell-only");
|
|
1367
|
-
errorNextSteps(): NextStep[];
|
|
1368
|
-
}
|
|
1369
|
-
interface KickProcessExecResult {
|
|
1370
|
-
stdout: string;
|
|
1371
|
-
stderr: string;
|
|
1372
|
-
exitCode: number | null;
|
|
1373
|
-
}
|
|
1374
|
-
type KickProcessExecutor = (cmd: string, args: readonly string[]) => Promise<KickProcessExecResult>;
|
|
1375
|
-
/** Install a custom executor (for tests). Returns the previous one so
|
|
1376
|
-
* tests can restore cleanly. */
|
|
1377
|
-
declare function setKickProcessExecutor(executor: KickProcessExecutor): KickProcessExecutor;
|
|
1378
|
-
/** Restore the real executor. */
|
|
1379
|
-
declare function resetKickProcessExecutor(): void;
|
|
1380
|
-
interface PsRow {
|
|
1381
|
-
pid: number;
|
|
1382
|
-
pgid: number;
|
|
1383
|
-
/** ps's `stat` (or `state`) field. The presence of `+` means
|
|
1384
|
-
* "foreground process group on its controlling tty". */
|
|
1385
|
-
stat: string;
|
|
1386
|
-
/** Process command (just the comm; truncated, used for diagnostics). */
|
|
1387
|
-
comm: string;
|
|
1388
|
-
}
|
|
1389
|
-
/**
|
|
1390
|
-
* Parse `ps -t <tty> -o pid=,pgid=,stat=,comm=` output. Each non-blank
|
|
1391
|
-
* line is one process: four whitespace-separated fields. Defensive
|
|
1392
|
-
* about leading whitespace and command names with embedded spaces
|
|
1393
|
-
* (the comm is the LAST field — join the tail).
|
|
1394
|
-
*/
|
|
1395
|
-
declare function parsePsTtyOutput(output: string): PsRow[];
|
|
1396
|
-
/**
|
|
1397
|
-
* Resolve the foreground process group id for a TTY device path. The
|
|
1398
|
-
* canonical signal `ps`'s `stat` field uses is `+` (BSD/Darwin AND
|
|
1399
|
-
* Linux procps). We pick the first row whose stat contains `+`; its
|
|
1400
|
-
* `pgid` is the foreground pgid of that controlling terminal.
|
|
1401
|
-
*
|
|
1402
|
-
* Returns:
|
|
1403
|
-
* - `{ kind: "ok", pgid, fgRow }` on success
|
|
1404
|
-
* - `{ kind: "no-foreground" }` when no row carries `+` AND there
|
|
1405
|
-
* are no candidate rows at all
|
|
1406
|
-
* - `{ kind: "shell-only", pgid, fgRow }` when the foreground pgid
|
|
1407
|
-
* resolves to a shell whose comm is the agent's wrapping CLI
|
|
1408
|
-
* (caller decides whether to refuse — kick refuses)
|
|
1409
|
-
*
|
|
1410
|
-
* The wrapping-CLI guard is intentionally narrow: we only refuse
|
|
1411
|
-
* when the foreground process command matches one of the known
|
|
1412
|
-
* pi/claude/codex/zsh/bash shapes. Anything else (a `find`, a
|
|
1413
|
-
* `cargo build`, a `python script.py`) is exactly what we want to
|
|
1414
|
-
* signal — that's the unbounded-tool case the verb was built for.
|
|
1415
|
-
*/
|
|
1416
|
-
interface ForegroundLookup {
|
|
1417
|
-
kind: "ok" | "shell-only" | "no-foreground";
|
|
1418
|
-
pgid?: number;
|
|
1419
|
-
fgRow?: PsRow;
|
|
1420
|
-
/** All rows ps returned for the tty, for diagnostics / tests. */
|
|
1421
|
-
rows: PsRow[];
|
|
1422
|
-
}
|
|
1423
|
-
declare function foregroundPgid(tty: string): Promise<ForegroundLookup>;
|
|
1424
|
-
interface KickAgentOptions {
|
|
1425
|
-
workstream: string;
|
|
1426
|
-
/** Defaults to SIGINT (matches Ctrl-C semantics). */
|
|
1427
|
-
signal?: KickSignal;
|
|
1428
|
-
}
|
|
1429
|
-
interface KickAgentResult {
|
|
1430
|
-
agentName: string;
|
|
1431
|
-
paneId: string;
|
|
1432
|
-
/** TTY device path the foreground pgid was resolved against. */
|
|
1433
|
-
tty: string;
|
|
1434
|
-
/** The pgid we signalled. */
|
|
1435
|
-
signaledPgid: number;
|
|
1436
|
-
signal: KickSignal;
|
|
1437
|
-
/** The comm of the foreground process at the time of signal — useful
|
|
1438
|
-
* diagnostic in the event log ("we kicked a `find`, not a `cargo`"). */
|
|
1439
|
-
foregroundComm: string;
|
|
1440
|
-
}
|
|
1441
|
-
/**
|
|
1442
|
-
* Send `signal` to the foreground process group of an agent's pane
|
|
1443
|
-
* TTY. Default signal is SIGINT.
|
|
1444
|
-
*
|
|
1445
|
-
* Errors:
|
|
1446
|
-
* - `AgentNotFoundError` — the agent doesn't exist in this workstream.
|
|
1447
|
-
* - `PaneNotFoundError` (from paneTTY) — the agent's pane has vanished.
|
|
1448
|
-
* - `NoForegroundProcessError` — pane has no foreground job, OR the
|
|
1449
|
-
* foreground is the wrapping CLI itself (refuse; use `mu agent close`).
|
|
1450
|
-
*
|
|
1451
|
-
* Emits an `agent kick <name> (signal=..., pgid=..., comm=...)` event
|
|
1452
|
-
* on success.
|
|
1453
|
-
*/
|
|
1454
|
-
declare function kickAgent(db: Db, name: string, opts: KickAgentOptions): Promise<KickAgentResult>;
|
|
1455
|
-
|
|
1456
|
-
type VcsBackendName = "jj" | "sl" | "git" | "none";
|
|
1457
|
-
interface RebaseResult {
|
|
1458
|
-
/** The ref the workspace was actually rebased onto (resolved
|
|
1459
|
-
* symbolic-or-revset → concrete name). For git that is the
|
|
1460
|
-
* resolveGitMainRef() symbolic ref; for jj/sl it's the literal
|
|
1461
|
-
* `trunk()` revset (or whatever the operator passed via fromRef). */
|
|
1462
|
-
fromRef: string;
|
|
1463
|
-
/** Commit subjects (or descriptions) that got replayed, oldest-first.
|
|
1464
|
-
* Empty when the workspace was already at fromRef (no-op). */
|
|
1465
|
-
replayed: string[];
|
|
1466
|
-
/** Files / commits that conflicted during the rebase. Always
|
|
1467
|
-
* empty for a successful rebase — a non-empty conflicts list
|
|
1468
|
-
* means we threw WorkspaceConflictError before returning. The
|
|
1469
|
-
* field exists so the error's serialised payload can carry it. */
|
|
1470
|
-
conflicts: string[];
|
|
1471
|
-
}
|
|
1472
|
-
interface CommitSummary {
|
|
1473
|
-
/** Full commit / change id. */
|
|
1474
|
-
sha: string;
|
|
1475
|
-
/** First-line description / subject. */
|
|
1476
|
-
subject: string;
|
|
1477
|
-
/** Remainder of the commit message (may be empty). */
|
|
1478
|
-
body: string;
|
|
1479
|
-
/** Author display name, when the backend exposes one. */
|
|
1480
|
-
author: string;
|
|
1481
|
-
/** ISO-8601 author / commit timestamp. */
|
|
1482
|
-
authorDate: string;
|
|
1483
|
-
/** Compact relative author time (e.g. "3m", "2d"). */
|
|
1484
|
-
relTime: string;
|
|
1485
|
-
}
|
|
1486
|
-
interface ShowCommitResult {
|
|
1487
|
-
/** Captured VCS show output (possibly truncated). Empty string on error. */
|
|
1488
|
-
text: string;
|
|
1489
|
-
/** True when stdout exceeded SHOW_COMMIT_MAX_CHARS and was clipped. */
|
|
1490
|
-
truncated: boolean;
|
|
1491
|
-
/** Human-readable error message; omitted on success. */
|
|
1492
|
-
error?: string;
|
|
1493
|
-
}
|
|
1494
|
-
interface CreateWorkspaceOptions$1 {
|
|
1495
|
-
/** The repository being branched from. Absolute path. */
|
|
1496
|
-
projectRoot: string;
|
|
1497
|
-
/** Where to place the new workspace. Absolute path; must NOT exist. */
|
|
1498
|
-
workspacePath: string;
|
|
1499
|
-
/** Optional commit / branch / changeset id to base off. Backend-specific:
|
|
1500
|
-
* git uses it as a `git worktree add`'s ref, jj as a revset, sl as a
|
|
1501
|
-
* rev. Undefined = current head. */
|
|
1502
|
-
parentRef?: string;
|
|
1503
|
-
}
|
|
1504
|
-
interface CreateWorkspaceResult {
|
|
1505
|
-
/** The actual ref the workspace points at (resolved to a stable id
|
|
1506
|
-
* when possible). Stored on the row; useful for `mu workspace list`
|
|
1507
|
-
* and for `--commit` flows. May be null for backends that don't
|
|
1508
|
-
* expose a meaningful parent (e.g. `none`). */
|
|
1509
|
-
parentRef: string | null;
|
|
1510
|
-
}
|
|
1511
|
-
interface FreeWorkspaceOptions$1 {
|
|
1512
|
-
workspacePath: string;
|
|
1513
|
-
/** If true, attempt to commit any pending changes BEFORE removal.
|
|
1514
|
-
* Backend-specific: jj auto-commits via `jj describe + jj new`, git
|
|
1515
|
-
* needs an explicit commit on the worktree, sl needs `sl commit`,
|
|
1516
|
-
* none has nothing to commit. If pending changes exist and `commit`
|
|
1517
|
-
* is false, the on-disk directory still gets removed and changes are
|
|
1518
|
-
* lost — the verb prints a clear warning. */
|
|
1519
|
-
commit: boolean;
|
|
1520
|
-
}
|
|
1521
|
-
interface FreeWorkspaceResult$1 {
|
|
1522
|
-
/** The commit id that captured the pending changes, when `commit` was
|
|
1523
|
-
* true and there was something to commit. Otherwise undefined. */
|
|
1524
|
-
committedRef?: string;
|
|
1525
|
-
/** True iff the on-disk path was actually removed (vs. already gone). */
|
|
1526
|
-
removed: boolean;
|
|
1208
|
+
interface FreeWorkspaceResult$1 {
|
|
1209
|
+
/** The commit id that captured the pending changes, when `commit` was
|
|
1210
|
+
* true and there was something to commit. Otherwise undefined. */
|
|
1211
|
+
committedRef?: string;
|
|
1212
|
+
/** True iff the on-disk path was actually removed (vs. already gone). */
|
|
1213
|
+
removed: boolean;
|
|
1527
1214
|
}
|
|
1528
1215
|
interface VcsBackend {
|
|
1529
1216
|
readonly name: VcsBackendName;
|
|
@@ -1644,136 +1331,597 @@ interface VcsBackend {
|
|
|
1644
1331
|
*/
|
|
1645
1332
|
listDirtyFiles(workspacePath: string): Promise<string[]>;
|
|
1646
1333
|
}
|
|
1647
|
-
|
|
1648
|
-
declare const gitBackend: VcsBackend;
|
|
1649
|
-
|
|
1650
|
-
declare const jjBackend: VcsBackend;
|
|
1651
|
-
|
|
1652
|
-
declare const noneBackend: VcsBackend;
|
|
1653
|
-
|
|
1654
|
-
declare const slBackend: VcsBackend;
|
|
1655
|
-
|
|
1656
|
-
/** Return the backend that should handle projectRoot. Walks BACKENDS
|
|
1657
|
-
* in precedence order; never returns undefined because noneBackend
|
|
1658
|
-
* always claims. */
|
|
1659
|
-
declare function detectBackend(projectRoot: string): Promise<VcsBackend>;
|
|
1660
|
-
/** Look up a backend by name. Throws on unknown name. Used by
|
|
1661
|
-
* `mu agent spawn --workspace-backend ...` to honour an explicit
|
|
1662
|
-
* override. */
|
|
1663
|
-
declare function backendByName(name: VcsBackendName): VcsBackend;
|
|
1664
|
-
|
|
1334
|
+
|
|
1335
|
+
declare const gitBackend: VcsBackend;
|
|
1336
|
+
|
|
1337
|
+
declare const jjBackend: VcsBackend;
|
|
1338
|
+
|
|
1339
|
+
declare const noneBackend: VcsBackend;
|
|
1340
|
+
|
|
1341
|
+
declare const slBackend: VcsBackend;
|
|
1342
|
+
|
|
1343
|
+
/** Return the backend that should handle projectRoot. Walks BACKENDS
|
|
1344
|
+
* in precedence order; never returns undefined because noneBackend
|
|
1345
|
+
* always claims. */
|
|
1346
|
+
declare function detectBackend(projectRoot: string): Promise<VcsBackend>;
|
|
1347
|
+
/** Look up a backend by name. Throws on unknown name. Used by
|
|
1348
|
+
* `mu agent spawn --workspace-backend ...` to honour an explicit
|
|
1349
|
+
* override. */
|
|
1350
|
+
declare function backendByName(name: VcsBackendName): VcsBackend;
|
|
1351
|
+
|
|
1352
|
+
/**
|
|
1353
|
+
* Resolve the actual executable to launch in an agent's pane for a given
|
|
1354
|
+
* `cli`. Honours the env var `MU_<UPPER_CLI>_COMMAND` (e.g. `MU_PI_COMMAND=
|
|
1355
|
+
* pi-alt` makes `--cli pi` actually exec `pi-alt`). Falls back to the cli
|
|
1356
|
+
* name itself, which is what users expect when their `pi` binary is on
|
|
1357
|
+
* `$PATH` under that exact name.
|
|
1358
|
+
*
|
|
1359
|
+
* Used by `spawnAgent` to pick the spawned command, and by reconcile's
|
|
1360
|
+
* orphan detector so externally-spawned panes running the resolved binary
|
|
1361
|
+
* are still recognised as agents.
|
|
1362
|
+
*/
|
|
1363
|
+
declare function resolveCliCommand(cli: string): string;
|
|
1364
|
+
/**
|
|
1365
|
+
* Compute the `MU_<UPPER_CLI>_COMMAND` env var name mu consults when
|
|
1366
|
+
* resolving `--cli <key>`. Hyphens in the cli key become underscores
|
|
1367
|
+
* (env var names can't contain `-`); this matches the operator-aliases
|
|
1368
|
+
* convention documented in the mu skill (e.g. `--cli pi-meta` →
|
|
1369
|
+
* `MU_PI_META_COMMAND`).
|
|
1370
|
+
*/
|
|
1371
|
+
declare function envVarNameForCli(cli: string): string;
|
|
1372
|
+
/**
|
|
1373
|
+
* Resolve `--cli <key>` to its actual command string AND tell the
|
|
1374
|
+
* caller whether the resolution came from a `MU_<UPPER_CLI>_COMMAND`
|
|
1375
|
+
* env var or fell through to the bare cli name. The CLI uses this to
|
|
1376
|
+
* surface env-var attribution in the spawn-success line so config
|
|
1377
|
+
* issues are visible without `mu agent show`
|
|
1378
|
+
* (fb_agent_spawn_no_validation, part C).
|
|
1379
|
+
*/
|
|
1380
|
+
declare function resolveCliCommandWithSource(cli: string): {
|
|
1381
|
+
command: string;
|
|
1382
|
+
envVar: string;
|
|
1383
|
+
resolvedFromEnv: boolean;
|
|
1384
|
+
};
|
|
1385
|
+
interface CommandResolutionResult {
|
|
1386
|
+
ok: boolean;
|
|
1387
|
+
/** First whitespace-separated token of the command — the binary
|
|
1388
|
+
* whose presence on PATH we checked. */
|
|
1389
|
+
binary: string;
|
|
1390
|
+
/** Absolute path of the resolved binary on PATH, when ok=true. */
|
|
1391
|
+
resolvedPath?: string;
|
|
1392
|
+
}
|
|
1393
|
+
type CommandResolver = (command: string) => Promise<CommandResolutionResult>;
|
|
1394
|
+
/** Override the PATH resolver. Tests use this to simulate "binary
|
|
1395
|
+
* absent" / "binary present" without depending on what's actually
|
|
1396
|
+
* installed. Production callers should never touch this. */
|
|
1397
|
+
declare function setCommandResolverForTests(resolver: CommandResolver): void;
|
|
1398
|
+
/** Restore the default PATH resolver. */
|
|
1399
|
+
declare function resetCommandResolverForTests(): void;
|
|
1400
|
+
/**
|
|
1401
|
+
* Verify the first token of `command` resolves to a binary on PATH.
|
|
1402
|
+
* Public so tests can call it directly; spawnAgent calls it before
|
|
1403
|
+
* prestageWorkspace so a bad --cli never creates an orphan workspace.
|
|
1404
|
+
*/
|
|
1405
|
+
declare function checkCommandResolvable(command: string): Promise<CommandResolutionResult>;
|
|
1406
|
+
interface SpawnAgentOptions {
|
|
1407
|
+
name: string;
|
|
1408
|
+
workstream: string;
|
|
1409
|
+
/** Defaults to "pi". 0.1.0 only really supports "pi" but the column
|
|
1410
|
+
* accepts any string for forward-compat with future multi-CLI support
|
|
1411
|
+
* (claude/codex). */
|
|
1412
|
+
cli?: string;
|
|
1413
|
+
/** The actual command to run in the pane. Defaults to the cli value. */
|
|
1414
|
+
command?: string;
|
|
1415
|
+
/** Window name to group this agent under. Defaults to the agent's name
|
|
1416
|
+
* (so each agent gets its own window). Multiple agents sharing a `tab`
|
|
1417
|
+
* share a window with multiple panes. */
|
|
1418
|
+
tab?: string;
|
|
1419
|
+
/** "full-access" (default) or "read-only". The schema stores it; today
|
|
1420
|
+
* the role isn't enforced (deferred to a future capabilities pass). */
|
|
1421
|
+
role?: string;
|
|
1422
|
+
/** Initial working directory for the spawned pane (`tmux -c <path>`).
|
|
1423
|
+
* When `workspace: true` is passed, this is ignored — the workspace
|
|
1424
|
+
* path is used instead. */
|
|
1425
|
+
cwd?: string;
|
|
1426
|
+
/** Override the tmux session name. Defaults to `mu-<workstream>`. */
|
|
1427
|
+
tmuxSession?: string;
|
|
1428
|
+
/** Auto-create a VCS workspace for this agent before spawning the
|
|
1429
|
+
* pane and use the workspace path as cwd. Backend defaults to
|
|
1430
|
+
* detection (jj > sl > git > none). */
|
|
1431
|
+
workspace?: boolean;
|
|
1432
|
+
/** Force a specific VCS backend (only meaningful with `workspace: true`). */
|
|
1433
|
+
workspaceBackend?: VcsBackendName;
|
|
1434
|
+
/** Optional ref to base the workspace on (only meaningful with
|
|
1435
|
+
* `workspace: true`). Backend-specific. */
|
|
1436
|
+
workspaceFrom?: string;
|
|
1437
|
+
/** Project root the workspace branches from (only meaningful with
|
|
1438
|
+
* `workspace: true`). Defaults to `process.cwd()`. */
|
|
1439
|
+
workspaceProjectRoot?: string;
|
|
1440
|
+
/** Run the control-socket handshake for pi agents (default true).
|
|
1441
|
+
* `false` skips it and reports `ctl: "skipped"`. */
|
|
1442
|
+
ctl?: boolean;
|
|
1443
|
+
}
|
|
1444
|
+
/** Outcome of the spawn-time control-socket handshake. */
|
|
1445
|
+
type SpawnCtl = "ok" | "missing" | "refused" | "skipped";
|
|
1446
|
+
/** What spawnAgent returns: the registered row plus the handshake outcome. */
|
|
1447
|
+
type SpawnedAgent = AgentRow & {
|
|
1448
|
+
ctl: SpawnCtl;
|
|
1449
|
+
ctlSocket: string;
|
|
1450
|
+
};
|
|
1451
|
+
/**
|
|
1452
|
+
* Spawn a new agent in its tmux pane and register it in the DB.
|
|
1453
|
+
*
|
|
1454
|
+
* Phases:
|
|
1455
|
+
* 1. Validate name + uniqueness.
|
|
1456
|
+
* 2. If --workspace: prestageWorkspace() (placeholder agent row +
|
|
1457
|
+
* workspace dir + workspace row).
|
|
1458
|
+
* 3. createOrReusePane() in the workspace path (or opts.cwd).
|
|
1459
|
+
* 4. setPaneTitle + enableMuPaneBordersForPane.
|
|
1460
|
+
* 5. finalizeAgentRow() — patch placeholder pane_id to real (workspace
|
|
1461
|
+
* path), or insert a fresh agent row (no-workspace path).
|
|
1462
|
+
* 6. awaitSpawnLiveness().
|
|
1463
|
+
*
|
|
1464
|
+
* Failure between any of (3)–(6) calls rollbackSpawn() to undo the
|
|
1465
|
+
* pane + row + workspace. The caller-visible error is preserved.
|
|
1466
|
+
*/
|
|
1467
|
+
declare function spawnAgent(db: Db, opts: SpawnAgentOptions): Promise<SpawnedAgent>;
|
|
1468
|
+
/**
|
|
1469
|
+
* Default liveness window in milliseconds. 0 disables the check (useful
|
|
1470
|
+
* for fast tests that don't want to wait). Override via env var
|
|
1471
|
+
* `MU_SPAWN_LIVENESS_MS`.
|
|
1472
|
+
*/
|
|
1473
|
+
declare function defaultSpawnLivenessMs(): number;
|
|
1474
|
+
|
|
1475
|
+
interface AdoptAgentOptions {
|
|
1476
|
+
/** tmux pane id (e.g. '%15'). Must already exist on the tmux server. */
|
|
1477
|
+
paneId: string;
|
|
1478
|
+
/** Workstream to adopt the pane into. The pane MUST be in the
|
|
1479
|
+
* matching tmux session (`mu-<workstream>`); cross-session adopt is
|
|
1480
|
+
* rejected. */
|
|
1481
|
+
workstream: string;
|
|
1482
|
+
/** Override the pane's title with this name. When omitted, the pane's
|
|
1483
|
+
* current title becomes the agent name (zero-config adoption). */
|
|
1484
|
+
name?: string;
|
|
1485
|
+
/** Defaults to 'pi' via the schema DEFAULT. */
|
|
1486
|
+
cli?: string;
|
|
1487
|
+
/** 'full-access' (default) or 'read-only'. */
|
|
1488
|
+
role?: string;
|
|
1489
|
+
/** Override the tmux session lookup. Defaults to `mu-<workstream>`. */
|
|
1490
|
+
tmuxSession?: string;
|
|
1491
|
+
}
|
|
1492
|
+
interface AdoptAgentResult {
|
|
1493
|
+
agent: AgentRow;
|
|
1494
|
+
/** True when the pane already had a matching agents row — the call
|
|
1495
|
+
* was a no-op (idempotent). */
|
|
1496
|
+
alreadyAdopted: boolean;
|
|
1497
|
+
/** The pane title before adopt, or null if the pane had no title. */
|
|
1498
|
+
previousTitle: string | null;
|
|
1499
|
+
/** The title the pane was set to (== agent.name post-adopt). Equal to
|
|
1500
|
+
* previousTitle when no retitle happened. */
|
|
1501
|
+
paneTitleSetTo: string;
|
|
1502
|
+
/** One probe of the derived control socket; "skipped" for non-pi CLIs.
|
|
1503
|
+
* An adopted pi pane usually lacks MU_CTL_SOCK, so this is "missing". */
|
|
1504
|
+
ctl: SpawnCtl;
|
|
1505
|
+
ctlSocket: string;
|
|
1506
|
+
}
|
|
1507
|
+
/**
|
|
1508
|
+
* Register an existing tmux pane as a managed mu agent. Inverse of the
|
|
1509
|
+
* 'orphan' state surfaced by `mu agent list`: a pane that looks like an
|
|
1510
|
+
* agent (running pi/claude/codex) but has no DB row.
|
|
1511
|
+
*
|
|
1512
|
+
* Identity contract (matches the claim protocol invariant):
|
|
1513
|
+
* - Post-adopt, the pane's title equals the agent's name.
|
|
1514
|
+
* - When `name` is omitted, the pane's existing title becomes the
|
|
1515
|
+
* agent name verbatim. Adopting a pane titled 'pi' would fail name
|
|
1516
|
+
* validation — caller must supply --name in that case.
|
|
1517
|
+
*
|
|
1518
|
+
* Idempotent: adopting the same pane twice with the same name is a
|
|
1519
|
+
* no-op (returns alreadyAdopted=true). Adopting a different pane under
|
|
1520
|
+
* an existing agent name throws AgentExistsError.
|
|
1521
|
+
*
|
|
1522
|
+
* Validation order (matches the design in note #100):
|
|
1523
|
+
* 1. Pane id format -> assertValidPaneId via paneExists / setPaneTitle
|
|
1524
|
+
* 2. Pane exists -> PaneNotFoundError
|
|
1525
|
+
* 3. Pane is in session -> AgentNotInWorkstreamError (cross-session)
|
|
1526
|
+
* 4. Resolved name OK -> isValidAgentName / Error('agent name invalid')
|
|
1527
|
+
* 5. Idempotent check -> if pane already owned by an agent of this
|
|
1528
|
+
* name, return alreadyAdopted=true
|
|
1529
|
+
* 6. Name not taken -> AgentExistsError (else)
|
|
1530
|
+
* 7. Insert + retitle.
|
|
1531
|
+
*
|
|
1532
|
+
* Status starts at 'free' — reconcile/detect will update it on the next
|
|
1533
|
+
* `mu agent list` based on actual pane content (the pi prompt yields
|
|
1534
|
+
* 'free'; an agent mid-thought yields 'busy'; etc.). We don't run
|
|
1535
|
+
* detection inline here because the caller may not have $TMUX, and
|
|
1536
|
+
* adoption shouldn't depend on a captured-pane probe succeeding.
|
|
1537
|
+
*/
|
|
1538
|
+
declare function adoptAgent(db: Db, opts: AdoptAgentOptions): Promise<AdoptAgentResult>;
|
|
1539
|
+
|
|
1540
|
+
/**
|
|
1541
|
+
* Pre-flight failure: the command mu would have spawned in the new
|
|
1542
|
+
* pane doesn't resolve to a binary on PATH (and isn't an absolute /
|
|
1543
|
+
* relative path that exists + is executable). Thrown by `spawnAgent`
|
|
1544
|
+
* BEFORE `prestageWorkspace` so a typo in `--cli` never leaves an
|
|
1545
|
+
* orphan workspace dir behind.
|
|
1546
|
+
*
|
|
1547
|
+
* Source: feedback ws task `fb_agent_spawn_no_validation`. Live
|
|
1548
|
+
* dogfood report: `mu agent spawn worker-1 --cli pi-meta` on a host
|
|
1549
|
+
* where the `pi-meta` binary wasn't on PATH printed `Spawned worker-1
|
|
1550
|
+
* (pi-meta)` and the pane immediately died with `command not found`;
|
|
1551
|
+
* the existing 1.5s liveness check sometimes missed it (the shell
|
|
1552
|
+
* stays alive after the failed exec). Pre-flighting the PATH lookup
|
|
1553
|
+
* surfaces the typo before any side effects (workspace, pane, DB row).
|
|
1554
|
+
*
|
|
1555
|
+
* Distinct from `AgentSpawnStartupError` (pane alive but parked at an
|
|
1556
|
+
* error prompt) and `AgentDiedOnSpawnError` (pane vanished within the
|
|
1557
|
+
* liveness window). All three carry different remediation hints, so
|
|
1558
|
+
* they're separate types.
|
|
1559
|
+
*/
|
|
1560
|
+
declare class AgentSpawnCliNotFoundError extends Error implements HasNextSteps {
|
|
1561
|
+
readonly cli: string;
|
|
1562
|
+
/** First whitespace-separated token of the resolved command — the
|
|
1563
|
+
* thing actually missing on PATH. Surfaced verbatim in the
|
|
1564
|
+
* message so the operator sees what mu searched for (which may
|
|
1565
|
+
* differ from `cli` when `$MU_<UPPER_CLI>_COMMAND` rewrites it). */
|
|
1566
|
+
readonly binary: string;
|
|
1567
|
+
/** Name of the env var that mu consulted before falling back to
|
|
1568
|
+
* the bare `cli` value (e.g. `MU_PI_META_COMMAND`). Always set
|
|
1569
|
+
* to the conventional name so the nextSteps hint can recommend
|
|
1570
|
+
* exporting it. */
|
|
1571
|
+
readonly envVarChecked: string;
|
|
1572
|
+
readonly name = "AgentSpawnCliNotFoundError";
|
|
1573
|
+
constructor(cli: string,
|
|
1574
|
+
/** First whitespace-separated token of the resolved command — the
|
|
1575
|
+
* thing actually missing on PATH. Surfaced verbatim in the
|
|
1576
|
+
* message so the operator sees what mu searched for (which may
|
|
1577
|
+
* differ from `cli` when `$MU_<UPPER_CLI>_COMMAND` rewrites it). */
|
|
1578
|
+
binary: string,
|
|
1579
|
+
/** Name of the env var that mu consulted before falling back to
|
|
1580
|
+
* the bare `cli` value (e.g. `MU_PI_META_COMMAND`). Always set
|
|
1581
|
+
* to the conventional name so the nextSteps hint can recommend
|
|
1582
|
+
* exporting it. */
|
|
1583
|
+
envVarChecked: string);
|
|
1584
|
+
errorNextSteps(): NextStep[];
|
|
1585
|
+
}
|
|
1586
|
+
declare class AgentExistsError extends Error implements HasNextSteps {
|
|
1587
|
+
readonly agentName: string;
|
|
1588
|
+
readonly name = "AgentExistsError";
|
|
1589
|
+
constructor(agentName: string);
|
|
1590
|
+
errorNextSteps(): NextStep[];
|
|
1591
|
+
}
|
|
1592
|
+
declare class AgentNotFoundError extends Error implements HasNextSteps {
|
|
1593
|
+
readonly agentName: string;
|
|
1594
|
+
/** Optional workstream context. When set, the message is enriched
|
|
1595
|
+
* with `(in workstream <ws>)` so the verb that hit the miss
|
|
1596
|
+
* (e.g. `mu workspace path <agent> -w <ws>`) doesn't leave the
|
|
1597
|
+
* operator guessing which scope was searched. Optional so existing
|
|
1598
|
+
* call sites that only know the agent name keep their original
|
|
1599
|
+
* one-line message. */
|
|
1600
|
+
readonly workstream?: string | undefined;
|
|
1601
|
+
readonly name = "AgentNotFoundError";
|
|
1602
|
+
constructor(agentName: string,
|
|
1603
|
+
/** Optional workstream context. When set, the message is enriched
|
|
1604
|
+
* with `(in workstream <ws>)` so the verb that hit the miss
|
|
1605
|
+
* (e.g. `mu workspace path <agent> -w <ws>`) doesn't leave the
|
|
1606
|
+
* operator guessing which scope was searched. Optional so existing
|
|
1607
|
+
* call sites that only know the agent name keep their original
|
|
1608
|
+
* one-line message. */
|
|
1609
|
+
workstream?: string | undefined);
|
|
1610
|
+
errorNextSteps(): NextStep[];
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* Thrown when an entity-targeted verb is invoked with `-w/--workstream
|
|
1614
|
+
* <name>` but the named agent lives in a different workstream.
|
|
1615
|
+
* Mirrors `TaskNotInWorkstreamError`. Maps to exit code 4 (conflict /
|
|
1616
|
+
* wrong scope). Distinguishes "the user typo'd the workstream" from
|
|
1617
|
+
* "the agent doesn't exist anywhere" (which surfaces as
|
|
1618
|
+
* `AgentNotFoundError`).
|
|
1619
|
+
*/
|
|
1620
|
+
declare class AgentNotInWorkstreamError extends Error implements HasNextSteps {
|
|
1621
|
+
readonly agentName: string;
|
|
1622
|
+
readonly expectedWorkstream: string;
|
|
1623
|
+
readonly actualWorkstream: string;
|
|
1624
|
+
readonly name = "AgentNotInWorkstreamError";
|
|
1625
|
+
constructor(agentName: string, expectedWorkstream: string, actualWorkstream: string);
|
|
1626
|
+
errorNextSteps(): NextStep[];
|
|
1627
|
+
}
|
|
1628
|
+
/**
|
|
1629
|
+
* Thrown when an agent's pane is created and titled successfully but the
|
|
1630
|
+
* spawned process exits within the liveness window (default 1500ms;
|
|
1631
|
+
* configurable via `MU_SPAWN_LIVENESS_MS`). The most common cause is the
|
|
1632
|
+
* underlying CLI failing fast: a wrapper CLI blocking on a single-instance
|
|
1633
|
+
* lock, `claude` rejecting an invalid API key, etc. The agent's last
|
|
1634
|
+
* scrollback (when capturable) is attached to help diagnose.
|
|
1635
|
+
*/
|
|
1636
|
+
declare class AgentDiedOnSpawnError extends Error implements HasNextSteps {
|
|
1637
|
+
readonly agentName: string;
|
|
1638
|
+
readonly paneId: string;
|
|
1639
|
+
readonly scrollback: string | undefined;
|
|
1640
|
+
/** The command the pane ran; an `ssh ...` command gets remote hints. */
|
|
1641
|
+
readonly command?: string | undefined;
|
|
1642
|
+
readonly name = "AgentDiedOnSpawnError";
|
|
1643
|
+
/** The spawned command is an ssh hop: remote causes, not wrapper locks. */
|
|
1644
|
+
readonly remote: boolean;
|
|
1645
|
+
constructor(agentName: string, paneId: string, scrollback: string | undefined,
|
|
1646
|
+
/** The command the pane ran; an `ssh ...` command gets remote hints. */
|
|
1647
|
+
command?: string | undefined);
|
|
1648
|
+
errorNextSteps(): NextStep[];
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Thrown when an agent's pane is alive AND staying alive after the
|
|
1652
|
+
* liveness window, but its first burst of output matches a known
|
|
1653
|
+
* provider-startup-failure pattern (missing API key, auth rejected, …).
|
|
1654
|
+
* Source: feedback ws task `agent_spawn_model_auth_failure_counts_as_live`.
|
|
1655
|
+
* Live dogfood report: `pi-meta --no-solo --model sonnet:high` printed
|
|
1656
|
+
* `Error: No API key found for amazon-bedrock` and parked at a prompt.
|
|
1657
|
+
* The pane stayed alive (1.5s liveness check passed) but the worker
|
|
1658
|
+
* could never do work — the orchestrator only discovered this when
|
|
1659
|
+
* `mu task wait` stalled minutes later.
|
|
1660
|
+
*
|
|
1661
|
+
* Distinct from `AgentDiedOnSpawnError`:
|
|
1662
|
+
* - `AgentDiedOnSpawnError` → pane vanished within the liveness window
|
|
1663
|
+
* (CLI exited fast).
|
|
1664
|
+
* - `AgentSpawnStartupError` → pane alive, but the captured scrollback
|
|
1665
|
+
* tail contains a curated provider-auth-failure pattern.
|
|
1666
|
+
* The two carry different remediation hints (CLI override vs. fix the
|
|
1667
|
+
* env var), so they're separate types instead of one with a flag.
|
|
1668
|
+
*
|
|
1669
|
+
* The pattern list is curated and short to keep false-positive risk low
|
|
1670
|
+
* — the scan only looks at the last ~30 lines of the 50-line capture
|
|
1671
|
+
* taken right after the liveness sleep, so matches naturally come from
|
|
1672
|
+
* the CLI's first ~1.5s of output (not arbitrary later prompts the
|
|
1673
|
+
* agent might type into).
|
|
1674
|
+
*/
|
|
1675
|
+
declare class AgentSpawnStartupError extends Error implements HasNextSteps {
|
|
1676
|
+
readonly agentName: string;
|
|
1677
|
+
readonly paneId: string;
|
|
1678
|
+
/** The single scrollback line that matched a known startup-error
|
|
1679
|
+
* pattern. Surfaced verbatim in the message so the operator sees
|
|
1680
|
+
* what mu saw. */
|
|
1681
|
+
readonly matchedLine: string;
|
|
1682
|
+
/** Full captured scrollback (tail-trimmed already by
|
|
1683
|
+
* awaitSpawnLiveness). Attached to the message for context. */
|
|
1684
|
+
readonly scrollback: string;
|
|
1685
|
+
readonly name = "AgentSpawnStartupError";
|
|
1686
|
+
constructor(agentName: string, paneId: string,
|
|
1687
|
+
/** The single scrollback line that matched a known startup-error
|
|
1688
|
+
* pattern. Surfaced verbatim in the message so the operator sees
|
|
1689
|
+
* what mu saw. */
|
|
1690
|
+
matchedLine: string,
|
|
1691
|
+
/** Full captured scrollback (tail-trimmed already by
|
|
1692
|
+
* awaitSpawnLiveness). Attached to the message for context. */
|
|
1693
|
+
scrollback: string);
|
|
1694
|
+
errorNextSteps(): NextStep[];
|
|
1695
|
+
}
|
|
1696
|
+
/**
|
|
1697
|
+
* Thrown when `closeAgent` is called on an agent that has an associated
|
|
1698
|
+
* workspace AND the caller didn't explicitly opt into discarding it.
|
|
1699
|
+
*
|
|
1700
|
+
* Background: the FK on `vcs_workspaces.agent` cascades on agent
|
|
1701
|
+
* delete, so a naive `closeAgent` drops the workspace registry row
|
|
1702
|
+
* but leaves the on-disk dir orphaned (mu can't see it via
|
|
1703
|
+
* `mu workspace list / free / path` afterwards). Surfaced during
|
|
1704
|
+
* the multi-agent dogfood teardown when three workspaces went
|
|
1705
|
+
* orphaned silently.
|
|
1706
|
+
*
|
|
1707
|
+
* The fix: refuse close if a workspace exists; force the caller to
|
|
1708
|
+
* decide. Two actionable resolutions:
|
|
1709
|
+
* - `mu workspace free <agent>` first, then close cleanly.
|
|
1710
|
+
* - `mu agent close <agent> --discard-workspace` to free the
|
|
1711
|
+
* workspace AND close the agent in one shot (lossy: pending
|
|
1712
|
+
* changes in the workspace are gone).
|
|
1713
|
+
*
|
|
1714
|
+
* Maps to exit code 4 (conflict) via the cli.ts handler.
|
|
1715
|
+
*/
|
|
1716
|
+
declare class WorkspacePreservedError extends Error implements HasNextSteps {
|
|
1717
|
+
readonly agentName: string;
|
|
1718
|
+
readonly workspacePath: string;
|
|
1719
|
+
readonly name = "WorkspacePreservedError";
|
|
1720
|
+
constructor(agentName: string, workspacePath: string);
|
|
1721
|
+
errorNextSteps(): NextStep[];
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* The agent's pane and pi are up, but nothing answers on its control
|
|
1725
|
+
* socket (`MU_CTL_SOCK`): the mu pi extension is not loaded, or, for a
|
|
1726
|
+
* remote agent, the ssh command lacks the `-L` forward. Spawn does not
|
|
1727
|
+
* throw it — the agent is usable by hand — but prints it as a warning;
|
|
1728
|
+
* verbs that need the socket throw it.
|
|
1729
|
+
*/
|
|
1730
|
+
declare class AgentCtlUnreachableError extends Error implements HasNextSteps {
|
|
1731
|
+
readonly agentName: string;
|
|
1732
|
+
readonly workstream: string;
|
|
1733
|
+
readonly socket: string;
|
|
1734
|
+
readonly kind: "missing" | "refused";
|
|
1735
|
+
readonly name = "AgentCtlUnreachableError";
|
|
1736
|
+
constructor(agentName: string, workstream: string, socket: string, kind: "missing" | "refused");
|
|
1737
|
+
errorNextSteps(): NextStep[];
|
|
1738
|
+
}
|
|
1665
1739
|
/**
|
|
1666
|
-
*
|
|
1667
|
-
*
|
|
1668
|
-
* pi-alt` makes `--cli pi` actually exec `pi-alt`). Falls back to the cli
|
|
1669
|
-
* name itself, which is what users expect when their `pi` binary is on
|
|
1670
|
-
* `$PATH` under that exact name.
|
|
1671
|
-
*
|
|
1672
|
-
* Used by `spawnAgent` to pick the spawned command, and by reconcile's
|
|
1673
|
-
* orphan detector so externally-spawned panes running the resolved binary
|
|
1674
|
-
* are still recognised as agents.
|
|
1740
|
+
* `mu agent abort` on an agent that does not run pi: there is no control
|
|
1741
|
+
* socket to carry the abort, and mu does not silently signal the pane.
|
|
1675
1742
|
*/
|
|
1676
|
-
declare
|
|
1743
|
+
declare class AgentAbortNeedsCtlError extends Error implements HasNextSteps {
|
|
1744
|
+
readonly agentName: string;
|
|
1745
|
+
readonly workstream: string;
|
|
1746
|
+
readonly cli: string;
|
|
1747
|
+
readonly name = "AgentAbortNeedsCtlError";
|
|
1748
|
+
constructor(agentName: string, workstream: string, cli: string);
|
|
1749
|
+
errorNextSteps(): NextStep[];
|
|
1750
|
+
}
|
|
1751
|
+
/** The abort was delivered but pi did not settle within the timeout. */
|
|
1752
|
+
declare class AgentAbortTimeoutError extends Error implements HasNextSteps {
|
|
1753
|
+
readonly agentName: string;
|
|
1754
|
+
readonly workstream: string;
|
|
1755
|
+
readonly timeoutMs: number;
|
|
1756
|
+
readonly name = "AgentAbortTimeoutError";
|
|
1757
|
+
constructor(agentName: string, workstream: string, timeoutMs: number);
|
|
1758
|
+
errorNextSteps(): NextStep[];
|
|
1759
|
+
}
|
|
1677
1760
|
/**
|
|
1678
|
-
*
|
|
1679
|
-
*
|
|
1680
|
-
* (env var names can't contain `-`); this matches the operator-aliases
|
|
1681
|
-
* convention documented in the mu skill (e.g. `--cli pi-meta` →
|
|
1682
|
-
* `MU_PI_META_COMMAND`).
|
|
1761
|
+
* `mu agent send --fresh` on an agent without a control socket (non-pi
|
|
1762
|
+
* CLI, or forced `--via mux`): there is no one-operation new session.
|
|
1683
1763
|
*/
|
|
1684
|
-
declare
|
|
1764
|
+
declare class AgentFreshNeedsCtlError extends Error implements HasNextSteps {
|
|
1765
|
+
readonly agentName: string;
|
|
1766
|
+
readonly workstream: string;
|
|
1767
|
+
readonly cli: string;
|
|
1768
|
+
readonly name = "AgentFreshNeedsCtlError";
|
|
1769
|
+
constructor(agentName: string, workstream: string, cli: string);
|
|
1770
|
+
errorNextSteps(): NextStep[];
|
|
1771
|
+
}
|
|
1772
|
+
/** `send --fresh` refused: pi is mid-turn, and a fresh session would abandon it. */
|
|
1773
|
+
declare class AgentBusyError extends Error implements HasNextSteps {
|
|
1774
|
+
readonly agentName: string;
|
|
1775
|
+
readonly workstream: string;
|
|
1776
|
+
readonly name = "AgentBusyError";
|
|
1777
|
+
constructor(agentName: string, workstream: string);
|
|
1778
|
+
errorNextSteps(): NextStep[];
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
/** The signal set kick supports. SIGINT is graceful (matches Ctrl-C
|
|
1782
|
+
* semantics — what the operator probably wanted in the first place);
|
|
1783
|
+
* SIGTERM is the polite escalation; SIGKILL is the unblockable
|
|
1784
|
+
* hammer. We deliberately don't expose arbitrary signals — the
|
|
1785
|
+
* three above are the actionable ones for "interrupt a wedged
|
|
1786
|
+
* foreground tool subprocess." */
|
|
1787
|
+
type KickSignal = "SIGINT" | "SIGTERM" | "SIGKILL";
|
|
1788
|
+
declare function isKickSignal(s: string): s is KickSignal;
|
|
1685
1789
|
/**
|
|
1686
|
-
*
|
|
1687
|
-
*
|
|
1688
|
-
*
|
|
1689
|
-
*
|
|
1690
|
-
*
|
|
1691
|
-
*
|
|
1790
|
+
* Thrown when the foreground pgid lookup on a pane's TTY yields
|
|
1791
|
+
* either no rows at all (the pane is sitting at an idle shell with
|
|
1792
|
+
* no foreground job) or only the wrapping shell itself (the LLM CLI
|
|
1793
|
+
* — pi/claude/codex — is the foreground; signalling it would close
|
|
1794
|
+
* the agent, which is what `mu agent close` is for).
|
|
1795
|
+
*
|
|
1796
|
+
* Maps to the generic exit code 1 in handle.ts (this is a
|
|
1797
|
+
* runtime-state condition, not a typed not-found / conflict).
|
|
1692
1798
|
*/
|
|
1693
|
-
declare
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1799
|
+
declare class NoForegroundProcessError extends Error implements HasNextSteps {
|
|
1800
|
+
readonly agentName: string;
|
|
1801
|
+
readonly tty: string;
|
|
1802
|
+
readonly reason: "no-foreground" | "shell-only";
|
|
1803
|
+
readonly name = "NoForegroundProcessError";
|
|
1804
|
+
constructor(agentName: string, tty: string, reason: "no-foreground" | "shell-only");
|
|
1805
|
+
errorNextSteps(): NextStep[];
|
|
1806
|
+
}
|
|
1807
|
+
interface KickProcessExecResult {
|
|
1808
|
+
stdout: string;
|
|
1809
|
+
stderr: string;
|
|
1810
|
+
exitCode: number | null;
|
|
1811
|
+
}
|
|
1812
|
+
type KickProcessExecutor = (cmd: string, args: readonly string[]) => Promise<KickProcessExecResult>;
|
|
1813
|
+
/** Install a custom executor (for tests). Returns the previous one so
|
|
1814
|
+
* tests can restore cleanly. */
|
|
1815
|
+
declare function setKickProcessExecutor(executor: KickProcessExecutor): KickProcessExecutor;
|
|
1816
|
+
/** Restore the real executor. */
|
|
1817
|
+
declare function resetKickProcessExecutor(): void;
|
|
1818
|
+
interface PsRow {
|
|
1819
|
+
pid: number;
|
|
1820
|
+
pgid: number;
|
|
1821
|
+
/** ps's `stat` (or `state`) field. The presence of `+` means
|
|
1822
|
+
* "foreground process group on its controlling tty". */
|
|
1823
|
+
stat: string;
|
|
1824
|
+
/** Process command (just the comm; truncated, used for diagnostics). */
|
|
1825
|
+
comm: string;
|
|
1705
1826
|
}
|
|
1706
|
-
type CommandResolver = (command: string) => Promise<CommandResolutionResult>;
|
|
1707
|
-
/** Override the PATH resolver. Tests use this to simulate "binary
|
|
1708
|
-
* absent" / "binary present" without depending on what's actually
|
|
1709
|
-
* installed. Production callers should never touch this. */
|
|
1710
|
-
declare function setCommandResolverForTests(resolver: CommandResolver): void;
|
|
1711
|
-
/** Restore the default PATH resolver. */
|
|
1712
|
-
declare function resetCommandResolverForTests(): void;
|
|
1713
1827
|
/**
|
|
1714
|
-
*
|
|
1715
|
-
*
|
|
1716
|
-
*
|
|
1828
|
+
* Parse `ps -t <tty> -o pid=,pgid=,stat=,comm=` output. Each non-blank
|
|
1829
|
+
* line is one process: four whitespace-separated fields. Defensive
|
|
1830
|
+
* about leading whitespace and command names with embedded spaces
|
|
1831
|
+
* (the comm is the LAST field — join the tail).
|
|
1717
1832
|
*/
|
|
1718
|
-
declare function
|
|
1719
|
-
|
|
1720
|
-
|
|
1833
|
+
declare function parsePsTtyOutput(output: string): PsRow[];
|
|
1834
|
+
/**
|
|
1835
|
+
* Resolve the foreground process group id for a TTY device path. The
|
|
1836
|
+
* canonical signal `ps`'s `stat` field uses is `+` (BSD/Darwin AND
|
|
1837
|
+
* Linux procps). We pick the first row whose stat contains `+`; its
|
|
1838
|
+
* `pgid` is the foreground pgid of that controlling terminal.
|
|
1839
|
+
*
|
|
1840
|
+
* Returns:
|
|
1841
|
+
* - `{ kind: "ok", pgid, fgRow }` on success
|
|
1842
|
+
* - `{ kind: "no-foreground" }` when no row carries `+` AND there
|
|
1843
|
+
* are no candidate rows at all
|
|
1844
|
+
* - `{ kind: "shell-only", pgid, fgRow }` when the foreground pgid
|
|
1845
|
+
* resolves to a shell whose comm is the agent's wrapping CLI
|
|
1846
|
+
* (caller decides whether to refuse — kick refuses)
|
|
1847
|
+
*
|
|
1848
|
+
* The wrapping-CLI guard is intentionally narrow: we only refuse
|
|
1849
|
+
* when the foreground process command matches one of the known
|
|
1850
|
+
* pi/claude/codex/zsh/bash shapes. Anything else (a `find`, a
|
|
1851
|
+
* `cargo build`, a `python script.py`) is exactly what we want to
|
|
1852
|
+
* signal — that's the unbounded-tool case the verb was built for.
|
|
1853
|
+
*/
|
|
1854
|
+
interface ForegroundLookup {
|
|
1855
|
+
kind: "ok" | "shell-only" | "no-foreground";
|
|
1856
|
+
pgid?: number;
|
|
1857
|
+
fgRow?: PsRow;
|
|
1858
|
+
/** All rows ps returned for the tty, for diagnostics / tests. */
|
|
1859
|
+
rows: PsRow[];
|
|
1860
|
+
}
|
|
1861
|
+
declare function foregroundPgid(tty: string): Promise<ForegroundLookup>;
|
|
1862
|
+
interface KickAgentOptions {
|
|
1721
1863
|
workstream: string;
|
|
1722
|
-
/** Defaults to
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
/**
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
* When `workspace: true` is passed, this is ignored — the workspace
|
|
1737
|
-
* path is used instead. */
|
|
1738
|
-
cwd?: string;
|
|
1739
|
-
/** Override the tmux session name. Defaults to `mu-<workstream>`. */
|
|
1740
|
-
tmuxSession?: string;
|
|
1741
|
-
/** Auto-create a VCS workspace for this agent before spawning the
|
|
1742
|
-
* pane and use the workspace path as cwd. Backend defaults to
|
|
1743
|
-
* detection (jj > sl > git > none). */
|
|
1744
|
-
workspace?: boolean;
|
|
1745
|
-
/** Force a specific VCS backend (only meaningful with `workspace: true`). */
|
|
1746
|
-
workspaceBackend?: VcsBackendName;
|
|
1747
|
-
/** Optional ref to base the workspace on (only meaningful with
|
|
1748
|
-
* `workspace: true`). Backend-specific. */
|
|
1749
|
-
workspaceFrom?: string;
|
|
1750
|
-
/** Project root the workspace branches from (only meaningful with
|
|
1751
|
-
* `workspace: true`). Defaults to `process.cwd()`. */
|
|
1752
|
-
workspaceProjectRoot?: string;
|
|
1864
|
+
/** Defaults to SIGINT (matches Ctrl-C semantics). */
|
|
1865
|
+
signal?: KickSignal;
|
|
1866
|
+
}
|
|
1867
|
+
interface KickAgentResult {
|
|
1868
|
+
agentName: string;
|
|
1869
|
+
paneId: string;
|
|
1870
|
+
/** TTY device path the foreground pgid was resolved against. */
|
|
1871
|
+
tty: string;
|
|
1872
|
+
/** The pgid we signalled. */
|
|
1873
|
+
signaledPgid: number;
|
|
1874
|
+
signal: KickSignal;
|
|
1875
|
+
/** The comm of the foreground process at the time of signal — useful
|
|
1876
|
+
* diagnostic in the event log ("we kicked a `find`, not a `cargo`"). */
|
|
1877
|
+
foregroundComm: string;
|
|
1753
1878
|
}
|
|
1754
1879
|
/**
|
|
1755
|
-
*
|
|
1880
|
+
* Send `signal` to the foreground process group of an agent's pane
|
|
1881
|
+
* TTY. Default signal is SIGINT.
|
|
1756
1882
|
*
|
|
1757
|
-
*
|
|
1758
|
-
*
|
|
1759
|
-
*
|
|
1760
|
-
*
|
|
1761
|
-
*
|
|
1762
|
-
* 4. setPaneTitle + enableMuPaneBordersForPane.
|
|
1763
|
-
* 5. finalizeAgentRow() — patch placeholder pane_id to real (workspace
|
|
1764
|
-
* path), or insert a fresh agent row (no-workspace path).
|
|
1765
|
-
* 6. awaitSpawnLiveness().
|
|
1883
|
+
* Errors:
|
|
1884
|
+
* - `AgentNotFoundError` — the agent doesn't exist in this workstream.
|
|
1885
|
+
* - `PaneNotFoundError` (from paneTTY) — the agent's pane has vanished.
|
|
1886
|
+
* - `NoForegroundProcessError` — pane has no foreground job, OR the
|
|
1887
|
+
* foreground is the wrapping CLI itself (refuse; use `mu agent close`).
|
|
1766
1888
|
*
|
|
1767
|
-
*
|
|
1768
|
-
*
|
|
1889
|
+
* Emits an `agent kick <name> (signal=..., pgid=..., comm=...)` event
|
|
1890
|
+
* on success.
|
|
1769
1891
|
*/
|
|
1770
|
-
declare function
|
|
1892
|
+
declare function kickAgent(db: Db, name: string, opts: KickAgentOptions): Promise<KickAgentResult>;
|
|
1893
|
+
|
|
1894
|
+
type Transport = "ctl" | "mux";
|
|
1895
|
+
type SendResult = {
|
|
1896
|
+
transport: Transport;
|
|
1897
|
+
state?: CtlState;
|
|
1898
|
+
};
|
|
1899
|
+
type TransportSendOptions = SendOptions & {
|
|
1900
|
+
/** How a busy pi queues the message. Default followUp. ctl only. */
|
|
1901
|
+
mode?: "steer" | "followUp";
|
|
1902
|
+
/** Force a transport instead of choosing by agent and text. */
|
|
1903
|
+
via?: Transport;
|
|
1904
|
+
/** Control socket path. Default: agentCtlSocket(db, agent). */
|
|
1905
|
+
socket?: string;
|
|
1906
|
+
/** Start a new pi session and send the text into it, as one ctl op. */
|
|
1907
|
+
fresh?: boolean;
|
|
1908
|
+
/** With fresh: abandon a running turn instead of refusing. */
|
|
1909
|
+
force?: boolean;
|
|
1910
|
+
};
|
|
1771
1911
|
/**
|
|
1772
|
-
*
|
|
1773
|
-
*
|
|
1774
|
-
*
|
|
1775
|
-
|
|
1776
|
-
|
|
1912
|
+
* True when the agent runs pi, so sends go through its control socket.
|
|
1913
|
+
* The cli key decides when it names pi (or MU_<KEY>_COMMAND here runs
|
|
1914
|
+
* pi). Otherwise the agent's own socket file decides: spawn removes any
|
|
1915
|
+
* stale file before the pane starts, so a file at the derived path was
|
|
1916
|
+
* bound by this agent's extension (or its ssh forward). That covers
|
|
1917
|
+
* `--cli helper --command "pi-meta ..."`, whose command is not stored,
|
|
1918
|
+
* without a schema change. `sock` defaults to the derived path; pass
|
|
1919
|
+
* agentCtlSocket(db, agent) when a DB is at hand.
|
|
1920
|
+
*/
|
|
1921
|
+
declare function expectsCtl(agent: Pick<AgentRow, "cli" | "name" | "workstreamName">, sock?: string): boolean;
|
|
1922
|
+
declare function sendViaTransport(agent: AgentRow, text: string, opts: TransportSendOptions & {
|
|
1923
|
+
socket: string;
|
|
1924
|
+
}): Promise<SendResult>;
|
|
1777
1925
|
|
|
1778
1926
|
interface AgentRow {
|
|
1779
1927
|
name: string;
|
|
@@ -1792,6 +1940,8 @@ interface AgentRow {
|
|
|
1792
1940
|
interface LiveAgent extends AgentRow {
|
|
1793
1941
|
state: RuntimeState;
|
|
1794
1942
|
source: StateSource;
|
|
1943
|
+
/** Control-socket link: ok / missing / refused for pi agents, n/a otherwise. */
|
|
1944
|
+
ctl?: CtlLink;
|
|
1795
1945
|
/** ISO 8601 time when the source entered this state. */
|
|
1796
1946
|
since: string | null;
|
|
1797
1947
|
reason?: string;
|
|
@@ -1846,12 +1996,14 @@ declare function refreshAgentTitle(db: Db, agentName: string, workstream: string
|
|
|
1846
1996
|
declare function deleteAgent(db: Db, name: string, workstream: string): boolean;
|
|
1847
1997
|
declare function isValidAgentName(name: string): boolean;
|
|
1848
1998
|
/**
|
|
1849
|
-
* Send
|
|
1850
|
-
*
|
|
1999
|
+
* Send text to an agent and submit it. A pi agent gets it through its
|
|
2000
|
+
* control socket (AgentCtlUnreachableError when that does not answer —
|
|
2001
|
+
* never a silent paste); a non-pi CLI, a slash command, or `via: "mux"`
|
|
2002
|
+
* goes through the mux paste path. See src/agents/transport.ts.
|
|
1851
2003
|
*/
|
|
1852
|
-
declare function sendToAgent(db: Db, name: string, text: string, opts:
|
|
2004
|
+
declare function sendToAgent(db: Db, name: string, text: string, opts: TransportSendOptions & {
|
|
1853
2005
|
workstream: string;
|
|
1854
|
-
}): Promise<
|
|
2006
|
+
}): Promise<SendResult>;
|
|
1855
2007
|
/**
|
|
1856
2008
|
* Read scrollback from an agent's pane. With no options, returns the full
|
|
1857
2009
|
* scrollback (`-S - -E -`); with `lines: N`, returns only the last N lines.
|
|
@@ -3348,6 +3500,56 @@ declare function loadFullDag(db: Db, workstream: string, opts?: LoadFullDagOptio
|
|
|
3348
3500
|
declare function renderForest(roots: readonly TaskRow[], edges: ReadonlyMap<string, readonly string[]>, statusFn: TaskStatusLabelFn, tasksByName?: ReadonlyMap<string, TaskRow>, opts?: RenderTreeOptions): string;
|
|
3349
3501
|
declare function renderTaskTree(db: Db, workstream: string, root: TaskRow, direction: "blockers" | "dependents", statusFn: TaskStatusLabelFn, opts?: RenderTreeOptions): string;
|
|
3350
3502
|
|
|
3503
|
+
/**
|
|
3504
|
+
* Identifies a generated shim on its own line, so re-linking (and
|
|
3505
|
+
* `inspectLinks`) can tell it from an older inlined copy without
|
|
3506
|
+
* depending on the import statement's exact shape.
|
|
3507
|
+
*/
|
|
3508
|
+
declare const MU_SHIM_MARKER = "// mu:shim";
|
|
3509
|
+
type LinkState = "ok" | "missing" | "stale-copy" | "foreign" | "dangling";
|
|
3510
|
+
interface LinkStatus {
|
|
3511
|
+
path: string;
|
|
3512
|
+
state: LinkState;
|
|
3513
|
+
target?: string;
|
|
3514
|
+
}
|
|
3515
|
+
interface LinkOptions {
|
|
3516
|
+
/** Root under which `.pi/` and `.agents/` live. Default `MU_PI_HOME ?? homedir()`. */
|
|
3517
|
+
home?: string;
|
|
3518
|
+
}
|
|
3519
|
+
/** Raised when the destination holds something mu did not put there
|
|
3520
|
+
* (a real directory, or a symlink to another checkout without
|
|
3521
|
+
* `--force`). mu never deletes user files to make room. */
|
|
3522
|
+
declare class LinkConflictError extends Error implements HasNextSteps {
|
|
3523
|
+
readonly path: string;
|
|
3524
|
+
readonly reason: "not-a-symlink" | "foreign-symlink";
|
|
3525
|
+
readonly current?: string | undefined;
|
|
3526
|
+
constructor(path: string, reason: "not-a-symlink" | "foreign-symlink", current?: string | undefined);
|
|
3527
|
+
errorNextSteps(): NextStep[];
|
|
3528
|
+
}
|
|
3529
|
+
/** Install the extension shim (or, with `copy`, an inlined copy pinned
|
|
3530
|
+
* to this version). `replacedCopy` is true when an existing file without
|
|
3531
|
+
* the shim marker was overwritten. */
|
|
3532
|
+
declare function linkPi(opts?: LinkOptions & {
|
|
3533
|
+
copy?: boolean;
|
|
3534
|
+
}): {
|
|
3535
|
+
path: string;
|
|
3536
|
+
replacedCopy: boolean;
|
|
3537
|
+
};
|
|
3538
|
+
/** Symlink `<home>/.agents/skills/mu` to the package's `skills/mu`.
|
|
3539
|
+
* `previous` is the old link target when one was replaced. */
|
|
3540
|
+
declare function linkSkill(opts?: LinkOptions & {
|
|
3541
|
+
force?: boolean;
|
|
3542
|
+
}): {
|
|
3543
|
+
path: string;
|
|
3544
|
+
target: string;
|
|
3545
|
+
previous?: string;
|
|
3546
|
+
};
|
|
3547
|
+
/** Report the state of both installs without changing anything. */
|
|
3548
|
+
declare function inspectLinks(opts?: LinkOptions): {
|
|
3549
|
+
extension: LinkStatus;
|
|
3550
|
+
skill: LinkStatus;
|
|
3551
|
+
};
|
|
3552
|
+
|
|
3351
3553
|
type LogKind = "message" | "event" | "broadcast" | string;
|
|
3352
3554
|
interface LogRow {
|
|
3353
3555
|
/** Monotonic AUTOINCREMENT id. Use as the cursor for `--since`. */
|
|
@@ -4979,4 +5181,4 @@ declare function summarizeWorkstream(db: Db, opts: WorkstreamOptions): Promise<W
|
|
|
4979
5181
|
*/
|
|
4980
5182
|
declare function teardownWorkstream(db: Db, opts: TeardownWorkstreamOptions): Promise<TeardownResult>;
|
|
4981
5183
|
|
|
4982
|
-
export { AGENT_STATE_GLYPH, type AddNoteOptions, type AddTaskOptions, type AdoptAgentOptions, type AdoptAgentResult, AgentDiedOnSpawnError, AgentExistsError, AgentNotFoundError, AgentNotInWorkstreamError, type AgentRow, AgentSpawnCliNotFoundError, AgentSpawnStartupError, type AmbientOptions, type AmbientResult, type AppendLogOptions, type ApplyResult, type BlockEdgeResult, CAPTURE_TRIGGER_DDL, CURRENT_SCHEMA_VERSION, type CaptureDb, type CaptureIntent, type CaptureOptions, type CaseCollision, type CheapDriftReport, type ClaimResult, type ClaimTaskOptions, ClaimerNotRegisteredError, type CloseAgentOptions, type CloseAgentResult, type CloseSubstate, type CloseTaskResult, type CommandResolutionResult, type CommandResolver, CrossWorkstreamEdgeError, CycleError, DEFAULT_SUBSTATE, DRIFT_REPORT_CAP, type Db, type DeleteTaskResult, type DoctorCheck, type DoctorStatus, type DoctorSummary, DriftDetectedError, type DriftRecord, type DriftReport, EXPECTED_TABLES, type EvidenceOption, type FileLockOptions, type FleetHazard, type FlushResult, type FsProbe, type FullDag, GLYPH, type GroupSummary, type HazardSeverity, type Hlc, HlcOverflowError, HlcParseError, HomeDirAsProjectRootError, type IdFromTitleResult, type IngestFromDbResult, type IngestResult, type InsertAgentInput, InvalidSubstateError, type InverseOp, KNOWN_INTENTS, KNOWN_VERBS, type KickAgentOptions, type KickAgentResult, type KickProcessExecutor, type KickSignal, type KnownIntent, type ListLiveAgentsOptions, type ListLogsOptions, type ListNotesOptions, type ListReadyOptions, type ListTasksOptions, type LiveAgent, type LiveAgentsView, type LoadFullDagOptions, type LoadWorkstreamSnapshotOptions, type LocalIntent, type LogKind, type LogRow, MACHINE_LOCAL_ENTITIES, MACHINE_LOCAL_TABLES, MachineIdentityMissingError, type MachineLocalEntity, type MachineLocalLoss, type MachineLocalTable, type MuxBackend, type MuxBackendName, MuxError, type MuxPane, type MuxPaneStatus, type MuxSession, type MuxWindow, type NewSessionOptions, type NewWindowOptions, NoForegroundProcessError, NoMultiplexerError, NothingToUndoError, OP_CTX_DDL, type Op, type OpContext, OpEntityNotSyncedError, OpKeyMalformedError, type OpenDbOptions, type OwnedTasksSummary, PANE_ID_RE, PEER_SHORT_LEN, PEER_STALE_MS, PORTABLE_TABLES, PaneNotFoundError, type ParkTaskOptions, type PeerSegment, type PeerStatus, type PortableTable, type RebuildOptions, type RebuildReport, RebuildTargetExistsError, RebuildTargetIsSourceError, type ReconcileMode, type ReconcileOptions, type ReconcileReport, type ReleaseResult, type ReleaseTaskOptions, type RemoveBlockEdgeResult, type RenderableOp, type RenderedOp, type ReparentTaskResult, type RoiBucket, type RuntimeState, SEGMENT_FORMAT_VERSION, SYNCED_ENTITIES, SchemaTooOldError, type SegmentDefect, type SegmentDefectKind, type SegmentLine, type SegmentManifest, type SendOptions, type SendWarning, type SetStatusOptions, type SetStatusResult, type SlugifyResult, type SpawnAgentOptions, type SplitWindowOptions, type StateReading, type StateSource, type StrandedWorkspaceOrphan, SubstateReasonRequiredError, type SyncPassResult, SyncPeerNotFoundError, SyncPeerRefAmbiguousError, SyncSourceNotFoundError, type SyncedEntity, TASK_STATUSES, TASK_STATUS_LIST, TASK_SUBSTATES, TASK_SUBSTATE_ROWS, TaskAlreadyOwnedError, type TaskEdgeWithStatus, type TaskEdges, type TaskEdgesWithStatus, TaskExistsError, TaskNotFoundError, TaskNotInWorkstreamError, type TaskNoteRow, type TaskPair, TaskParkStateError, TaskParkedError, type TaskRow, type TaskStatus, type TaskSubstate, type TaskWaitOptions, type TaskWaitRef, type TaskWaitResult, type TaskWaitTaskState, type TeardownResult, TmuxError, type TmuxExecResult, type TmuxExecutor, type TmuxPane, type TmuxSession, type TmuxWindow, type Track, UNKNOWN_REASON, UndoGroupNotFoundError, type UndoOptions, type UndoPlan, type UndoResult, UndoSupersededError, type UpdateTaskOptions, type UpdateTaskResult, type VcsBackend, type VcsBackendName, WORKSPACE_STALE_THRESHOLD, WorkspaceExistsError, type WorkspaceFailure, WorkspaceNotFoundError, type WorkspaceOrphan, WorkspacePathNotEmptyError, WorkspacePreservedError, type WorkspaceRow, type WorkspaceStaleness, WorkstreamExistsError, WorkstreamNameInvalidError, type WorkstreamOptions, type WorkstreamSnapshot, type WorkstreamSnapshotSlowFields, type WorkstreamSummary, activeMux, addBlockEdge, addNote, addTask, adoptAgent, agentKey, agentStateGlyph, agentStateHistogram, ambientFlush, ambientIngest, ambientSyncPass, appendLog, applyIncomingOp, applyOp, applyOps, assertValidPaneId, awaitPaneQuiescence, backendByName, capturePane, checkCaseCollisions, checkCheapDriftInvariant, checkCommandResolvable, checkDbInsideSyncDir, checkDrift, checkFleetHazards, checkNetworkMount, claimTask, classifyFsType, closeAgent, closeTask, compareHlc, composeAgentTitle, countProblems, createWorkspace, currentAgentName, currentOpContext, currentPaneTitle, decorateWithDirty, decorateWithStaleness, defaultDbPath, defaultSendDelayMs, defaultSendReadinessMs, defaultSpawnLivenessMs, defaultStateDir, deleteAgent, deleteTask, detectBackend, detectMux, discoverPeers, driftRemediation, emitEvent, ensureWorkstream, envVarNameForCli, findCaseCollisions, flushSegment, foregroundPgid, formatDriftRecord, formatHlc, formatPair, freeWorkspace, getAgent, getAgentByPane, getParallelTracks, getPrerequisites, getTask, getTaskEdges, getTaskEdgesWithStatus, getWaitPollCount, getWatermark, getWorkspaceForAgent, getWorkspaceStaleness, gitBackend, hasWorkMarker, idFromTitle, idFromTitleVerbose, ingestFromDb, ingestSegment, insertAgent, installCapture, isKickSignal, isPathInside, isTaskStatus, isValidAgentName, isValidPair, isValidPaneId, isValidTaskId, isValidWorkstreamName, isWorkspaceStale, jjBackend, kickAgent, killPane, killSession, latestSeq, listAgents, listAllOrphanWorkspaces, listBlocked, listGoals, listInProgress, listLiveAgents, listLogs, listNotes, listPanes, listPanesInSession, listReady, listRecentClosed, listRecentGroups, listSessions, listTasks, listTasksByOwner, listWindows, listWorkspaceOrphans, listWorkspaces, listWorkstreams, loadDoctorChecks, loadDoctorSummary, loadFullDag, loadWorkstreamSnapshot, loadWorkstreamSnapshotFast, loadWorkstreamSnapshotSlow, localMachineId, locksDir, mapLegacyStatus, mergeSnapshotFastSlow, mostRecentGroup, murmurAvailable, mux, muxByName, newSession, newSessionWithPane, newWindow, nextHlc, noneBackend, opSubject, openDb, openTask, paneExists, paneTTY, parkTask, parseAgentNameFromTitle, parseHlc, parseOpKey, parsePsTtyOutput, peerStatuses, planUndo, priorFieldValue, probeFilesystem, readAgent, readAgentStates, readFileLockMeta, readManifest, rebuildInto, receiveHlc, reconcile, refreshAgentTitle, releaseTask, remediationParagraph, removeBlockEdge, renderForest, renderOp, renderOpLine, renderTaskTree, repairPeer, reparentTask, resetCommandResolverForTests, resetKickProcessExecutor, resetMux, resetSleep, resetTmuxExecutor, resetWaitPollCount, resetWatermark, resolveActorIdentity, resolveCliCommand, resolveCliCommandWithSource, resolveGroupId, resolvePair, resolvePeerRef, roiBucket, segmentLineCount, segmentPath, selectLayout, sendToAgent, sendToPane, sessionExists, setCommandResolverForTests, setKickProcessExecutor, setMuxForTests, setPaneTitle, setSleepForTests, setTaskStatus, setTmuxExecutor, setWaitSleepForTests, setWaitStuckWarnForTests, setWatermark, slBackend, sleep, slugifyTitle, slugifyTitleVerbose, spawnAgent, splitWindow, summarizeOwnedTasks, summarizeWorkstream, syncDir, syncEnabled, syncPass, teardownWorkstream, tmux, tmuxBackend, transportNextSteps, undoGroup, unparkTask, updateTask, verifyAgainstManifest, waitForTasks, withCaptureSuppressed, withFileLock, withOpContext, workspacePath, workspacesRoot, yankCommandForCheck };
|
|
5184
|
+
export { AGENT_STATE_GLYPH, type AbortAgentOptions, type AbortResult, type AddNoteOptions, type AddTaskOptions, type AdoptAgentOptions, type AdoptAgentResult, AgentAbortNeedsCtlError, AgentAbortTimeoutError, AgentBusyError, AgentCtlUnreachableError, AgentDiedOnSpawnError, AgentExistsError, AgentFreshNeedsCtlError, AgentNotFoundError, AgentNotInWorkstreamError, type AgentRow, AgentSpawnCliNotFoundError, AgentSpawnStartupError, type AmbientOptions, type AmbientResult, type AppendLogOptions, type ApplyResult, type BlockEdgeResult, CAPTURE_TRIGGER_DDL, CURRENT_SCHEMA_VERSION, type CaptureDb, type CaptureIntent, type CaptureOptions, type CaseCollision, type CheapDriftReport, type ClaimResult, type ClaimTaskOptions, ClaimerNotRegisteredError, type CloseAgentOptions, type CloseAgentResult, type CloseSubstate, type CloseTaskResult, type CommandResolutionResult, type CommandResolver, CrossWorkstreamEdgeError, type CtlLink, CycleError, DEFAULT_SUBSTATE, DRIFT_REPORT_CAP, type Db, type DeleteTaskResult, type DoctorCheck, type DoctorStatus, type DoctorSummary, DriftDetectedError, type DriftRecord, type DriftReport, EXPECTED_TABLES, type EvidenceOption, type FileLockOptions, type FleetHazard, type FlushResult, type FsProbe, type FullDag, GLYPH, type GroupSummary, type HazardSeverity, type Hlc, HlcOverflowError, HlcParseError, HomeDirAsProjectRootError, type IdFromTitleResult, type IngestFromDbResult, type IngestResult, type InsertAgentInput, InvalidSubstateError, type InverseOp, KNOWN_INTENTS, KNOWN_VERBS, type KickAgentOptions, type KickAgentResult, type KickProcessExecutor, type KickSignal, type KnownIntent, LinkConflictError, type LinkState, type LinkStatus, type ListLiveAgentsOptions, type ListLogsOptions, type ListNotesOptions, type ListReadyOptions, type ListTasksOptions, type LiveAgent, type LiveAgentsView, type LoadFullDagOptions, type LoadWorkstreamSnapshotOptions, type LocalIntent, type LogKind, type LogRow, MACHINE_LOCAL_ENTITIES, MACHINE_LOCAL_TABLES, MU_SHIM_MARKER, MachineIdentityMissingError, type MachineLocalEntity, type MachineLocalLoss, type MachineLocalTable, type MuxBackend, type MuxBackendName, MuxError, type MuxPane, type MuxPaneStatus, type MuxSession, type MuxWindow, type NewSessionOptions, type NewWindowOptions, NoForegroundProcessError, NoMultiplexerError, NothingToUndoError, OP_CTX_DDL, type Op, type OpContext, OpEntityNotSyncedError, OpKeyMalformedError, type OpenDbOptions, type OwnedTasksSummary, PANE_ID_RE, PEER_SHORT_LEN, PEER_STALE_MS, PORTABLE_TABLES, PaneNotFoundError, type ParkTaskOptions, type PeerSegment, type PeerStatus, type PortableTable, type RebuildOptions, type RebuildReport, RebuildTargetExistsError, RebuildTargetIsSourceError, type ReconcileMode, type ReconcileOptions, type ReconcileReport, type ReleaseResult, type ReleaseTaskOptions, type RemoveBlockEdgeResult, type RenderableOp, type RenderedOp, type ReparentTaskResult, type RoiBucket, type RuntimeState, SEGMENT_FORMAT_VERSION, SYNCED_ENTITIES, SchemaTooOldError, type SegmentDefect, type SegmentDefectKind, type SegmentLine, type SegmentManifest, type SendOptions, type SendResult, type SendWarning, type SetStatusOptions, type SetStatusResult, type SlugifyResult, type SpawnAgentOptions, type SplitWindowOptions, type StateReading, type StateSource, type StrandedWorkspaceOrphan, SubstateReasonRequiredError, type SyncPassResult, SyncPeerNotFoundError, SyncPeerRefAmbiguousError, SyncSourceNotFoundError, type SyncedEntity, TASK_STATUSES, TASK_STATUS_LIST, TASK_SUBSTATES, TASK_SUBSTATE_ROWS, TaskAlreadyOwnedError, type TaskEdgeWithStatus, type TaskEdges, type TaskEdgesWithStatus, TaskExistsError, TaskNotFoundError, TaskNotInWorkstreamError, type TaskNoteRow, type TaskPair, TaskParkStateError, TaskParkedError, type TaskRow, type TaskStatus, type TaskSubstate, type TaskWaitOptions, type TaskWaitRef, type TaskWaitResult, type TaskWaitTaskState, type TeardownResult, TmuxError, type TmuxExecResult, type TmuxExecutor, type TmuxPane, type TmuxSession, type TmuxWindow, type Track, type Transport, UNKNOWN_REASON, UndoGroupNotFoundError, type UndoOptions, type UndoPlan, type UndoResult, UndoSupersededError, type UpdateTaskOptions, type UpdateTaskResult, type VcsBackend, type VcsBackendName, WORKSPACE_STALE_THRESHOLD, WorkspaceExistsError, type WorkspaceFailure, WorkspaceNotFoundError, type WorkspaceOrphan, WorkspacePathNotEmptyError, WorkspacePreservedError, type WorkspaceRow, type WorkspaceStaleness, WorkstreamExistsError, WorkstreamNameInvalidError, type WorkstreamOptions, type WorkstreamSnapshot, type WorkstreamSnapshotSlowFields, type WorkstreamSummary, abortAgent, activeMux, addBlockEdge, addNote, addTask, adoptAgent, agentKey, agentStateGlyph, agentStateHistogram, ambientFlush, ambientIngest, ambientSyncPass, appendLog, applyIncomingOp, applyOp, applyOps, assertValidPaneId, awaitPaneQuiescence, backendByName, capturePane, checkCaseCollisions, checkCheapDriftInvariant, checkCommandResolvable, checkDbInsideSyncDir, checkDrift, checkFleetHazards, checkNetworkMount, claimTask, classifyFsType, closeAgent, closeTask, compareHlc, composeAgentTitle, countProblems, createWorkspace, ctlRuntimeState, currentAgentName, currentOpContext, currentPaneTitle, decorateWithDirty, decorateWithStaleness, defaultDbPath, defaultSendDelayMs, defaultSendReadinessMs, defaultSpawnLivenessMs, defaultStateDir, deleteAgent, deleteTask, detectBackend, detectMux, discoverPeers, driftRemediation, emitEvent, ensureWorkstream, envVarNameForCli, expectsCtl, findCaseCollisions, flushSegment, foregroundPgid, formatDriftRecord, formatHlc, formatPair, freeWorkspace, getAgent, getAgentByPane, getParallelTracks, getPrerequisites, getTask, getTaskEdges, getTaskEdgesWithStatus, getWaitPollCount, getWatermark, getWorkspaceForAgent, getWorkspaceStaleness, gitBackend, hasWorkMarker, idFromTitle, idFromTitleVerbose, ingestFromDb, ingestSegment, insertAgent, inspectLinks, installCapture, isKickSignal, isPathInside, isTaskStatus, isValidAgentName, isValidPair, isValidPaneId, isValidTaskId, isValidWorkstreamName, isWorkspaceStale, jjBackend, kickAgent, killPane, killSession, latestSeq, linkPi, linkSkill, listAgents, listAllOrphanWorkspaces, listBlocked, listGoals, listInProgress, listLiveAgents, listLogs, listNotes, listPanes, listPanesInSession, listReady, listRecentClosed, listRecentGroups, listSessions, listTasks, listTasksByOwner, listWindows, listWorkspaceOrphans, listWorkspaces, listWorkstreams, loadDoctorChecks, loadDoctorSummary, loadFullDag, loadWorkstreamSnapshot, loadWorkstreamSnapshotFast, loadWorkstreamSnapshotSlow, localMachineId, locksDir, mapLegacyStatus, mergeSnapshotFastSlow, mostRecentGroup, murmurAvailable, mux, muxByName, newSession, newSessionWithPane, newWindow, nextHlc, noneBackend, opSubject, openDb, openTask, paneExists, paneTTY, parkTask, parseAgentNameFromTitle, parseHlc, parseOpKey, parsePsTtyOutput, peerStatuses, planUndo, priorFieldValue, probeFilesystem, readAgent, readAgentStates, readFileLockMeta, readManifest, rebuildInto, receiveHlc, reconcile, refreshAgentTitle, releaseTask, remediationParagraph, removeBlockEdge, renderForest, renderOp, renderOpLine, renderTaskTree, repairPeer, reparentTask, resetCommandResolverForTests, resetKickProcessExecutor, resetMux, resetSleep, resetTmuxExecutor, resetWaitPollCount, resetWatermark, resolveActorIdentity, resolveCliCommand, resolveCliCommandWithSource, resolveGroupId, resolvePair, resolvePeerRef, roiBucket, segmentLineCount, segmentPath, selectLayout, sendToAgent, sendToPane, sendViaTransport, sessionExists, setCommandResolverForTests, setKickProcessExecutor, setMuxForTests, setPaneTitle, setSleepForTests, setTaskStatus, setTmuxExecutor, setWaitSleepForTests, setWaitStuckWarnForTests, setWatermark, slBackend, sleep, slugifyTitle, slugifyTitleVerbose, spawnAgent, splitWindow, summarizeOwnedTasks, summarizeWorkstream, syncDir, syncEnabled, syncPass, teardownWorkstream, tmux, tmuxBackend, transportNextSteps, undoGroup, unparkTask, updateTask, verifyAgainstManifest, waitForTasks, withCaptureSuppressed, withFileLock, withOpContext, workspacePath, workspacesRoot, yankCommandForCheck };
|