Skip to content

Commit d9cbf3f

Browse files
feat: release pr context.
1 parent 57138c8 commit d9cbf3f

5 files changed

Lines changed: 42 additions & 30 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ browser acts as the runtime host for render, lint, and typecheck flows.
4141

4242
- GitHub PAT setup and usage: [docs/byot.md](docs/byot.md)
4343

44+
AI chat features remain opt-in behind
45+
`?feature-ai=true`.
46+
4447
## Fine-Grained PAT Quick Setup
4548

46-
For AI/BYOT flows, use a fine-grained GitHub PAT and follow the existing setup guide:
49+
For PR/BYOT and AI chat flows, use a fine-grained GitHub PAT and follow the
50+
existing setup guide:
4751

4852
- Full setup and behavior: [docs/byot.md](docs/byot.md)
4953
- Repository permissions screenshot: [docs/media/byot-repo-perms.png](docs/media/byot-repo-perms.png)

docs/byot.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,25 @@ This guide explains how to create and use a fine-grained GitHub Personal Access
44

55
## What BYOT does in the app
66

7-
When the AI/BYOT feature is enabled, the token is used to:
7+
BYOT controls are available by default. The token is used to:
88

99
- authenticate GitHub API requests
1010
- load repositories where you have write access
1111
- let you choose which repository to work with
12+
- use PR context features (Open PR / Push Commit flows)
1213

13-
As additional AI/PR features roll out, the same token is also used for model and repository operations that require the configured permissions.
14+
When AI chat is enabled, the same token is also used for GitHub Models requests.
1415

1516
## Privacy and storage behavior
1617

1718
- Your token is stored only in your browser `localStorage`.
1819
- The token is never sent to any service except the GitHub endpoints required by the feature.
1920
- You can remove it at any time using the delete button in the BYOT controls.
2021

21-
## Enable the BYOT feature
22+
## Enable AI chat features
2223

23-
Use one of these options:
24+
BYOT/PR controls do not require a feature flag. To enable AI chat features, use one
25+
of these options:
2426

2527
1. Add `?feature-ai=true` to the app URL.
2628
2. Set `localStorage` key `knighted:develop:feature:ai-assistant` to `true`.
@@ -57,10 +59,11 @@ Use either of these scopes depending on your needs:
5759
## Recommended setup flow
5860

5961
1. Create token with the permissions above.
60-
2. Open `@knighted/develop` with `?feature-ai=true`.
62+
2. Open `@knighted/develop`.
6163
3. Paste token into the BYOT input and click add.
6264
4. Verify repository list loads.
6365
5. Select your target repository.
66+
6. Optional: enable AI chat with `?feature-ai=true`.
6467

6568
## Screenshots
6669

docs/next-steps.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,21 @@ Focused follow-up work for `@knighted/develop`.
3131
- Add mode-aware recommendation behavior so the assistant strongly adapts suggestions to current render mode and style mode.
3232
- Add an editor update workflow where the assistant can propose structured edits and the user can apply to Component and Styles editors with explicit confirmation.
3333
- Keep behavior and constraints aligned with current implementation:
34-
- Keep everything behind the existing browser-only AI feature flag.
34+
- Keep AI chat/assistant behavior behind the existing browser-only AI feature flag.
35+
- Keep PR/BYOT controls available by default.
3536
- Preserve BYOT token semantics (localStorage persistence until user deletes).
3637
- Keep CDN-first runtime behavior and existing fallback model.
3738
- Do not add dependencies without explicit approval.
3839
- Remaining Phase 3 mini-spec (agent implementation prompt):
39-
- "Continue Issue #18 in @knighted/develop from the current baseline where PR filename/path groundwork and Open PR flow are already shipped. Implement the two remaining Phase 3 assistant deliverables. (1) Add mode-aware assistant guidance: when collecting AI context, include explicit policy hints derived from render mode and style mode, and ensure recommendations avoid incompatible patterns (for example, avoid React hook/state guidance in DOM mode unless user explicitly asks for React migration). (2) Add assistant-to-editor apply flow: support structured assistant responses that can propose edits for component and/or styles editors; render these as reviewable actions in the chat drawer, require explicit user confirmation to apply, and support a one-step undo for last applied assistant edit per editor. Keep all AI/BYOT behavior behind the existing browser-only AI feature flag and preserve current token/repo persistence semantics. Do not add dependencies. Validate with npm run lint and targeted Playwright tests covering mode-aware recommendation constraints and apply/undo editor actions."
40+
- "Continue Issue #18 in @knighted/develop from the current baseline where PR filename/path groundwork and Open PR flow are already shipped. Implement the two remaining Phase 3 assistant deliverables. (1) Add mode-aware assistant guidance: when collecting AI context, include explicit policy hints derived from render mode and style mode, and ensure recommendations avoid incompatible patterns (for example, avoid React hook/state guidance in DOM mode unless user explicitly asks for React migration). (2) Add assistant-to-editor apply flow: support structured assistant responses that can propose edits for component and/or styles editors; render these as reviewable actions in the chat drawer, require explicit user confirmation to apply, and support a one-step undo for last applied assistant edit per editor. Keep AI chat/assistant behavior behind the existing browser-only AI feature flag, keep PR/BYOT controls available by default, and preserve current token/repo persistence semantics. Do not add dependencies. Validate with npm run lint and targeted Playwright tests covering mode-aware recommendation constraints and apply/undo editor actions."
4041

4142
5. **Phase 2 UX/UI continuation: fixed editor tabs first pass (Component, Styles, App)**
4243
- Continue the tabs/editor UX work with a constrained first implementation that supports exactly three editor tabs: Component, Styles, and App.
4344
- Do not introduce arbitrary/custom tab names in this pass; treat custom naming as future scope after baseline tab behavior is stable.
4445
- Preserve existing runtime behavior and editor content semantics while adding tab switching, active tab indication, and predictable persistence/reset behavior consistent with current app patterns.
4546
- Ensure assistant/editor integration remains compatible with this model (edits should target one of the fixed tabs) without expanding to dynamic tab metadata yet.
4647
- Suggested implementation prompt:
47-
- "Implement Phase 2 UX/UI tab support in @knighted/develop with a fixed first-pass tab model: Component, Styles, and App only (no arbitrary tab names yet). Add a clear tab UI for switching editor panes, preserve existing editor behavior/content wiring, and keep render/lint/typecheck/diagnostics flows working with the selected tab context where relevant. Keep AI/BYOT feature-flag behavior unchanged, maintain CDN-first runtime constraints, and do not add dependencies. Add targeted Playwright coverage for tab switching, default/active tab behavior, and interactions with existing render/style-mode flows. Validate with npm run lint and targeted Playwright tests."
48+
- "Implement Phase 2 UX/UI tab support in @knighted/develop with a fixed first-pass tab model: Component, Styles, and App only (no arbitrary tab names yet). Add a clear tab UI for switching editor panes, preserve existing editor behavior/content wiring, and keep render/lint/typecheck/diagnostics flows working with the selected tab context where relevant. Keep AI chat feature-flag behavior unchanged while keeping PR/BYOT controls available by default, maintain CDN-first runtime constraints, and do not add dependencies. Add targeted Playwright coverage for tab switching, default/active tab behavior, and interactions with existing render/style-mode flows. Validate with npm run lint and targeted Playwright tests."
4849

4950
6. **Document implicit App strict-flow behavior (auto render)**
5051
- Add a short behavior matrix in docs that explains when implicit App wrapping is allowed versus when users must define `App` explicitly.

playwright/github-byot-ai.spec.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,26 @@ import {
1010
waitForAppReady,
1111
} from './helpers/app-test-helpers.js'
1212

13-
test('BYOT controls stay hidden when feature flag is disabled', async ({ page }) => {
13+
test('PR/BYOT controls are visible without feature flag, but chat stays hidden', async ({
14+
page,
15+
}) => {
1416
await waitForAppReady(page)
1517

16-
const byotControls = page.getByRole('group', {
17-
name: 'GitHub controls',
18-
includeHidden: true,
19-
})
20-
await expect(byotControls).toHaveAttribute('hidden', '')
21-
await expect(byotControls).toBeHidden()
18+
const byotControls = page.getByRole('group', { name: 'GitHub controls' })
19+
await expect(byotControls).toBeVisible()
20+
await expect(page.getByRole('textbox', { name: 'GitHub token' })).toBeVisible()
21+
await expect(page.getByRole('button', { name: 'Add GitHub token' })).toBeVisible()
2222
await expect(page.getByRole('button', { name: 'Chat' })).toBeHidden()
2323
await expect(page.getByRole('heading', { name: 'AI Chat' })).toBeHidden()
2424
await expect(page.getByRole('button', { name: 'Open PR' })).toBeHidden()
25-
await expect(page.getByRole('heading', { name: 'Open Pull Request' })).toBeHidden()
25+
})
26+
27+
test('chat remains hidden without feature flag after token connect', async ({ page }) => {
28+
await waitForAppReady(page)
29+
await connectByotWithSingleRepo(page)
30+
31+
await expect(page.getByRole('button', { name: 'Open pull request' })).toBeVisible()
32+
await expect(page.getByRole('button', { name: 'Chat' })).toBeHidden()
2633
})
2734

2835
test('BYOT controls render when feature flag is enabled by query param', async ({

src/app.js

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -224,16 +224,6 @@ const setCompactAiControlsOpen = isOpen => {
224224
return
225225
}
226226

227-
if (!aiAssistantFeatureEnabled) {
228-
compactAiControlsOpen = false
229-
setGitHubTokenInfoOpen(false)
230-
aiControlsToggle.setAttribute('hidden', '')
231-
aiControlsToggle.setAttribute('aria-expanded', 'false')
232-
githubAiControls.removeAttribute('data-compact-open')
233-
githubAiControls.setAttribute('hidden', '')
234-
return
235-
}
236-
237227
aiControlsToggle.removeAttribute('hidden')
238228

239229
if (!isCompactViewport()) {
@@ -663,8 +653,15 @@ const syncAiChatTokenVisibility = token => {
663653
const hasToken = typeof token === 'string' && token.trim().length > 0
664654

665655
if (hasToken) {
666-
aiChatToggle?.removeAttribute('hidden')
656+
if (aiAssistantFeatureEnabled) {
657+
aiChatToggle?.removeAttribute('hidden')
658+
} else {
659+
aiChatToggle?.setAttribute('hidden', '')
660+
aiChatToggle?.setAttribute('aria-expanded', 'false')
661+
}
662+
667663
githubPrToggle?.removeAttribute('hidden')
664+
668665
if (githubAiContextState.activePrContext) {
669666
githubPrContextClose?.removeAttribute('hidden')
670667
} else {
@@ -688,7 +685,7 @@ const syncAiChatTokenVisibility = token => {
688685
}
689686

690687
const byotControls = createGitHubByotControls({
691-
featureEnabled: aiAssistantFeatureEnabled,
688+
featureEnabled: true,
692689
controlsRoot: githubAiControls,
693690
tokenInput: githubTokenInput,
694691
tokenInfoButton: githubTokenInfo,
@@ -791,7 +788,7 @@ chatDrawerController = createGitHubChatDrawer({
791788
})
792789

793790
prDrawerController = createGitHubPrDrawer({
794-
featureEnabled: aiAssistantFeatureEnabled,
791+
featureEnabled: true,
795792
toggleButton: githubPrToggle,
796793
drawer: githubPrDrawer,
797794
closeButton: githubPrClose,

0 commit comments

Comments
 (0)