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
10 changes: 1 addition & 9 deletions docs/next-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,7 @@ Focused follow-up work for `@knighted/develop`.
- Suggested implementation prompt:
- "Evaluate and optionally optimize @knighted/develop GitHub file upsert behavior. Compare metadata-first preflight GET+PUT against optimistic PUT with retry-on-missing-sha for existing files. Keep current reliability guarantees and avoid reintroducing noisy false-positive failures. If implementing a hybrid/configurable strategy, keep defaults conservative, update docs, and validate with npm run lint plus targeted Playwright PR drawer flows."

5. **Remove pre-multitab component/styles compatibility paths**
- Delete code paths that preserve or translate legacy single-component/single-styles storage and sync behavior from before the multitab update.
- Remove backward-compatibility shims, fallback field reads, and migration glue tied to old `componentFilePath`/`stylesFilePath`-style assumptions when equivalent tab-derived data exists.
- Favor one canonical tab-first data contract across local storage, IndexedDB workspace records, PR sync metadata, and commit target derivation.
- Accept breaking changes for old locally stored app state to simplify maintenance and reduce branching logic.
- Suggested implementation prompt:
- "Remove backwards-compatibility code in @knighted/develop that supports pre-multitab component/styles storage/sync behavior. Standardize on the current tab-derived schema only, delete legacy field fallbacks and migration helpers, and update tests/docs to match the simplified contract. Validate with npm run lint and targeted Playwright suites for workspace tabs + PR drawer flows."

6. **Promise handling conventions (consistency of intent)**
5. **Promise handling conventions (consistency of intent)**
- Define a project default: use `async`/`await` with `try`/`catch` for most async control flow.
- Keep Promise chains where they better express intent (for example, fire-and-forget paths with explicit `.catch()` to avoid unhandled rejections, or concise pass-through composition).
- Document this as an intent-first rule so mixed syntax is acceptable only when deliberate and easy to reason about.
Expand Down
6 changes: 5 additions & 1 deletion playwright/diagnostics.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ test('clear component diagnostics removes type errors and restores rendered stat
),
)

await page.getByRole('button', { name: 'Typecheck' }).click()
await expect(
page.locator('.editor-panel[data-editor-kind="component"] .cm-content').first(),
).toContainText("const count: number = 'oops'")

await runTypecheck(page)
const diagnosticsToggle = page.getByRole('button', { name: /^Diagnostics/ })
await expect(diagnosticsToggle).toHaveClass(/diagnostics-toggle--error/)
await expect(page.getByText(/Rendered \(Type errors: [1-9]\d*\)/)).toBeVisible()
Expand Down
2 changes: 1 addition & 1 deletion playwright/github-byot-ai.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, test } from '@playwright/test'
import { defaultGitHubChatModel } from '../src/modules/github-api.js'
import { defaultGitHubChatModel } from '../src/modules/github/github-api.js'
import type { ChatRequestBody, ChatRequestMessage } from './helpers/app-test-helpers.js'
import {
appEntryPath,
Expand Down
66 changes: 44 additions & 22 deletions playwright/github-pr-drawer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@
expect(activeContext.key).toBe(
'knighted:develop:github-pr-config:knightedcodemonkey/css',
)
expect(activeContext.parsed?.headBranch).toBe('examples/css/head')

Check failure on line 811 in playwright/github-pr-drawer.spec.ts

View workflow job for this annotation

GitHub Actions / E2E (Playwright, webkit, shard 2/4)

[webkit] › playwright/github-pr-drawer.spec.ts:740:1 › Open PR drawer keeps a single active PR context in localStorage

1) [webkit] › playwright/github-pr-drawer.spec.ts:740:1 › Open PR drawer keeps a single active PR context in localStorage Error: expect(received).toBe(expected) // Object.is equality Expected: "examples/css/head" Received: "examples/develop/head" 809 | 'knighted:develop:github-pr-config:knightedcodemonkey/css', 810 | ) > 811 | expect(activeContext.parsed?.headBranch).toBe('examples/css/head') | ^ 812 | }) 813 | 814 | test('Open PR drawer does not prune saved PR context on repo switch before save', async ({ at /home/runner/work/develop/develop/playwright/github-pr-drawer.spec.ts:811:44
})

test('Open PR drawer does not prune saved PR context on repo switch before save', async ({
Expand Down Expand Up @@ -968,8 +968,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
baseBranch: 'main',
headBranch: 'develop/open-pr-test',
Expand Down Expand Up @@ -1141,8 +1143,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
baseBranch: 'main',
headBranch: 'develop/open-pr-test',
Expand Down Expand Up @@ -1231,8 +1235,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
baseBranch: 'main',
headBranch: 'develop/open-pr-test',
Expand Down Expand Up @@ -1330,8 +1336,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/css',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
baseBranch: 'main',
headBranch: 'css/rehydrate-test',
Expand Down Expand Up @@ -1441,8 +1449,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/css',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
baseBranch: 'main',
headBranch: 'css/rehydrate-test',
Expand Down Expand Up @@ -1555,8 +1565,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
baseBranch: 'main',
headBranch: '',
Expand Down Expand Up @@ -1699,8 +1711,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
baseBranch: 'main',
headBranch: 'develop/open-pr-test',
Expand Down Expand Up @@ -1936,8 +1950,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
baseBranch: 'main',
headBranch: 'develop/open-pr-test',
Expand Down Expand Up @@ -2098,8 +2114,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
baseBranch: 'main',
headBranch: 'develop/open-pr-test',
Expand Down Expand Up @@ -2241,8 +2259,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
styleMode: 'sass',
baseBranch: 'main',
Expand Down Expand Up @@ -2326,8 +2346,10 @@
localStorage.setItem(
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
JSON.stringify({
syncComponentFilePath: 'src/components/App.tsx',
syncStylesFilePath: 'src/styles/app.css',
syncTabTargets: [
{ kind: 'component', path: 'src/components/App.tsx' },
{ kind: 'styles', path: 'src/styles/app.css' },
],
renderMode: 'react',
styleMode: 'scss',
baseBranch: 'main',
Expand Down
14 changes: 2 additions & 12 deletions playwright/rendering-modes.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { expect, test } from '@playwright/test'
import {
addWorkspaceTab,
Expand Down Expand Up @@ -195,21 +195,11 @@
}
})

await setComponentEditorSource(
page,
[
"import React from 'react'",
'const App = () => <button type="button">react types loaded</button>',
].join('\n'),
)

await page.getByRole('combobox', { name: 'Render mode' }).selectOption('react')
await page.getByRole('button', { name: 'Typecheck' }).click()
await runTypecheck(page)

await ensureDiagnosticsDrawerOpen(page)
await expect(page.locator('#diagnostics-component')).toContainText(
'No TypeScript errors found.',
)
await expect(page.locator('#diagnostics-component')).not.toContainText('Type checking…')

const diagnosticsText = await page.locator('#diagnostics-component').innerText()
expect(diagnosticsText).not.toContain("Cannot find type definition file for 'react'")
Expand Down
Loading
Loading