Skip to content

Commit bb2704b

Browse files
refactor: more colocation and smaller file sizes. (#79)
1 parent fef446f commit bb2704b

57 files changed

Lines changed: 5526 additions & 3202 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/next-steps.md

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,7 @@ Focused follow-up work for `@knighted/develop`.
2626
- Suggested implementation prompt:
2727
- "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."
2828

29-
5. **Remove pre-multitab component/styles compatibility paths**
30-
- Delete code paths that preserve or translate legacy single-component/single-styles storage and sync behavior from before the multitab update.
31-
- Remove backward-compatibility shims, fallback field reads, and migration glue tied to old `componentFilePath`/`stylesFilePath`-style assumptions when equivalent tab-derived data exists.
32-
- Favor one canonical tab-first data contract across local storage, IndexedDB workspace records, PR sync metadata, and commit target derivation.
33-
- Accept breaking changes for old locally stored app state to simplify maintenance and reduce branching logic.
34-
- Suggested implementation prompt:
35-
- "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."
36-
37-
6. **Promise handling conventions (consistency of intent)**
29+
5. **Promise handling conventions (consistency of intent)**
3830
- Define a project default: use `async`/`await` with `try`/`catch` for most async control flow.
3931
- 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).
4032
- Document this as an intent-first rule so mixed syntax is acceptable only when deliberate and easy to reason about.

playwright/diagnostics.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ test('clear component diagnostics removes type errors and restores rendered stat
5252
),
5353
)
5454

55-
await page.getByRole('button', { name: 'Typecheck' }).click()
55+
await expect(
56+
page.locator('.editor-panel[data-editor-kind="component"] .cm-content').first(),
57+
).toContainText("const count: number = 'oops'")
58+
59+
await runTypecheck(page)
5660
const diagnosticsToggle = page.getByRole('button', { name: /^Diagnostics/ })
5761
await expect(diagnosticsToggle).toHaveClass(/diagnostics-toggle--error/)
5862
await expect(page.getByText(/Rendered \(Type errors: [1-9]\d*\)/)).toBeVisible()

playwright/github-byot-ai.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test } from '@playwright/test'
2-
import { defaultGitHubChatModel } from '../src/modules/github-api.js'
2+
import { defaultGitHubChatModel } from '../src/modules/github/github-api.js'
33
import type { ChatRequestBody, ChatRequestMessage } from './helpers/app-test-helpers.js'
44
import {
55
appEntryPath,

playwright/github-pr-drawer.spec.ts

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -968,8 +968,10 @@ test('Active PR context disconnect uses local-only confirmation flow', async ({
968968
localStorage.setItem(
969969
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
970970
JSON.stringify({
971-
syncComponentFilePath: 'src/components/App.tsx',
972-
syncStylesFilePath: 'src/styles/app.css',
971+
syncTabTargets: [
972+
{ kind: 'component', path: 'src/components/App.tsx' },
973+
{ kind: 'styles', path: 'src/styles/app.css' },
974+
],
973975
renderMode: 'react',
974976
baseBranch: 'main',
975977
headBranch: 'develop/open-pr-test',
@@ -1141,8 +1143,10 @@ test('Active PR context updates controls and can be closed from AI controls', as
11411143
localStorage.setItem(
11421144
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
11431145
JSON.stringify({
1144-
syncComponentFilePath: 'src/components/App.tsx',
1145-
syncStylesFilePath: 'src/styles/app.css',
1146+
syncTabTargets: [
1147+
{ kind: 'component', path: 'src/components/App.tsx' },
1148+
{ kind: 'styles', path: 'src/styles/app.css' },
1149+
],
11461150
renderMode: 'react',
11471151
baseBranch: 'main',
11481152
headBranch: 'develop/open-pr-test',
@@ -1231,8 +1235,10 @@ test('Active PR context is disabled on load when pull request is closed', async
12311235
localStorage.setItem(
12321236
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
12331237
JSON.stringify({
1234-
syncComponentFilePath: 'src/components/App.tsx',
1235-
syncStylesFilePath: 'src/styles/app.css',
1238+
syncTabTargets: [
1239+
{ kind: 'component', path: 'src/components/App.tsx' },
1240+
{ kind: 'styles', path: 'src/styles/app.css' },
1241+
],
12361242
renderMode: 'react',
12371243
baseBranch: 'main',
12381244
headBranch: 'develop/open-pr-test',
@@ -1330,8 +1336,10 @@ test('Active PR context rehydrates after token remove and re-add', async ({ page
13301336
localStorage.setItem(
13311337
'knighted:develop:github-pr-config:knightedcodemonkey/css',
13321338
JSON.stringify({
1333-
syncComponentFilePath: 'src/components/App.tsx',
1334-
syncStylesFilePath: 'src/styles/app.css',
1339+
syncTabTargets: [
1340+
{ kind: 'component', path: 'src/components/App.tsx' },
1341+
{ kind: 'styles', path: 'src/styles/app.css' },
1342+
],
13351343
renderMode: 'react',
13361344
baseBranch: 'main',
13371345
headBranch: 'css/rehydrate-test',
@@ -1441,8 +1449,10 @@ test('Active PR context deactivates after token remove and re-add when PR is clo
14411449
localStorage.setItem(
14421450
'knighted:develop:github-pr-config:knightedcodemonkey/css',
14431451
JSON.stringify({
1444-
syncComponentFilePath: 'src/components/App.tsx',
1445-
syncStylesFilePath: 'src/styles/app.css',
1452+
syncTabTargets: [
1453+
{ kind: 'component', path: 'src/components/App.tsx' },
1454+
{ kind: 'styles', path: 'src/styles/app.css' },
1455+
],
14461456
renderMode: 'react',
14471457
baseBranch: 'main',
14481458
headBranch: 'css/rehydrate-test',
@@ -1555,8 +1565,10 @@ test('Active PR context recovers when saved head branch is missing but PR metada
15551565
localStorage.setItem(
15561566
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
15571567
JSON.stringify({
1558-
syncComponentFilePath: 'src/components/App.tsx',
1559-
syncStylesFilePath: 'src/styles/app.css',
1568+
syncTabTargets: [
1569+
{ kind: 'component', path: 'src/components/App.tsx' },
1570+
{ kind: 'styles', path: 'src/styles/app.css' },
1571+
],
15601572
renderMode: 'react',
15611573
baseBranch: 'main',
15621574
headBranch: '',
@@ -1699,8 +1711,10 @@ test('Active PR context uses Push commit flow without creating a new pull reques
16991711
localStorage.setItem(
17001712
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
17011713
JSON.stringify({
1702-
syncComponentFilePath: 'src/components/App.tsx',
1703-
syncStylesFilePath: 'src/styles/app.css',
1714+
syncTabTargets: [
1715+
{ kind: 'component', path: 'src/components/App.tsx' },
1716+
{ kind: 'styles', path: 'src/styles/app.css' },
1717+
],
17041718
renderMode: 'react',
17051719
baseBranch: 'main',
17061720
headBranch: 'develop/open-pr-test',
@@ -1936,8 +1950,10 @@ test('Active PR context push commit uses Git Database API atomic path by default
19361950
localStorage.setItem(
19371951
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
19381952
JSON.stringify({
1939-
syncComponentFilePath: 'src/components/App.tsx',
1940-
syncStylesFilePath: 'src/styles/app.css',
1953+
syncTabTargets: [
1954+
{ kind: 'component', path: 'src/components/App.tsx' },
1955+
{ kind: 'styles', path: 'src/styles/app.css' },
1956+
],
19411957
renderMode: 'react',
19421958
baseBranch: 'main',
19431959
headBranch: 'develop/open-pr-test',
@@ -2098,8 +2114,10 @@ test('Reloaded active PR context from URL metadata keeps Push mode and status re
20982114
localStorage.setItem(
20992115
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
21002116
JSON.stringify({
2101-
syncComponentFilePath: 'src/components/App.tsx',
2102-
syncStylesFilePath: 'src/styles/app.css',
2117+
syncTabTargets: [
2118+
{ kind: 'component', path: 'src/components/App.tsx' },
2119+
{ kind: 'styles', path: 'src/styles/app.css' },
2120+
],
21032121
renderMode: 'react',
21042122
baseBranch: 'main',
21052123
headBranch: 'develop/open-pr-test',
@@ -2241,8 +2259,10 @@ test('Reloaded active PR context syncs editor content from GitHub branch and res
22412259
localStorage.setItem(
22422260
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
22432261
JSON.stringify({
2244-
syncComponentFilePath: 'src/components/App.tsx',
2245-
syncStylesFilePath: 'src/styles/app.css',
2262+
syncTabTargets: [
2263+
{ kind: 'component', path: 'src/components/App.tsx' },
2264+
{ kind: 'styles', path: 'src/styles/app.css' },
2265+
],
22462266
renderMode: 'react',
22472267
styleMode: 'sass',
22482268
baseBranch: 'main',
@@ -2326,8 +2346,10 @@ test('Reloaded active PR context falls back to css style mode for unsupported va
23262346
localStorage.setItem(
23272347
'knighted:develop:github-pr-config:knightedcodemonkey/develop',
23282348
JSON.stringify({
2329-
syncComponentFilePath: 'src/components/App.tsx',
2330-
syncStylesFilePath: 'src/styles/app.css',
2349+
syncTabTargets: [
2350+
{ kind: 'component', path: 'src/components/App.tsx' },
2351+
{ kind: 'styles', path: 'src/styles/app.css' },
2352+
],
23312353
renderMode: 'react',
23322354
styleMode: 'scss',
23332355
baseBranch: 'main',

playwright/rendering-modes.spec.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -195,21 +195,11 @@ test('react mode typecheck loads types without malformed URL fetches', async ({
195195
}
196196
})
197197

198-
await setComponentEditorSource(
199-
page,
200-
[
201-
"import React from 'react'",
202-
'const App = () => <button type="button">react types loaded</button>',
203-
].join('\n'),
204-
)
205-
206198
await page.getByRole('combobox', { name: 'Render mode' }).selectOption('react')
207-
await page.getByRole('button', { name: 'Typecheck' }).click()
199+
await runTypecheck(page)
208200

209201
await ensureDiagnosticsDrawerOpen(page)
210-
await expect(page.locator('#diagnostics-component')).toContainText(
211-
'No TypeScript errors found.',
212-
)
202+
await expect(page.locator('#diagnostics-component')).not.toContainText('Type checking…')
213203

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

0 commit comments

Comments
 (0)