+
Send a Goal
@@ -37,6 +104,7 @@
placeholder="e.g., Open YouTube and search for lofi beats"
class="flex-1 rounded border border-neutral-300 px-3 py-2 text-sm focus:border-neutral-500 focus:outline-none"
disabled={status === 'running'}
+ onkeydown={(e) => e.key === 'Enter' && submitGoal()}
/>
- {#if steps.length > 0}
+
+ {#if steps.length > 0 || status === 'running'}
+
+
+
+ {currentGoal ? `Goal: ${currentGoal}` : 'Current Run'}
+
+ {#if status === 'running'}
+
+
+ Running
+
+ {:else if status === 'completed'}
+ Completed
+ {:else if status === 'failed'}
+ Failed
+ {/if}
+
+ {#if steps.length > 0}
+
+ {#each steps as s (s.step)}
+
+
+
+ {s.step}
+
+ {s.action}
+
+ {#if s.reasoning}
+
{s.reasoning}
+ {/if}
+
+ {/each}
+
+ {:else}
+
Waiting for first step...
+ {/if}
+
+ {/if}
+
+
+ {#if sessions.length > 0}
-
Steps
+ Session History
- {#each steps as step (step.step)}
+ {#each sessions as sess (sess.id)}
-
Step {step.step}: {step.action}
-
{step.reasoning}
+
+
{sess.goal}
+
+ {sess.status === 'completed' ? 'Success' : sess.status === 'running' ? 'Running' : 'Failed'}
+
+
+
+ {formatTime(sess.startedAt)} · {sess.stepsUsed} steps
+
{/each}
{/if}
-
- {#if status === 'completed'}
-
Goal completed successfully.
- {:else if status === 'failed'}
-
Goal failed. Please try again.
- {/if}
diff --git a/web/src/routes/login/+page.svelte b/web/src/routes/login/+page.svelte
new file mode 100644
index 0000000..250a1bf
--- /dev/null
+++ b/web/src/routes/login/+page.svelte
@@ -0,0 +1,32 @@
+
+
+
diff --git a/web/src/routes/page.svelte.spec.ts b/web/src/routes/page.svelte.spec.ts
new file mode 100644
index 0000000..3c6adf3
--- /dev/null
+++ b/web/src/routes/page.svelte.spec.ts
@@ -0,0 +1,13 @@
+import { page } from '@vitest/browser/context';
+import { describe, expect, it } from 'vitest';
+import { render } from 'vitest-browser-svelte';
+import Page from './+page.svelte';
+
+describe('/+page.svelte', () => {
+ it('should render h1', async () => {
+ render(Page);
+
+ const heading = page.getByRole('heading', { level: 1 });
+ await expect.element(heading).toBeInTheDocument();
+ });
+});
diff --git a/web/src/routes/signup/+page.svelte b/web/src/routes/signup/+page.svelte
new file mode 100644
index 0000000..dde2edd
--- /dev/null
+++ b/web/src/routes/signup/+page.svelte
@@ -0,0 +1,35 @@
+
+
+
diff --git a/web/static/robots.txt b/web/static/robots.txt
new file mode 100644
index 0000000..b6dd667
--- /dev/null
+++ b/web/static/robots.txt
@@ -0,0 +1,3 @@
+# allow crawling everything by default
+User-agent: *
+Disallow:
diff --git a/web/tsconfig.json b/web/tsconfig.json
new file mode 100644
index 0000000..a5567ee
--- /dev/null
+++ b/web/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "extends": "./.svelte-kit/tsconfig.json",
+ "compilerOptions": {
+ "allowJs": true,
+ "checkJs": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "strict": true,
+ "moduleResolution": "bundler"
+ }
+ // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
+ // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
+ //
+ // To make changes to top-level options such as include and exclude, we recommend extending
+ // the generated config; see https://svelte.dev/docs/kit/configuration#typescript
+}
diff --git a/web/vite.config.ts b/web/vite.config.ts
new file mode 100644
index 0000000..e388fe7
--- /dev/null
+++ b/web/vite.config.ts
@@ -0,0 +1,37 @@
+import devtoolsJson from 'vite-plugin-devtools-json';
+import tailwindcss from '@tailwindcss/vite';
+import { defineConfig } from 'vitest/config';
+import { sveltekit } from '@sveltejs/kit/vite';
+
+export default defineConfig({
+ plugins: [tailwindcss(), sveltekit(), devtoolsJson()],
+ test: {
+ expect: { requireAssertions: true },
+ projects: [
+ {
+ extends: './vite.config.ts',
+ test: {
+ name: 'client',
+ environment: 'browser',
+ browser: {
+ enabled: true,
+ provider: 'playwright',
+ instances: [{ browser: 'chromium' }]
+ },
+ include: ['src/**/*.svelte.{test,spec}.{js,ts}'],
+ exclude: ['src/lib/server/**'],
+ setupFiles: ['./vitest-setup-client.ts']
+ }
+ },
+ {
+ extends: './vite.config.ts',
+ test: {
+ name: 'server',
+ environment: 'node',
+ include: ['src/**/*.{test,spec}.{js,ts}'],
+ exclude: ['src/**/*.svelte.{test,spec}.{js,ts}']
+ }
+ }
+ ]
+ }
+});
diff --git a/web/vitest-setup-client.ts b/web/vitest-setup-client.ts
new file mode 100644
index 0000000..570b9f0
--- /dev/null
+++ b/web/vitest-setup-client.ts
@@ -0,0 +1,2 @@
+///
+///