Repository navigation
Settings: split into General / Work / Make repo / Advanced sub-tabs - #37
Conversation
- Flat 10-workflow stack becomes 4 tabbed workflows - Make repo (not Publish) holds Create + Promote cards - Advanced isolates Delete branch + Run raw git - Draft inputs persist across tab switches via ghDraft - Token scopes collapsed behind details element
There was a problem hiding this comment.
4 issues found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/index.ts">
<violation number="1" location="src/index.ts:3705">
P2: The selected branch draft is not scoped to the linked repository. Opening another repo leaves the old branch name in `ghDraft.pickedBranch`, so Advanced can prefill and submit a branch from the previous repo; reset branch/delete drafts when the repo changes.</violation>
<violation number="2" location="src/index.ts:3966">
P2: Draft fields now survive successful actions and are never cleared. After a promote, 'delete source branch' and 'include uncommitted' stay checked, and the completed repo name and commit message also remain. Clear the matching `ghDraft` fields on success in ghCreate, ghPromote, and ghCommitPush.</violation>
<violation number="3" location="src/index.ts:3999">
P2: Typing a branch into an initially empty delete field never enables `Delete branch` because the button's disabled state is calculated only during render. Recompute `delBtn.disabled` from `din.value` in the input handler.</violation>
<violation number="4" location="src/index.ts:4042">
P2: On the General tab, the Model API key and gateway controls render only after GitHub status loads. If `/api/github/status` fails or is still loading, the key input is missing, so BYOK users cannot set a key. Render the model setup section before the status-gated early return.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
| const pdel = document.createElement("input"); | ||
| pdel.type = "checkbox"; pdel.title = "delete source branch after promote"; | ||
| pdel.checked = !!ghDraft.promoteDel; | ||
| pdel.onchange = () => { ghDraft.promoteDel = pdel.checked; }; |
There was a problem hiding this comment.
P2: Draft fields now survive successful actions and are never cleared. After a promote, 'delete source branch' and 'include uncommitted' stay checked, and the completed repo name and commit message also remain. Clear the matching ghDraft fields on success in ghCreate, ghPromote, and ghCommitPush.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At src/index.ts, line 3966:
<comment>Draft fields now survive successful actions and are never cleared. After a promote, 'delete source branch' and 'include uncommitted' stay checked, and the completed repo name and commit message also remain. Clear the matching `ghDraft` fields on success in ghCreate, ghPromote, and ghCommitPush.</comment>
<file context>
@@ -3737,198 +3797,277 @@ function renderGitHub() {
+ const pdel = document.createElement("input");
+ pdel.type = "checkbox"; pdel.title = "delete source branch after promote";
+ pdel.checked = !!ghDraft.promoteDel;
+ pdel.onchange = () => { ghDraft.promoteDel = pdel.checked; };
+ pdelLbl.appendChild(pdel);
+ pdelLbl.appendChild(document.createTextNode("delete source branch"));
</file context>
There was a problem hiding this comment.
Fixed in #38: ghCreate/ghPromote/ghCommitPush (and ghNewBranch) now clear their ghDraft fields on success. Covered by the new served-page needles test in tests/branches.test.ts.
| runB.onclick = () => ghRunCmd(cmd.value); | ||
| qrow.appendChild(cmd); qrow.appendChild(runB); | ||
| wrap.appendChild(qrow); | ||
| if (tab === "general") renderSharing(wrap); |
There was a problem hiding this comment.
P2: On the General tab, the Model API key and gateway controls render only after GitHub status loads. If /api/github/status fails or is still loading, the key input is missing, so BYOK users cannot set a key. Render the model setup section before the status-gated early return.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At src/index.ts, line 4042:
<comment>On the General tab, the Model API key and gateway controls render only after GitHub status loads. If `/api/github/status` fails or is still loading, the key input is missing, so BYOK users cannot set a key. Render the model setup section before the status-gated early return.</comment>
<file context>
@@ -3737,198 +3797,277 @@ function renderGitHub() {
- runB.onclick = () => ghRunCmd(cmd.value);
- qrow.appendChild(cmd); qrow.appendChild(runB);
- wrap.appendChild(qrow);
+ if (tab === "general") renderSharing(wrap);
+ if (ghMsg) wrap.appendChild(el("pre", "out", ghMsg));
+ pane.appendChild(wrap);
</file context>
There was a problem hiding this comment.
Fixed in #38: model setup extracted to renderGhModelSetup and rendered before the status-gated early return, restoring the pre-split behavior where BYOK users always see the key field. Covered by the needles test.
| din.type = "text"; din.placeholder = "branch, e.g. proto/my-prototype"; | ||
| din.setAttribute("aria-label", "Branch to delete"); | ||
| din.value = ghDraft.delBranch || (ghDraft.pickedBranch || ""); | ||
| din.oninput = () => { ghDraft.delBranch = din.value; }; |
There was a problem hiding this comment.
P2: Typing a branch into an initially empty delete field never enables Delete branch because the button's disabled state is calculated only during render. Recompute delBtn.disabled from din.value in the input handler.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At src/index.ts, line 3999:
<comment>Typing a branch into an initially empty delete field never enables `Delete branch` because the button's disabled state is calculated only during render. Recompute `delBtn.disabled` from `din.value` in the input handler.</comment>
<file context>
@@ -3737,198 +3797,277 @@ function renderGitHub() {
+ din.type = "text"; din.placeholder = "branch, e.g. proto/my-prototype";
+ din.setAttribute("aria-label", "Branch to delete");
+ din.value = ghDraft.delBranch || (ghDraft.pickedBranch || "");
+ din.oninput = () => { ghDraft.delBranch = din.value; };
+ const delBtn = el("button", null, "Delete branch");
+ delBtn.disabled = ghBusy || !linked || !(din.value || "").trim();
</file context>
| din.oninput = () => { ghDraft.delBranch = din.value; }; | |
| din.oninput = () => { | |
| ghDraft.delBranch = din.value; | |
| delBtn.disabled = ghBusy || !linked || !(din.value || "").trim(); | |
| }; |
There was a problem hiding this comment.
Fixed in #38: the Advanced delete row now recomputes delBtn.disabled from the input value in the input handler (syncDelBtn). Covered by the needles test.
| const label = (b.current ? "● " : "") + b.name + (b.remote && !list.some((x) => x.name === b.name && !x.remote) ? " (remote)" : ""); | ||
| const o = el("option", null, label); | ||
| o.value = b.name; | ||
| if (ghDraft.pickedBranch) { |
There was a problem hiding this comment.
P2: The selected branch draft is not scoped to the linked repository. Opening another repo leaves the old branch name in ghDraft.pickedBranch, so Advanced can prefill and submit a branch from the previous repo; reset branch/delete drafts when the repo changes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At src/index.ts, line 3705:
<comment>The selected branch draft is not scoped to the linked repository. Opening another repo leaves the old branch name in `ghDraft.pickedBranch`, so Advanced can prefill and submit a branch from the previous repo; reset branch/delete drafts when the repo changes.</comment>
<file context>
@@ -3628,11 +3666,73 @@ function ghIsRemoteOnly(name) {
+ const label = (b.current ? "● " : "") + b.name + (b.remote && !list.some((x) => x.name === b.name && !x.remote) ? " (remote)" : "");
+ const o = el("option", null, label);
+ o.value = b.name;
+ if (ghDraft.pickedBranch) {
+ if (b.name === ghDraft.pickedBranch) o.selected = true;
+ } else if (b.current || (!cur && ghStatus && ghStatus.linked && b.name === ghStatus.linked.branch)) o.selected = true;
</file context>
There was a problem hiding this comment.
Fixed in #38: ghResetBranches now clears pickedBranch/delBranch (runs on open/create/promote/logout), and switch/new/delete track the picked branch, so drafts never leak across repos. Covered by the needles test.
The Settings tab was 10 workflows stacked flat (API key, gateway, login, sharing, open repo, branches, create, promote, repo list, commit, raw git) — worst at the bottom on mobile.
This splits it into 4 sub-tabs by intent:
Draft inputs persist across tab switches via
ghDraft(previously every render wiped them). Token scopes collapsed;Refresh branches,Delete branch,Remote-onlystrings preserved.Work / Make repo / Advanced show a login gate when logged out and unlock after GitHub login. Verified:
tsc --noEmitclean, 352/352 tests pass.Summary by cubic
Restructures the Settings tab from a flat 10-workflow stack into 4 sub-tabs grouped by intent — General (model setup, GitHub account, sharing), Work (open repo, branches, save), Make repo (create, promote), Advanced (delete branch, raw git) — so workflows are reachable without scrolling past everything else.
Refresh branchesbutton on the Work tab now refreshes the list without needing the picker.Written for commit 977c1da. Summary will update on new commits.
Linked-tab shots use representative fixture data (same components, no OAuth in the screenshot env).