Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/app.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { onMounted, reactive, ref, type ComponentPublicInstance } from "vue";
import { nextTick, onMounted, reactive, ref, type ComponentPublicInstance } from "vue";
import { useOsStore } from "./features/os/stores/os";
import { useAppsStore } from "./features/apps/stores/apps";
import WindowFrame from "./features/os/components/WindowFrame.vue";
Expand Down Expand Up @@ -81,12 +81,14 @@ function getAppSource(id: string) {
return app ? readFile(app.entry) : null;
}

function askFix(payload: { appId: string; error: string; sourceCode?: string }) {
async function askFix(payload: { appId: string; error: string; sourceCode?: string }) {
const chatWin = os.windows.find((w) => w.appId === 'chat');
if (chatWin) {
os.focusWindow(chatWin.id);
} else {
openBuiltin('chat');
// The chat window mounts on the next render; wait for its ref before sending.
await nextTick();
}

const app = getApp(payload.appId);
Expand Down
46 changes: 46 additions & 0 deletions tests/e2e/ask-fix-chat-closed.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { expect, test } from '@playwright/test'
import { stubAgentReply } from './support/agent-stub'
import { appWindow, dominicHooks, keepRequestsLocal, openDesktop } from './support/desktop'

// #92: "Ask Agent to Fix" must reach the agent even when Agent Chat was
// closed. The click reopens the chat window; the message has to wait for that
// window to mount instead of being dropped.

const REPAIRED_APP = `<template>
<div class="p-6">
<h2>{{ status }}</h2>
</div>
</template>

<script setup>
import { ref } from 'vue'
const status = ref('Repaired by the agent')
</script>
`

test.beforeEach(async ({ page, baseURL }) => {
await keepRequestsLocal(page, baseURL)
})

test('Ask Agent to Fix reopens a closed Agent Chat and still reaches the agent', async ({ page }) => {
const dominic = dominicHooks(page)
const chat = appWindow(page, 'Agent Chat')
const broken = appWindow(page, 'Broken (Syntax Error)')
await openDesktop(page)

await chat.getByRole('button', { name: 'Close' }).click()
await expect(chat).toHaveCount(0)

await dominic.injectBrokenApp('compile')
await expect(broken.getByText('Component Compilation Error')).toBeVisible()

const requests = await stubAgentReply(page, {
text: 'Found the bug; sending a fixed version.',
updateApp: { id: 'broken-app', vueSfcCode: REPAIRED_APP, summary: 'Fix the deliberate error' },
})
await broken.getByRole('button', { name: 'Ask Agent to Fix' }).click()

await expect(chat).toBeVisible()
await expect(broken.getByRole('heading', { name: 'Repaired by the agent' })).toBeVisible()
expect(requests).toHaveLength(1)
})
Loading