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
8 changes: 8 additions & 0 deletions .frame/PROJECT_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3739,3 +3739,11 @@ Shape:
- `layoutMigration.lineNeedsReview` learned two cases so the off template is not reported as user edits: a renumbered navigation item, and a document that never names STRUCTURE.json.
- Still mentioning the map regardless: the REFERENCE.md and QUICKSTART.md templates.
- The lifecycle decision is taken when a project is opened; hooks and scripts read the config on every run.

### [2026-10-22] Project switcher back in the sidebar, above Work

User's request (Turkish, verbatim): "project seçimi şu an yukarıda sağda, onu soldan ikinci panele, work menü item ının üstüne geri yerleştirmek istiyorum".

History: sidebar-project-section put the switcher above the rail-and-panel split; shell-chrome-app-header-collapsible-panels D1 (2026-09-14) moved it into the app header's center so it stayed reachable with the sidebar collapsed; bfdb629 later moved it to the header's right, beside the Agent picker. This explicitly overturns D1: the switcher is now the first child of `.sidebar-panel`, above Work (and above the Files / Changes / GitHub views — index.js already keeps it visible on every tab). Accepted consequence: with the sidebar collapsed (⌘B) the switcher is out of sight.

Changed: `index.html` markup moved out of `.lane-bar-launcher`; switcher CSS moved from `app-header.css` to `project-section.css` (full panel width, 28px); the header's `:not()` button selectors dropped the switcher classes; the tour's switcher step points right; the Guide text and shell sketch show it atop the sidebar (region renamed `sidebar-switcher`).
20 changes: 10 additions & 10 deletions .frame/STRUCTURE.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"version": "1.1",
"description": "Auto-generated module structure",
"lastUpdated": "2026-10-21",
"lastUpdated": "2026-10-23",
"architecture": {},
"modules": {
".claude/settings.json": {
Expand Down Expand Up @@ -290,7 +290,7 @@
"exports": [],
"depends": [],
"functions": {},
"sizeBytes": 93948,
"sizeBytes": 94121,
"extraction": {
"status": "unsupported",
"reason": "no-extractor"
Expand Down Expand Up @@ -9975,7 +9975,7 @@
"purpose": "Check the content against every rule the host relies on."
}
},
"sizeBytes": 35031,
"sizeBytes": 35030,
"extraction": {
"status": "parsed"
},
Expand Down Expand Up @@ -10060,7 +10060,7 @@
]
}
},
"sizeBytes": 35391,
"sizeBytes": 35392,
"extraction": {
"status": "parsed"
},
Expand Down Expand Up @@ -11108,7 +11108,7 @@
"ANALYTICS_EXCEPTION"
]
},
"sizeBytes": 38783,
"sizeBytes": 38779,
"extraction": {
"status": "parsed"
},
Expand Down Expand Up @@ -15071,7 +15071,7 @@
"exports": [],
"depends": [],
"functions": {},
"sizeBytes": 13599,
"sizeBytes": 9955,
"extraction": {
"status": "unsupported",
"reason": "no-extractor"
Expand Down Expand Up @@ -15203,7 +15203,7 @@
"exports": [],
"depends": [],
"functions": {},
"sizeBytes": 34666,
"sizeBytes": 34925,
"extraction": {
"status": "unsupported",
"reason": "no-extractor"
Expand Down Expand Up @@ -15275,7 +15275,7 @@
"exports": [],
"depends": [],
"functions": {},
"sizeBytes": 1869,
"sizeBytes": 5277,
"extraction": {
"status": "unsupported",
"reason": "no-extractor"
Expand Down Expand Up @@ -16906,7 +16906,7 @@
"purpose": "Mistakes in a step list, as readable strings; empty when it is sound."
}
},
"sizeBytes": 9836,
"sizeBytes": 9835,
"extraction": {
"status": "parsed"
},
Expand Down Expand Up @@ -28522,6 +28522,6 @@
"truncated": false,
"samples": []
},
"revision": "e28aa60c6d1aadcb35099ef01ea634ff7a26a2e1a4b3fdf3921cc7daa57cdd37"
"revision": "4098d30de66746721c76e982e2ba4e648a5e8256e018dc903adf04d08afa2e0a"
}
}
34 changes: 18 additions & 16 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@
markup on purpose — it exists before any script runs, so nothing in
it flashes at boot and every module that binds by id finds its
element at DOMContentLoaded. Left: Frame's mark. Right: the
project and agent pickers with Start, the window-level controls and
the layout toggles. appHeader.js wires the behavior. -->
agent picker with Start, the window-level controls and the layout
toggles. appHeader.js wires the behavior. -->
<header id="app-header">
<div class="app-header-left">
<!-- Frame's mark (assets/frame-mark.svg): the four corner brackets that
Expand All @@ -135,20 +135,6 @@
stale. The options below are a placeholder: aiToolSelector
repopulates from the real tool list. -->
<div class="lane-bar-launcher">
<!-- Current-project switcher: the one project selector, directly left
of the agent picker and drawn the same way (a small uppercase
label, then the value), so the header reads "Project · Agent ·
Start". index.js binds it by id. -->
<div id="sidebar-current-project-wrap" class="sidebar-current-project-wrap">
<button id="sidebar-current-project" class="sidebar-current-project" tabindex="-1" title="Switch project" aria-haspopup="true" aria-expanded="false">
<span class="sidebar-current-project-label">Project</span>
<span class="sidebar-current-project-name" id="sidebar-current-project-name">No project</span>
<svg class="sidebar-current-project-caret" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<polyline points="6 9 12 15 18 9"/>
</svg>
</button>
<div id="sidebar-project-menu" class="sidebar-project-menu" role="menu" hidden></div>
</div>
<!-- The select is wrapped in a label so the visible control (label
text, agent name, chevron) is one styled box while the native
<select> stays the interactive element underneath — clicking
Expand Down Expand Up @@ -283,6 +269,22 @@ <h4>Initialize as Frame Project</h4>
</nav>

<div class="sidebar-panel">
<!-- Current-project switcher: the one project selector, at the top of
the panel above Work (and above whatever view the rail picked), so
everything below it reads as "this project's". Moved back from
the app header on 2026-10-22 at the user's request, overturning
shell-chrome-app-header-collapsible-panels D1: with the sidebar
collapsed (⌘B) it is out of sight. index.js binds it by id. -->
<div id="sidebar-current-project-wrap" class="sidebar-current-project-wrap">
<button id="sidebar-current-project" class="sidebar-current-project" tabindex="-1" title="Switch project" aria-haspopup="true" aria-expanded="false">
<span class="sidebar-current-project-label">Project</span>
<span class="sidebar-current-project-name" id="sidebar-current-project-name">No project</span>
<svg class="sidebar-current-project-caret" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<polyline points="6 9 12 15 18 9"/>
</svg>
</button>
<div id="sidebar-project-menu" class="sidebar-project-menu" role="menu" hidden></div>
</div>
<!-- Projects view (default) — the workspace panel for the selected
project (project-dropdown spec): selection lives in the
current-project switcher above, which also carries "+ Add a
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/guide/guideContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const CHAPTERS = [
{
id: 'start.open',
title: 'Open a project',
sketch: { kind: 'shell', focus: 'header-switcher' },
sketch: { kind: 'shell', focus: 'sidebar-switcher' },
blocks: [
{ p: 'Everything in Frame happens inside a project. There are four ways in:' },
{ list: [
Expand All @@ -107,7 +107,7 @@ const CHAPTERS = [
'Clone a repository from GitHub by its URL.',
'Try the sample project — a small fictional codebase with specs, tasks and notes already filled in.'
] },
{ p: 'The project switcher in the middle of the header shows the current project; its menu lists your other projects and ends with “+ Add a project…”. The Welcome screen that greets you when Frame starts has all four too.' }
{ p: 'The project switcher at the top of the sidebar shows the current project; its menu lists your other projects and ends with “+ Add a project…”. The Welcome screen that greets you when Frame starts has all four too.' }
],
actions: [
{ id: 'project.add', label: 'Add a project' },
Expand Down
6 changes: 3 additions & 3 deletions src/renderer/guide/guideSketches.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const KINDS = {
},

/**
* The whole window. Regions: header-switcher, header-agent, header-start,
* The whole window. Regions: sidebar-switcher, header-agent, header-start,
* header-theme, rail-views, rail-foot, rail-guide, sidebar-nav, center,
* dock, statusbar-left, statusbar-right.
*/
Expand All @@ -127,7 +127,6 @@ const KINDS = {
const header = `
<div class="gs-shell-header">
<span class="gs-mark"></span>
${region('header-switcher', focused, 'gs-switcher', `${label('my-project')}${icon(ChevronDown, 10)}`)}
<div class="gs-header-right">
${region('header-agent', focused, 'gs-agent-picker', `${label('Agent', 'gs-dim')}${label('Claude Code')}${icon(ChevronDown, 10)}`)}
${region('header-start', focused, 'gs-start', `${icon(Play, 10)}${label('Start')}`)}
Expand All @@ -151,6 +150,7 @@ const KINDS = {
</div>`;

const sidebar = region('sidebar-nav', focused, 'gs-sidebar', `
${region('sidebar-switcher', focused, 'gs-switcher', `${label('my-project')}${icon(ChevronDown, 10)}`)}
<div class="gs-nav-group">${label('WORK', 'gs-eyebrow')}</div>
${navRow('Terminals')}
<div class="gs-nav-group">${label('CONTEXT', 'gs-eyebrow')}</div>
Expand Down Expand Up @@ -483,7 +483,7 @@ const KINDS = {
<div class="gs-dock-list">${bodies[active]}</div>`)}`);
},

/** Several projects. Regions: switcher (header + its menu), others (status bar popover). */
/** Several projects. Regions: switcher (sidebar + its menu), others (status bar popover). */
multiProject(focused) {
const proj = (name, badge, current) => `<div class="gs-proj-row${current ? ' gs-proj-current' : ''}">${icon(Folder, 10)}${label(name)}${badge || ''}</div>`;
const agentRow = (name, state, dot) => `<div class="gs-proj-row">${icon(Bot, 10)}${label(name)}${chip(state, { dot, cls: 'gs-chip-tiny' })}</div>`;
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ function setupButtonHandlers() {
// (status-bar spec). Binding it from here would attach a listener before
// the element exists.

// Current-project switcher (above the rail and the panel): reflects the
// Current-project switcher (top of the sidebar panel): reflects the
// active project and opens a dropdown to switch project without leaving
// the view.
const currentProjectNameEl = document.getElementById('sidebar-current-project-name');
Expand Down
Loading
Loading