@brimveyn/aimux 1.19.7 → 1.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/package.json +3 -2
- package/skills/aimux-orchestrator/SKILL.md +127 -0
- package/skills/aimux-orchestrator/assets/ledger.template.md +18 -0
- package/skills/aimux-orchestrator/references/prompts.md +68 -0
- package/skills/aimux-orchestrator/references/review.md +18 -0
- package/src/cli/client/daemon-client.ts +16 -0
- package/src/cli/client/workspace-resolver.ts +61 -8
- package/src/cli/commands/tab/await.ts +1 -1
- package/src/cli/commands/tab/close.ts +1 -1
- package/src/cli/commands/tab/create.ts +263 -128
- package/src/cli/commands/tab/focus.ts +1 -1
- package/src/cli/commands/tab/prompt-io.ts +8 -2
- package/src/cli/commands/tab/run.ts +10 -2
- package/src/cli/commands/tab/send.ts +12 -7
- package/src/cli/commands/tab/snapshot.ts +2 -1
- package/src/cli/commands/tab/tail.ts +1 -1
- package/src/cli/commands/tab/wait.ts +2 -1
- package/src/cli/commands/worker/await.ts +34 -0
- package/src/cli/commands/worker/doctor.ts +153 -0
- package/src/cli/commands/worker/list.ts +67 -0
- package/src/cli/commands/worker/prompt.ts +74 -0
- package/src/cli/commands/worker/run.ts +143 -0
- package/src/cli/commands/worker/shared.ts +515 -0
- package/src/cli/commands/worker/stop.ts +113 -0
- package/src/cli/commands/worker/submit.ts +40 -0
- package/src/cli/commands/workspace/close.ts +1 -1
- package/src/cli/commands/workspace/create.ts +2 -1
- package/src/cli/commands/workspace/switch.ts +1 -1
- package/src/cli/commands/worktree/create-core.ts +27 -7
- package/src/cli/commands/worktree/create.ts +18 -3
- package/src/cli/commands/worktree/remove.ts +32 -10
- package/src/cli/completion/entry.ts +181 -0
- package/src/cli/completion/install.ts +222 -0
- package/src/cli/completion/plan.ts +216 -0
- package/src/cli/completion/scripts.ts +147 -0
- package/src/cli/completion/sources.ts +74 -0
- package/src/cli/context.ts +15 -0
- package/src/cli/flags.ts +45 -2
- package/src/cli/index.ts +40 -18
- package/src/cli/output.ts +3 -0
- package/src/cli/registry.ts +14 -0
- package/src/daemon/daemon.ts +58 -8
- package/src/daemon/session-registry.ts +5 -0
- package/src/doctor.ts +4 -0
- package/src/git/worktree.ts +23 -1
- package/src/index.tsx +53 -92
- package/src/ipc/manager-protocol.ts +15 -2
- package/src/ipc/protocol.ts +26 -3
- package/src/platform/worktree-paths.ts +21 -1
- package/src/state/session-persistence.ts +2 -0
- package/src/state/types.ts +4 -0
- package/src/state/validation.ts +1 -0
- package/src/terminal-manager/manager-client.ts +18 -3
package/README.md
CHANGED
|
@@ -36,6 +36,12 @@ bun install -g @brimveyn/aimux
|
|
|
36
36
|
|
|
37
37
|
Requires [Bun](https://bun.sh).
|
|
38
38
|
|
|
39
|
+
Shell completion (bash, zsh, fish) installs itself the first time you launch
|
|
40
|
+
the TUI — one file in your shell's completions directory, no dotfile edits.
|
|
41
|
+
Run `aimux doctor` to see where it landed, or
|
|
42
|
+
`aimux completion install --shell zsh` to place it yourself. Opt out with
|
|
43
|
+
`AIMUX_NO_COMPLETION_INSTALL=1`. See [docs/reference/cli.md](docs/reference/cli.md#aimux-completion).
|
|
44
|
+
|
|
39
45
|
## Quick Start
|
|
40
46
|
|
|
41
47
|
Create the default profile and install the typed config package into it:
|
|
@@ -157,6 +163,8 @@ The help modal reflects the resolved keymap, so it includes your overrides.
|
|
|
157
163
|
|
|
158
164
|
```bash
|
|
159
165
|
aimux
|
|
166
|
+
aimux worker doctor
|
|
167
|
+
aimux worker run --name investigate --assistant claude "inspect this repository"
|
|
160
168
|
aimux version
|
|
161
169
|
aimux doctor
|
|
162
170
|
aimux update
|
|
@@ -166,6 +174,12 @@ aimux restart-terminal-manager
|
|
|
166
174
|
|
|
167
175
|
See [`docs/reference/cli.md`](docs/reference/cli.md) for behavior details.
|
|
168
176
|
|
|
177
|
+
For agent orchestration, prefer the named `aimux worker` commands. They combine
|
|
178
|
+
isolated worktree creation, prompt dispatch, authoritative turn waiting, fleet
|
|
179
|
+
inspection, and guarded cleanup without shell wrappers or `jq`. Pin the target
|
|
180
|
+
with `--workspace` (or `AIMUX_WORKSPACE`) for anything long-running: the default
|
|
181
|
+
follows whichever workspace the UI opened last.
|
|
182
|
+
|
|
169
183
|
## Runtime Model
|
|
170
184
|
|
|
171
185
|
`aimux` is split into:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brimveyn/aimux",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.2",
|
|
4
4
|
"description": "A terminal multiplexer for AI CLIs. Run Claude, Codex, OpenCode, Kimi side-by-side with tabbed navigation, split panes, and persistent sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"files": [
|
|
36
36
|
"src",
|
|
37
|
+
"skills",
|
|
37
38
|
"README.md",
|
|
38
39
|
"LICENSE"
|
|
39
40
|
],
|
|
@@ -65,7 +66,7 @@
|
|
|
65
66
|
"bump:terminal_manager": "bun run scripts/bump-protocol.ts terminal-manager"
|
|
66
67
|
},
|
|
67
68
|
"dependencies": {
|
|
68
|
-
"@brimveyn/aimux-config": "0.8.
|
|
69
|
+
"@brimveyn/aimux-config": "0.8.5",
|
|
69
70
|
"@opentui/core": "^0.1.90",
|
|
70
71
|
"@opentui/react": "^0.1.90",
|
|
71
72
|
"@resvg/resvg-wasm": "^2.6.2",
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aimux-orchestrator
|
|
3
|
+
description: Orchestrate implementation plans with parallel Claude, Codex, OpenCode, Grok, or Kimi workers through the aimux worker CLI. Use when an agent must decompose a plan, launch isolated workers, supervise questions and failures, review each worker's diff and checks, integrate accepted work, and clean up safely.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# aimux Orchestrator
|
|
7
|
+
|
|
8
|
+
Own the plan and quality gate. Let aimux own worker transport and lifecycle.
|
|
9
|
+
|
|
10
|
+
## Preflight
|
|
11
|
+
|
|
12
|
+
Run once:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
aimux worker doctor --workspace <target>
|
|
16
|
+
aimux worker --help
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Stop if the doctor reports missing worker capabilities, the wrong workspace, or
|
|
20
|
+
an unavailable assistant. Restart/update aimux as instructed; do not fall back
|
|
21
|
+
to screen scraping or the legacy shell wrappers.
|
|
22
|
+
|
|
23
|
+
**Pin the workspace and verify the repo before dispatching anything.** Without
|
|
24
|
+
`--workspace` (or `AIMUX_WORKSPACE`) aimux targets whichever workspace the UI
|
|
25
|
+
opened last, and that can change under you mid-run — including to a different
|
|
26
|
+
project. Check `checks.workspace.repoRoot` in the doctor output against the
|
|
27
|
+
repository you mean, then pass `--workspace <id|name>` on **every** call (all
|
|
28
|
+
examples below do). Every worker response echoes `workspace.repoRoot`; read it on
|
|
29
|
+
the first dispatch instead of assuming.
|
|
30
|
+
|
|
31
|
+
## Orchestration loop
|
|
32
|
+
|
|
33
|
+
1. Parse the plan into independently reviewable units and dependencies.
|
|
34
|
+
2. Record units in a ledger. Copy `assets/ledger.template.md` for multi-unit work.
|
|
35
|
+
3. Select only units whose dependencies are accepted.
|
|
36
|
+
4. Launch no more workers than you can review:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
aimux worker run \
|
|
40
|
+
--workspace <target> \
|
|
41
|
+
--name feat-auth \
|
|
42
|
+
--assistant claude \
|
|
43
|
+
--prompt-file /tmp/feat-auth.md \
|
|
44
|
+
--detach
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
5. Inspect the fleet with `aimux worker list --workspace <target>`.
|
|
48
|
+
6. Await a detached worker with `aimux worker await feat-auth --workspace <target>`.
|
|
49
|
+
7. If a worker asks a question, answer only when the plan already determines the
|
|
50
|
+
answer:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
aimux worker prompt feat-auth --workspace <target> --replace --prompt-file /tmp/answer.md
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Escalate design choices, irreversible operations, deployments, pushes,
|
|
57
|
+
migrations, spending, and external communication to the human.
|
|
58
|
+
|
|
59
|
+
8. Review the worktree path returned in the worker JSON. Read the diff and run
|
|
60
|
+
the repository's required tests, typecheck, lint, and build. Worker claims
|
|
61
|
+
are not evidence.
|
|
62
|
+
9. Accept, request a precise correction with `worker prompt`, or escalate.
|
|
63
|
+
10. After integration, close and clean up:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
aimux worker stop feat-auth --workspace <target> --cleanup-worktree
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Dispatch failure modes
|
|
70
|
+
|
|
71
|
+
Read these before the first dispatch; each one otherwise reads as a lost fleet.
|
|
72
|
+
|
|
73
|
+
- **`status: "pending-submit"` (exit 11)** — the prompt is sitting unsubmitted in
|
|
74
|
+
the worker's composer. The worker is alive and healthy. Recover with
|
|
75
|
+
`aimux worker submit <name> --workspace <target>`; never re-dispatch, which
|
|
76
|
+
would double the fleet onto the same branches. Widen the confirmation window
|
|
77
|
+
with `--uptake-timeout <ms>` for slow-booting assistants.
|
|
78
|
+
- **An empty `worker list`** — read the `workspace` field in the response. An
|
|
79
|
+
empty fleet in the wrong workspace is not a dead fleet. Add
|
|
80
|
+
`--all-workspaces` to answer "are they really gone?" in one call;
|
|
81
|
+
`git worktree list` in the target repo is the on-disk cross-check.
|
|
82
|
+
- **Composer contamination** — a human typing in a worker's tab leaves text that
|
|
83
|
+
`worker prompt` would append to, merging both into one incoherent instruction.
|
|
84
|
+
Use `--replace` (clears with `<C-u>`) for every correction, and
|
|
85
|
+
`aimux tab snapshot <tabId>` when a worker's behaviour doesn't match the
|
|
86
|
+
prompt you believe you sent.
|
|
87
|
+
- **Fresh worktrees are not provisioned** — a new worktree has no installed
|
|
88
|
+
dependencies and no generated files. Every dispatch prompt must tell the worker
|
|
89
|
+
to bootstrap before running any gate (see `references/prompts.md`), or it will
|
|
90
|
+
report environment failures as its own.
|
|
91
|
+
|
|
92
|
+
## Isolation
|
|
93
|
+
|
|
94
|
+
`worker run` creates a fresh worktree by default. Keep that default when writes
|
|
95
|
+
may overlap or scope is uncertain.
|
|
96
|
+
|
|
97
|
+
- Use `--worktree <id>` only for workers intentionally sharing one review unit.
|
|
98
|
+
- Use `--no-worktree` only for sequential work or provably disjoint writes in
|
|
99
|
+
the active tree.
|
|
100
|
+
- Review co-located workers together because their diff is shared.
|
|
101
|
+
|
|
102
|
+
## Dispatch rules
|
|
103
|
+
|
|
104
|
+
- Give each worker one bounded unit with goal, scope, exclusions, acceptance
|
|
105
|
+
criteria, repository conventions, and required verification.
|
|
106
|
+
- Read `references/prompts.md` when drafting task or correction prompts.
|
|
107
|
+
- Use provider defaults unless the plan or user requires a model. Set
|
|
108
|
+
`--model`/`--effort` only when `worker doctor` says the assistant supports the
|
|
109
|
+
control.
|
|
110
|
+
- Prefer `--prompt-file` for multiline prompts; it avoids shell quoting hazards.
|
|
111
|
+
- Use `--detach` for parallel launch. Without it, `worker run` waits and returns
|
|
112
|
+
a completed/question/timeout/error outcome.
|
|
113
|
+
- Pass `--workspace` on every call, and confirm the `repoRoot` the first response
|
|
114
|
+
reports is the repository you intend to change.
|
|
115
|
+
|
|
116
|
+
## Quality and safety
|
|
117
|
+
|
|
118
|
+
Read `references/review.md` before accepting the first unit.
|
|
119
|
+
|
|
120
|
+
- `completed` means the turn ended, not that the change is correct.
|
|
121
|
+
- Never accept a failing or unrun verification gate.
|
|
122
|
+
- Cap correction attempts at three; then escalate with evidence.
|
|
123
|
+
- Never use `--force` cleanup unless the human authorized discarding dirty work.
|
|
124
|
+
- Keep the ledger truthful after every dispatch, outcome, review, and integration.
|
|
125
|
+
|
|
126
|
+
The CLI is the command reference. Use `aimux worker <verb> --help` instead of
|
|
127
|
+
copying flags or JSON shapes into this skill.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Orchestration ledger
|
|
2
|
+
|
|
3
|
+
Base: `<branch / sha>`
|
|
4
|
+
|
|
5
|
+
| unit | goal | deps | status | worker | worktree / branch | attempts | review evidence |
|
|
6
|
+
| ---- | ---- | ---- | ------- | ------ | ----------------- | -------: | --------------- |
|
|
7
|
+
| 1.1 | | — | pending | | | 0 | |
|
|
8
|
+
|
|
9
|
+
Statuses: `pending`, `dispatched`, `in-review`, `needs-changes`, `accepted`,
|
|
10
|
+
`blocked`, `escalated`.
|
|
11
|
+
|
|
12
|
+
## Decisions
|
|
13
|
+
|
|
14
|
+
- `<date>` — `<decision and reason>`
|
|
15
|
+
|
|
16
|
+
## Human questions
|
|
17
|
+
|
|
18
|
+
- [ ] `<unit>` — `<decision needed, evidence, and options>`
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Worker prompts
|
|
2
|
+
|
|
3
|
+
## Task
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
# Task: <id> — <title>
|
|
7
|
+
|
|
8
|
+
## Goal
|
|
9
|
+
|
|
10
|
+
<observable outcome>
|
|
11
|
+
|
|
12
|
+
## Scope
|
|
13
|
+
|
|
14
|
+
- In: <files or subsystem>
|
|
15
|
+
- Out: <explicit exclusions>
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
1. <behavior>
|
|
20
|
+
2. <edge case>
|
|
21
|
+
|
|
22
|
+
## Acceptance
|
|
23
|
+
|
|
24
|
+
- <machine-checkable criterion>
|
|
25
|
+
|
|
26
|
+
## Environment
|
|
27
|
+
|
|
28
|
+
This is a fresh worktree: it has no installed dependencies and no generated
|
|
29
|
+
files. Run <the repo's install + codegen commands> before any verification gate,
|
|
30
|
+
and report a bootstrap failure as a bootstrap failure — never as a failing gate.
|
|
31
|
+
|
|
32
|
+
## Verification
|
|
33
|
+
|
|
34
|
+
Run the repository's tests, typecheck, lint, and build commands that apply.
|
|
35
|
+
Report changed files, commands run, results, and remaining risks.
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Tell the worker to read repository instructions before editing. Do not ask it to
|
|
39
|
+
merge, push, deploy, or clean up its worktree.
|
|
40
|
+
|
|
41
|
+
Keep the **Environment** block. A fresh `git worktree` shares history, not build
|
|
42
|
+
state: no `node_modules`, no generated clients or route files. Without it workers
|
|
43
|
+
run the gates in a half-provisioned tree, fail for environment reasons, and report
|
|
44
|
+
those failures as if they were their own.
|
|
45
|
+
|
|
46
|
+
## Correction
|
|
47
|
+
|
|
48
|
+
```markdown
|
|
49
|
+
# Correction for <id>
|
|
50
|
+
|
|
51
|
+
The review found:
|
|
52
|
+
|
|
53
|
+
- <specific failing behavior with file/test evidence>
|
|
54
|
+
|
|
55
|
+
Required change:
|
|
56
|
+
|
|
57
|
+
- <bounded correction>
|
|
58
|
+
|
|
59
|
+
Do not broaden scope. Re-run:
|
|
60
|
+
|
|
61
|
+
- <exact verification commands>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Answer
|
|
65
|
+
|
|
66
|
+
Answer the exact question and restate any relevant boundary. If the question
|
|
67
|
+
introduces a product decision or risky action not settled by the plan, escalate
|
|
68
|
+
instead of improvising.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Worker review gate
|
|
2
|
+
|
|
3
|
+
Review inside the returned worktree path.
|
|
4
|
+
|
|
5
|
+
1. Read repository instructions and the dispatched acceptance criteria.
|
|
6
|
+
2. Inspect status and the complete diff against the unit's base.
|
|
7
|
+
3. Confirm every changed hunk belongs to the requested scope.
|
|
8
|
+
4. Check correctness, edge cases, error paths, tests, debug leftovers, secrets,
|
|
9
|
+
stubs, and repository conventions.
|
|
10
|
+
5. Run the required test, typecheck, lint, format-check, and build commands
|
|
11
|
+
yourself.
|
|
12
|
+
6. Record evidence in the ledger.
|
|
13
|
+
|
|
14
|
+
Accept only when the behavior and verification pass. If a check cannot run,
|
|
15
|
+
record why and escalate when it prevents a trustworthy decision.
|
|
16
|
+
|
|
17
|
+
Request changes with concrete evidence: location, observed behavior, expected
|
|
18
|
+
behavior, and the exact gate to rerun. Do not send a vague "fix the tests" prompt.
|
|
@@ -135,10 +135,26 @@ export class DaemonClient {
|
|
|
135
135
|
return this.hello.capabilities
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
getAppVersion(): string | null {
|
|
139
|
+
return this.hello.appVersion ?? null
|
|
140
|
+
}
|
|
141
|
+
|
|
138
142
|
getSelectedVersion(): number {
|
|
139
143
|
return this.hello.selectedVersion
|
|
140
144
|
}
|
|
141
145
|
|
|
146
|
+
getProcessVersion(): string {
|
|
147
|
+
return this.hello.processVersion
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
getManagerCapabilities(): readonly string[] {
|
|
151
|
+
return this.hello.managerCapabilities ?? []
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
getManagerSelectedVersion(): number | null {
|
|
155
|
+
return this.hello.managerSelectedVersion ?? null
|
|
156
|
+
}
|
|
157
|
+
|
|
142
158
|
private async send(request: ClientRequest): Promise<ServerResponse> {
|
|
143
159
|
return new Promise((resolve, reject) => {
|
|
144
160
|
const timer = setTimeout(() => {
|
|
@@ -1,17 +1,55 @@
|
|
|
1
|
-
import type { SessionRecord } from '../../state/types'
|
|
1
|
+
import type { SessionRecord, WorktreeRecord } from '../../state/types'
|
|
2
2
|
|
|
3
3
|
import { findMostRecentSession, loadSessionCatalog } from '../../state/session-catalog'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
|
|
6
|
+
* Where a command's target workspace came from. An orchestrator needs this to
|
|
7
|
+
* tell "I asked for pragma-once" from "aimux guessed, and the UI had moved on":
|
|
8
|
+
* `active` is the only origin that can silently follow the UI to another repo.
|
|
9
|
+
*/
|
|
10
|
+
export type WorkspaceOrigin = 'flag' | 'env' | 'active'
|
|
11
|
+
|
|
12
|
+
export interface ResolvedWorkspace {
|
|
13
|
+
origin: WorkspaceOrigin
|
|
14
|
+
record: SessionRecord
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Env pin for headless orchestrators — `--workspace` still wins over it. */
|
|
18
|
+
export const WORKSPACE_ENV_VAR = 'AIMUX_WORKSPACE'
|
|
19
|
+
|
|
20
|
+
/** The workspace's primary (root) worktree, i.e. the repository it is about. */
|
|
21
|
+
export function findPrimaryWorktree(session: SessionRecord): WorktreeRecord | undefined {
|
|
22
|
+
return session.worktrees?.find((worktree) => worktree.source === 'primary')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The repo every fresh worktree for this workspace is cut from. Surfaced in
|
|
27
|
+
* every worker envelope so an agent can see *which project* it just acted on
|
|
28
|
+
* instead of inferring it from a worktree path hash.
|
|
29
|
+
*/
|
|
30
|
+
export function workspaceRepoRoot(session: SessionRecord): string | null {
|
|
31
|
+
return findPrimaryWorktree(session)?.repoRoot ?? session.projectPath ?? null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Stable workspace identity block embedded in command output. */
|
|
35
|
+
export function workspaceIdentity(session: SessionRecord): {
|
|
36
|
+
id: string
|
|
37
|
+
name: string
|
|
38
|
+
repoRoot: string | null
|
|
39
|
+
} {
|
|
40
|
+
return { id: session.id, name: session.name, repoRoot: workspaceRepoRoot(session) }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Resolve `--workspace W` to a session record from the catalog, reporting where
|
|
45
|
+
* the choice came from. Precedence: the explicit flag, then `AIMUX_WORKSPACE`,
|
|
46
|
+
* then the most recently opened session. Throws when the catalog is empty (no
|
|
47
|
+
* session has ever been created) or when the explicit name/id doesn't match.
|
|
10
48
|
*
|
|
11
49
|
* Matching: exact id wins; otherwise exact name (case-sensitive); otherwise
|
|
12
50
|
* unique case-insensitive name match.
|
|
13
51
|
*/
|
|
14
|
-
export function
|
|
52
|
+
export function resolveWorkspaceWithOrigin(name: string | undefined): ResolvedWorkspace {
|
|
15
53
|
const sessions = loadSessionCatalog()
|
|
16
54
|
if (sessions.length === 0) {
|
|
17
55
|
throw new Error(
|
|
@@ -19,14 +57,29 @@ export function resolveWorkspace(name: string | undefined): SessionRecord {
|
|
|
19
57
|
)
|
|
20
58
|
}
|
|
21
59
|
|
|
22
|
-
|
|
60
|
+
const flag = name !== undefined && name !== '' ? name : undefined
|
|
61
|
+
const env = process.env[WORKSPACE_ENV_VAR]
|
|
62
|
+
const fromEnv = env != null && env !== '' ? env : undefined
|
|
63
|
+
const selector = flag ?? fromEnv
|
|
64
|
+
if (selector === undefined) {
|
|
23
65
|
const active = findMostRecentSession(sessions)
|
|
24
66
|
if (!active) {
|
|
25
67
|
throw new Error('no active workspace and the catalog is empty')
|
|
26
68
|
}
|
|
27
|
-
return active
|
|
69
|
+
return { origin: 'active', record: active }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
origin: flag !== undefined ? 'flag' : 'env',
|
|
74
|
+
record: matchWorkspace(sessions, selector),
|
|
28
75
|
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function resolveWorkspace(name: string | undefined): SessionRecord {
|
|
79
|
+
return resolveWorkspaceWithOrigin(name).record
|
|
80
|
+
}
|
|
29
81
|
|
|
82
|
+
function matchWorkspace(sessions: SessionRecord[], name: string): SessionRecord {
|
|
30
83
|
const byId = sessions.find((session) => session.id === name)
|
|
31
84
|
if (byId) return byId
|
|
32
85
|
|
|
@@ -27,7 +27,7 @@ import { awaitTurn, DEFAULT_TIMEOUT_MS, type TurnOutcome, turnOutcomeExitCode }
|
|
|
27
27
|
const QUESTION_TAIL_LINES = 25
|
|
28
28
|
|
|
29
29
|
export const tabAwait: CliCommand = {
|
|
30
|
-
args: [{ name: 'tabId', required: true }],
|
|
30
|
+
args: [{ complete: { kind: 'dynamic', source: 'tab' }, name: 'tabId', required: true }],
|
|
31
31
|
flags: [
|
|
32
32
|
...SHARED_FLAGS,
|
|
33
33
|
{
|
|
@@ -5,7 +5,7 @@ import { SHARED_FLAGS } from '../../flags'
|
|
|
5
5
|
import { EXIT_OK, writeJson } from '../../output'
|
|
6
6
|
|
|
7
7
|
export const tabClose: CliCommand = {
|
|
8
|
-
args: [{ name: 'tabId', required: true }],
|
|
8
|
+
args: [{ complete: { kind: 'dynamic', source: 'tab' }, name: 'tabId', required: true }],
|
|
9
9
|
flags: SHARED_FLAGS,
|
|
10
10
|
group: 'tab',
|
|
11
11
|
run: async (ctx) => {
|