Skip to content

Commit 0aeb61c

Browse files
committed
handle docker setup
1 parent 5e09d87 commit 0aeb61c

File tree

8 files changed

+838
-17
lines changed

8 files changed

+838
-17
lines changed

bun.lock

Lines changed: 249 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"type": "module",
2222
"dependencies": {
2323
"@opentui/react": "^0.1.74",
24+
"build-strap": "^5.2.0",
2425
"commander": "^14.0.2",
2526
"react": "^19.2.3"
2627
}

src/commands/branch.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// ============================================================================
44

55
import { Command } from 'commander';
6+
import { runDockerSetupScreen } from '../components/DockerSetupScreen';
67
import { type AgentType, readConfig } from '../services/config';
78
import { type ForkResult, forkDatabase } from '../services/db';
89
import { ensureDockerImage, startContainer } from '../services/docker';
@@ -93,10 +94,21 @@ export async function branchAction(
9394
console.log(` Database fork created: ${forkResult.name}`);
9495
}
9596

96-
// Step 7: Ensure Docker image exists (build if missing)
97+
// Step 7: Ensure Docker is ready (installed and running)
98+
const dockerResult = await runDockerSetupScreen();
99+
if (dockerResult.type === 'cancelled') {
100+
console.log('Cancelled.');
101+
return;
102+
}
103+
if (dockerResult.type === 'error') {
104+
console.error(`Docker setup failed: ${dockerResult.error}`);
105+
process.exit(1);
106+
}
107+
108+
// Step 8: Ensure Docker image exists (build if missing)
97109
await ensureDockerImage();
98110

99-
// Step 8: Start container (repo will be cloned inside container)
111+
// Step 9: Start container (repo will be cloned inside container)
100112
console.log(
101113
`Starting agent container (using ${effectiveAgent}${effectiveModel ? ` with ${effectiveModel}` : ''})...`,
102114
);

src/commands/init.tsx

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { createCliRenderer, type SelectOption } from '@opentui/core';
66
import { createRoot } from '@opentui/react';
77
import { Command } from 'commander';
88
import { useEffect, useMemo, useState } from 'react';
9+
import { DockerSetup } from '../components/DockerSetup';
910
import { FilterableSelector } from '../components/FilterableSelector';
1011
import { Loading } from '../components/Loading';
1112
import { Selector } from '../components/Selector';
@@ -72,8 +73,8 @@ function App({ onComplete }: AppProps) {
7273
);
7374

7475
const [step, setStep] = useState<
75-
'service' | 'agent' | 'install-opencode' | 'model'
76-
>('service');
76+
'docker' | 'service' | 'agent' | 'install-opencode' | 'model'
77+
>('docker');
7778
const [config, setConfig] = useState<ConductorConfig | null>(null);
7879

7980
// Async data - null means still loading
@@ -121,7 +122,29 @@ function App({ onComplete }: AppProps) {
121122
onComplete({ type: 'cancelled' });
122123
};
123124

124-
// ---- Step 1: Service Selection ----
125+
// ---- Step 1: Docker Setup ----
126+
if (step === 'docker') {
127+
return (
128+
<DockerSetup
129+
title="Step 1/4: Docker Setup"
130+
onComplete={(result) => {
131+
if (result.type === 'cancelled') {
132+
onComplete({ type: 'cancelled' });
133+
} else if (result.type === 'error') {
134+
onComplete({
135+
type: 'error',
136+
message: result.error ?? 'Docker setup failed',
137+
});
138+
} else {
139+
setStep('service');
140+
}
141+
}}
142+
showBack={false}
143+
/>
144+
);
145+
}
146+
147+
// ---- Step 2: Service Selection ----
125148
if (step === 'service') {
126149
// Need config and services
127150
if (config === null || services === null) {
@@ -152,21 +175,22 @@ function App({ onComplete }: AppProps) {
152175

153176
return (
154177
<Selector
155-
title="Step 1/3: Database Service"
178+
title="Step 2/4: Database Service"
156179
description="Select a Tiger service to use as the default parent for database forks."
157180
options={serviceOptions}
158181
initialIndex={initialIndex >= 0 ? initialIndex : 0}
159-
showBack={false}
182+
showBack
160183
onSelect={(value) => {
161184
setConfig((c) => (c ? { ...c, tigerServiceId: value } : c));
162185
setStep('agent');
163186
}}
164187
onCancel={handleCancel}
188+
onBack={() => setStep('docker')}
165189
/>
166190
);
167191
}
168192

169-
// ---- Step 2: Agent Selection ----
193+
// ---- Step 3: Agent Selection ----
170194
if (step === 'agent') {
171195
// Need opencodeInstalled to know whether to show install prompt
172196
if (opencodeInstalled === null) {
@@ -185,7 +209,7 @@ function App({ onComplete }: AppProps) {
185209

186210
return (
187211
<Selector
188-
title="Step 2/3: Default Agent"
212+
title="Step 3/4: Default Agent"
189213
description="Select the default coding agent to use."
190214
options={agentOptions}
191215
initialIndex={initialIndex >= 0 ? initialIndex : 0}
@@ -226,7 +250,7 @@ function App({ onComplete }: AppProps) {
226250
);
227251
}
228252

229-
// ---- Step 2.5: Install OpenCode ----
253+
// ---- Step 3.5: Install OpenCode ----
230254
if (step === 'install-opencode') {
231255
if (isInstalling) {
232256
return <Loading title="Installing opencode" onCancel={handleCancel} />;
@@ -292,7 +316,7 @@ function App({ onComplete }: AppProps) {
292316
);
293317
}
294318

295-
// ---- Step 3: Model Selection ----
319+
// ---- Step 4: Model Selection ----
296320
if (step === 'model') {
297321
const currentModels =
298322
config?.agent === 'opencode' ? opencodeModels : claudeModels;
@@ -329,7 +353,7 @@ function App({ onComplete }: AppProps) {
329353
if (config?.agent === 'opencode') {
330354
return (
331355
<FilterableSelector
332-
title={`Step 3/3: Default Model (${config.agent})`}
356+
title={`Step 4/4: Default Model (${config.agent})`}
333357
description={`Select the default model for ${config.agent}.`}
334358
options={modelOptions}
335359
initialIndex={initialIndex >= 0 ? initialIndex : 0}
@@ -343,7 +367,7 @@ function App({ onComplete }: AppProps) {
343367

344368
return (
345369
<Selector
346-
title={`Step 3/3: Default Model (${config?.agent})`}
370+
title={`Step 4/4: Default Model (${config?.agent})`}
347371
description={`Select the default model for ${config?.agent}.`}
348372
options={modelOptions}
349373
initialIndex={initialIndex >= 0 ? initialIndex : 0}

0 commit comments

Comments
 (0)