Skip to content

Commit 71ae127

Browse files
author
Colin McNeil
committed
Add all necessary prerun
1 parent a727811 commit 71ae127

File tree

3 files changed

+55
-30
lines changed

3 files changed

+55
-30
lines changed

src/extension/docker-compose.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
services:
22
labs-ai-tools-for-devs:
33
image: ${DESKTOP_PLUGIN_IMAGE}
4+
volumes:
5+
openai_key:
6+
driver: local
7+

src/extension/ui/src/App.tsx

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import React, { useEffect } from 'react';
22
import Button from '@mui/material/Button';
33
import DelIcon from '@mui/icons-material/Delete';
44
import { createDockerDesktopClient } from '@docker/extension-api-client';
5-
import { Divider, FormControlLabel, FormGroup, Grid, Icon, IconButton, Link, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Modal, Paper, Stack, Switch, TextField, Tooltip, Typography } from '@mui/material';
5+
import { Divider, FormControlLabel, FormGroup, Grid, Icon, IconButton, Link, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Modal, Paper, Stack, Switch, TextareaAutosize, TextField, Tooltip, Typography } from '@mui/material';
66
import { getRunArgs } from './args';
7-
import { on } from 'events';
87

98
// Note: This line relies on Docker Desktop's presence as a host application.
109
// If you're running this React app in a browser, it won't work properly.
@@ -22,12 +21,12 @@ const debouncedToastSuccess = debounce(client.desktopUI.toast.success, 1000)
2221

2322
export function App() {
2423
const [projects, setProjects] = React.useState<string[]>(localStorage.getItem('projects') ? JSON.parse(localStorage.getItem('projects')!) : []);
25-
const [selectedProject, setSelectedProject] = React.useState<string | null>(null);
24+
const [selectedProject, setSelectedProject] = React.useState<string | null>(localStorage.getItem('selectedProject') || null);
2625

2726
const [prompts, setPrompts] = React.useState<string[]>(localStorage.getItem('prompts') ? JSON.parse(localStorage.getItem('prompts')!) : []);
28-
const [selectedPrompt, setSelectedPrompt] = React.useState<string | null>(null);
27+
const [selectedPrompt, setSelectedPrompt] = React.useState<string | null>(localStorage.getItem('selectedPrompt') || null);
2928

30-
const [openAIKey, setOpenAIKey] = React.useState<string | null>(null);
29+
const [openAIKey, setOpenAIKey] = React.useState<string | null>(localStorage.getItem('openAIKey') || '');
3130

3231
const [promptInput, setPromptInput] = React.useState<string>('');
3332

@@ -46,6 +45,14 @@ export function App() {
4645
localStorage.setItem('openAIKey', openAIKey || '');
4746
}, [openAIKey]);
4847

48+
useEffect(() => {
49+
localStorage.setItem('selectedProject', selectedProject || '');
50+
}, [selectedProject]);
51+
52+
useEffect(() => {
53+
localStorage.setItem('selectedPrompt', selectedPrompt || '');
54+
}, [selectedPrompt]);
55+
4956

5057
useEffect(() => {
5158
// URL format: https://github.com/<owner>/<repo>/tree/<branch>/<path>
@@ -63,6 +70,10 @@ export function App() {
6370
}
6471
}, [promptInput]);
6572

73+
const appendToRunOut = (msg: string) => {
74+
setRunOut(runOut + '\n' + msg);
75+
}
76+
6677
const delim = client.host.platform === 'win32' ? '\\' : '/';
6778

6879
return (
@@ -72,7 +83,7 @@ export function App() {
7283
<Paper sx={{ padding: 1, pl: 2 }}>
7384
<Stack direction='row' spacing={2} alignItems={'center'} justifyContent={'space-between'}>
7485
<Typography sx={{ flex: '1 1 30%' }} variant='h4'>OpenAI Key</Typography>
75-
<TextField sx={{ flex: '1 1 70%' }} onChange={e => setOpenAIKey(e.target.value)} value={openAIKey} placeholder='Enter OpenAI API key' type='password' />
86+
<TextField sx={{ flex: '1 1 70%' }} onChange={e => setOpenAIKey(e.target.value)} value={openAIKey || ''} placeholder='Enter OpenAI API key' type='password' />
7687
</Stack>
7788
</Paper>
7889
</Grid>
@@ -98,6 +109,7 @@ export function App() {
98109
<List>
99110
{projects.map((project) => (
100111
<ListItem
112+
key={project}
101113
sx={theme => ({ borderLeft: 'solid black 3px', borderColor: selectedProject === project ? theme.palette.success.main : 'none', my: 0.5, padding: 0 })}
102114
secondaryAction={
103115
<IconButton color='error' onClick={() => {
@@ -140,6 +152,7 @@ export function App() {
140152
<List>
141153
{prompts.map((prompt) => (
142154
<ListItem
155+
key={prompt}
143156
sx={theme => ({
144157
borderLeft: 'solid black 3px',
145158
borderColor: selectedPrompt === prompt ? theme.palette.success.main : 'none',
@@ -169,49 +182,58 @@ export function App() {
169182
</Paper>
170183
</Grid>
171184
{/* Show row at bottom if selectProject AND selectedPrompt */}
172-
{selectedProject && selectedPrompt ? (
185+
{selectedProject && selectedPrompt && openAIKey ? (
173186
<Grid item xs={12}>
174187
<Paper sx={{ padding: 1 }}>
175188
<Typography variant="h3" component="h2">Ready</Typography>
176-
<Typography><pre>PROJECT={selectedProject}</pre></Typography>
177-
<Typography><pre>PROMPT={selectedPrompt}</pre></Typography>
189+
<pre>PROJECT={selectedProject}</pre>
190+
<pre>PROMPT={selectedPrompt}</pre>
178191
<Button sx={{ mt: 1, }} color='success' onClick={async () => {
179192
// Write openai key to $HOME/.openai-api-key
180-
setRunOut('Writing OpenAI key...');
181-
await client.extension.vm?.cli.exec('/bin/sh', ['-c', `echo ${openAIKey} > $HOME/.openai-api-key`]);
182-
setRunOut('Running...');
193+
appendToRunOut('Writing OpenAI key...');
194+
await new Promise((resolve) => setTimeout(resolve, 1000));
195+
// Write openai key to $HOME/.openai-api-key without shell operator
196+
const result = await client.docker.cli.exec('volume', ['create', 'openai-key']);
197+
appendToRunOut(JSON.stringify(result));
198+
// appendToRunOut(runOut + '\nRunning...');
183199
client.docker.cli.exec('run', getRunArgs(selectedPrompt, selectedProject, client.host.hostname, client.host.platform), {
184200
stream: {
185201
onError: (err) => {
186-
setRunOut(runOut + '\n' + err.message);
202+
// appendToRunOut(err.message);
187203
},
188204
onOutput: ({ stdout, stderr }) => {
189-
setRunOut(runOut + '\n' + (stdout || stderr));
205+
// appendToRunOut(stdout || stderr || '');
190206
}
191-
}
207+
},
192208
})
193209
}}>
194210
<Typography variant='h3'>Run</Typography>
195211
</Button>
196212
</Paper>
197-
</Grid>
213+
</Grid >
198214
) : (
199215
<Grid item xs={12}>
200-
<Paper>
201-
You must select a project and a prompt to run.
216+
<Paper sx={{ padding: 1 }}>
217+
<Typography variant='h3'>Missing:</Typography>
218+
{selectedProject?.length ? null : <Typography variant='body1'> - Project</Typography>}
219+
{selectedPrompt?.length ? null : <Typography variant='body1'> - Prompt</Typography>}
220+
{openAIKey?.length ? null : <Typography variant='body1'> - OpenAI Key</Typography>}
202221
</Paper>
203222
</Grid>
204-
)}
223+
)
224+
}
205225
{/* Show run output */}
206-
{runOut && (
207-
<Grid item xs={12}>
208-
<Paper>
209-
<Typography variant='h3'>Run output</Typography>
210-
<pre>{runOut}</pre>
211-
</Paper>
212-
</Grid>
213-
)}
214-
</Grid>
226+
{
227+
runOut && (
228+
<Grid item xs={12}>
229+
<Paper>
230+
<Typography variant='h3'>Run output</Typography>
231+
<textarea readOnly style={{ width: '100%', minHeight: '100px' }} value={runOut} />
232+
</Paper>
233+
</Grid>
234+
)
235+
}
236+
</Grid >
215237
</>
216238
);
217239
}

src/extension/ui/src/args.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ export const getRunArgs = (prompt_ref: string, project_dir: string, username: st
1212
// "github:docker/labs-githooks?ref=main&path=prompts/git_hooks"
1313
return [
1414
'--rm',
15-
'-it',
1615
'-v',
1716
'/var/run/docker.sock:/var/run/docker.sock',
1817
'--mount',
1918
'type=volume,source=docker-prompts,target=/prompts',
2019
'--mount',
21-
'type=bind,source=$HOME/.openai-api-key,target=/root/.openai-api-key',
20+
'type=bind,source=/root/.openai-api-key,target=/root/.openai-api-key',
2221
'vonwig/prompts:latest',
2322
'run',
2423
project_dir,

0 commit comments

Comments
 (0)