690ca0306e855f19788cee912cba31af48fddaaf
16
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d0a2733cb6 |
fix(design): text on a tint of itself now clears AA app-wide, and the check gates it (#3141)
CI & Build / Plugin hooks (push) Successful in 11s
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 36s
CI & Build / integration (push) Successful in 34s
CI & Build / Python tests (push) Successful in 1m12s
CI & Build / Build & push image (push) Successful in 1m2s
The badge fix (#3132) exposed the same defect everywhere: 48 rules painting a token as TEXT on an inline color-mix tint of that same token. Worst raw measurements, across every tint strength in use, both modes, over page/raised/hover: accent 1.53:1 · success 1.67:1 · text-tertiary 2.15:1 warning 2.32:1 · error 2.36:1 against AA's 4.5 THE DEFECT IS IN THE HOUSE, NOT IN SCRIBE. The semantic hues are shared family-wide, and the accent case was measured against every app's real accent, not assumed from Scribe's: Minstrel 1.81, Forge 1.87, Steward 1.65, Roundtable 3.01 — all failing. So the six -fg tokens are recorded on FabledSword (design system 1), where their parents live, rather than copied into each app. 45% toward --fs-text-primary clears AA for ALL FIVE accents (4.56-5.00), so this is one house token rather than five overrides, and it keeps deriving from --fs-accent — an app that overrides its accent still gets a legible tinted-text colour in its own colour, the same mechanism as --fs-accent-soft. The tokens are additive: a sibling app is unaffected until it regenerates its own stylesheet. One token is honestly redundant. --fs-text-secondary already passes at 4.82:1, and --fs-text-secondary-fg barely moves it. It exists so the rule has NO exceptions, because the alternative is a permanent allow-list entry for the one case that happens to pass — and a guard with an invisible exception is a guard that erodes. 46 substitutions across 18 files, each rewriting only the `color:` inside a block that tints its own background. THE CHECK NOW GATES BOTH SPELLINGS. It previously reported the inline form, because a gate nobody can satisfy on the day it lands gets switched off. Both are clean, so both fail the build now. And the check had a false-positive bug worth naming: its `color\s*:` regex matched the tail of `border-color`, `border-left-color` and `outline-color`, so it flagged seven rules that were already correct. A border is a non-text graphic with a 3:1 floor, not text at 4.5. A check that cries wolf on correct code is one that gets muted, so that mattered more than the noise. Verified by construction, not by passing: reintroduced each defect form (exit 1 each), and confirmed a legitimate border-only rule still exits 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
ce1376edc9 |
refactor(ui): the badge layer gets one owner per shape (#3132 items 1-3)
CI & Build / Python lint (push) Successful in 5s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 33s
CI & Build / TypeScript typecheck (push) Successful in 40s
CI & Build / Python tests (push) Successful in 1m6s
CI & Build / Build & push image (push) Successful in 39s
ITEM 1 — the dead canon. StatusBadge is recorded canon (#2960) and its only consumer, TaskCard, has been unreachable since 2026-04-08, when TasksListView was deleted in favour of the Knowledge view. Four and a half months of a canon that rendered nowhere, which is worse than no canon: a session pulls #2960, builds from it, and matches a component nobody has seen. TaskCard is deleted (rule 22), and the canon is made real by adoption rather than by being left as a museum piece. ITEM 2 — MY OWN ISSUE OVERSTATED THIS, and the correction is the finding. "Three scoped re-spellings" assumed one shape spelled thrice. Reading them: KnowledgeView a task-status chip, just smaller -> a real duplicate WorkspaceTaskPanel a CLICKABLE cycler: pointer, outlined, transparent background -> a control, not a chip ProjectView PROJECT lifecycle (active/paused/ completed/archived) -> a different vocabulary Only the first was ever a duplicate. The others shared a class NAME and nothing else — which is exactly what would make a future consolidation merge three unrelated things. So: KnowledgeView adopts StatusBadge/PriorityBadge via the `compact` variant the canon already anticipated ("interactive/compact re-spellings are variants of it"); the cycler becomes `.status-cycler`; and project status becomes its own vocabulary. And there was a FOURTH, in ProjectListView — the genuine duplicate of ProjectView's project pill, differing by the amounts two hands differ by: 0.68rem vs 0.7rem, a 14% tint vs 15%, one bordered and one not. Both now use one ProjectStatusBadge. `statusLabel` went with its only caller. ITEM 3 — weight. StatusBadge and PriorityBadge used font-weight 600; the house style allows 400 and 500 only. Also "In Progress" -> "In progress", which was invisible under `text-transform: uppercase` and becomes visible the moment the compact variant turns that off. THE GUARD MISSED FOUR LIVE SITES, which is the part worth keeping. The project pills painted a hue on an inline `color-mix` tint of itself — measured 1.61-2.39:1 — and the checker only knew the `--fs-X-bg` token form. Widened, it finds 48 across the app, 26 of them --fs-accent. That backlog is not this task, so the check now splits: it GATES the token form, which is clean, and REPORTS the inline form with a count and its worst offenders. A gate nobody can satisfy today gets switched off, and then it guards nothing. Gate re-verified by reintroducing a defect — exit 1 with it, exit 0 without. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
a0b54ff6a3 |
feat(ui): task rows show their kind — a badge for issue and spike (#3124)
CI & Build / integration (push) Successful in 29s
CI & Build / Python tests (push) Successful in 1m3s
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / TypeScript typecheck (push) Successful in 10s
CI & Build / Build & push image (push) Successful in 32s
task_kind was only visible inside the task editor's Kind select, so every list surface rendered work, issue and spike identically and a list of tasks hid the fact that three different things were in it. ONE component, not a fifth spelling. The badge layer had already drifted — StatusBadge.vue is the recorded canon (#2960) but WorkspaceTaskPanel, ProjectView and KnowledgeView each carry their own scoped `.status-badge`. KindBadge is modelled on PriorityBadge, its closest sibling, which already does the thing that matters here: the DEFAULT value renders nothing. `work` is most tasks, so badging it would put a chip on nearly every row and say nothing — the same reason RuleListPane marks only `conditional`. COLOUR BY TEMPERATURE, measured rather than eyeballed. Issue and spike are opposite in character — corrective vs exploratory — so they split warm (warning) against cool (info), which survives being small and stays distinguishable without reading the word. Neither uses the accent; kind is not one of the places it is allowed. The raw semantic colour FAILS the contrast floor on the dark palette: warning on its own 12% tint measures 2.97:1 against AA's 4.5. So the text is the hue mixed toward --fs-text-primary, which passes and, because that token inverts by mode, follows light/dark for free. Measured both ways — issue 5.23:1 dark / 6.68:1 light, spike 5.33:1 / 9.26:1. `plan` renders hue-free and italic: retired since 0066, so a legacy row should read as archival rather than as a fourth kind competing for attention. In KnowledgeView it is passed as null instead, because the type badge beside it already says "Plan" and two chips reading the same word would look like two facts. Weight is 500, not the 600 the two older badges use — the house style allows 400 and 500 only, and copying 600 would spread it. SERVER FIX, without which this was decorative: dashboard's `_task_row` omitted task_kind entirely. The badge would have rendered nothing there while working everywhere else, which reads as "this list has no issues" rather than as a missing field. The guard is on the payload, where the omission was. Surfaces: ProjectView's three status columns, WorkspaceTaskPanel's two task lists, DashboardView's milestone and no-milestone rows, KnowledgeView's result rows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
2a6c55dacb |
refactor(frontend): auth-shared.css, apiErrorMessage, one date helper per shape, modal canon in components.css — the frontend pass of the shape audit (#2831 #2832, milestone 296)
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 22s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Python tests (push) Successful in 57s
CI & Build / Build & push image (push) Successful in 16s
- assets/auth-shared.css: the five auth views carried byte-identical scoped
copies of the page/card/brand/footer/field/input/error rules (~60 lines
each); they now load one stylesheet the way the editors load
editor-shared.css. .closed-msg/.error-block/.success-msg (identical bodies)
are one .auth-note; the form rules are scoped under .auth-card so nothing
leaks into the rest of the app.
- api/client.apiErrorMessage(e, fallback): the one place the {"error"} envelope
is unpacked; replaces ten six-line `"body" in e` catch blocks.
- utils/dateFormat: fmtDate / fmtStamp / fmtLogStamp replace eight local
formatDate/formatTime copies (three byte-identical pairs); the file’s old
Calendar/Home helpers had no callers and are gone. useRelativeTime gains
relativeTimeOrDate for the two workspace panels’ identical variant.
- components.css now owns the .modal-* shape (overlay/card/title/message/
actions/btn/primary/danger). It was copied into four views and lived in
editor-shared.css, which ConfirmDialog — styleless, teleported to <body> —
silently depended on: opened from SnippetDetailView before any editor view
had loaded, it rendered unstyled. Views keep only their own overrides.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
4ba544e2af |
refactor(theme): retire the --color-* shim — the sweep it promised, run
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 7s
CI & Build / integration (push) Successful in 17s
CI & Build / TypeScript typecheck (push) Successful in 34s
CI & Build / Python tests (push) Successful in 48s
CI & Build / Build & push image (push) Successful in 37s
#2533. theme.css claimed "removing this block is a rename sweep across the
components, tracked separately" — written in
|
||
|
|
bd60d679d9 |
refactor(theme): remove 184 var() fallbacks — every one was unreachable
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 16s
CI & Build / integration (push) Successful in 23s
CI & Build / TypeScript typecheck (push) Successful in 25s
CI & Build / Python tests (push) Successful in 57s
CI & Build / Build & push image (push) Successful in 43s
#2277 counted ~150 "raw colour literals bypassing the tokens". Measuring them told a different story: 184 sat in `var(--token, #fallback)` position, and a check against theme.css shows every one of those tokens IS declared. So the fallbacks could not render. Not drift — vestigial. They were also not this palette. The most common were Tailwind and Flat-UI defaults — #6366f1 indigo, #22c55e green, #f59e0b amber, #3b82f6 blue, #e74c3c and #27ae60 — a second, unsanctioned colour scheme sitting in the codebase looking like the app's colours to anyone reading it. Removing them is not tidying. #2319's lesson is that a fallback is WORSE than a missing token: a missing token renders as nothing and someone eventually notices, while a fallback renders something plausible forever. These 184 were one token rename away from silently repainting the app in Tailwind. The design token check would catch the rename — but the fallback is precisely the thing that would make it invisible if the check were ever bypassed. Literal count 152 -> 45, which matters beyond the number: a report that is mostly unreachable noise is one people stop reading, and then it stops working while still passing. What remains should be genuinely worth looking at. Done with a paren-aware transform, not a regex — `var(--x, rgba(0,0,0,.5))` nests parens and `[^)]+` would cut at the first one and leave `))` behind. Verified after: every changed line is a fallback strip and nothing else, and every var() reference still resolves. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs |
||
|
|
c7cf07824a |
refactor(ui): the two workspace panels migrate onto the shared buttons
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / TypeScript typecheck (push) Successful in 38s
CI & Build / Python tests (push) Canceled after 1m35s
CI & Build / integration (push) Canceled after 1m35s
CI & Build / Build & push image (push) Canceled after 0s
Eighteen bespoke button rules across the two densest components, replaced by
composition in the template. Net -279 lines.
These files are where the size taxonomy earns itself: almost every button here
is an inline affordance — a dismiss ×, a confirm tick, an add-chip — sitting
inside a card or a line of text. Forcing them to the standard 8/16px would have
broken the layouts, which is why the previous commit measured the clusters
before assuming a button is a button.
What the migration left behind is the useful signal. Each residual rule is now
one line stating only what the shared classes genuinely cannot:
.btn-add { font-size: 1rem; } a '+' glyph, not a label
.btn-search-clear { padding: 0; flex-shrink: 0; } sits in the field
.btn-suggest-tags { flex-shrink: 0; align-self: center; }
.btn-delete-task { margin-left: 0.25rem; }
Four residuals were deleted rather than kept, because the shared sheet already
said the same thing: a disabled opacity, two hover colours, and a danger-outline
hover fill. Keeping them would have recreated the drift in miniature.
Two accent hovers went with them. .btn-suggest-tags tinted its border and label
with the accent on hover, which is the same house-style violation corrected in
|
||
|
|
f491b6d7b9 |
refactor(ui): action buttons stop wearing the accent
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 7s
CI & Build / integration (push) Successful in 18s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Python tests (push) Successful in 46s
CI & Build / Build & push image (push) Successful in 47s
21 buttons filled with --color-primary, which resolves to Scribe's violet accent: every auth Submit (Login, Register, Invite, Forgot, Reset), plus Invite, Add, Confirm, Restore, Generate, Log-save, Subtask-confirm, Toggle-open, the modal primary, the version-restore, the inline-assist button, the milestone-plan actions, the task-advance hover, and both empty-state CTAs. The house style is explicit that the accent never appears on an action button: action colours are universal across the family precisely so a Save button looks identical in every app, while the accent carries identity. Doing both makes the accent mean two things and neither clearly. Operator's call, and the reasoning is worth keeping: the violet-on-Scribe- actions treatment was a deliberate early choice to give the web UI its own personality, made when much more of the app was user-facing. That is no longer true, so consistency is now worth more than the distinction it was buying. Found in two passes, which is the part worth noting. The first scan looked for `.btn-*` and found 13. Seven more were the same thing under different names — .modal-btn-primary, .vh-btn-restore, .inline-assist-btn, .empty-action, .task-advance-btn — plus .ms-plan-actions .btn-primary, a compound override flagged in the previous commit. Searching by naming convention finds what was named consistently, which is never the whole set. Deliberately NOT changed: progress-bar fills, active tab / page / selection states, tag-pill hover, the duration badge, the skip link, the assist pulse. Those are identity and active-state, which is exactly where the accent belongs. After this the accent appears only there, which is what makes it read as identity rather than as decoration. Colour swaps only — 25 lines changed, no geometry, no structure, no templates. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs |
||
|
|
4c9a637507 |
fix(theme): text on a filled colour needs its own token — the old one inverts
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 13s
CI & Build / integration (push) Successful in 29s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 55s
CI & Build / Build & push image (push) Successful in 41s
76 hardcoded `color: #fff` now resolve to --fs-text-on-action, a new token that is parchment in BOTH modes. The design system said they should supersede to --fs-text-primary, on the recorded reasoning that "there is no 'text on action' colour, there is just the text colour." That is true on dark and wrong on light. --fs-text-primary inverts to #14171A; the surfaces underneath it do not invert at all — every one of these 76 sits on an action colour, a semantic colour, the accent, or the CTA gradient, all of which hold a single value across modes. Sweeping as recorded would have put obsidian text on moss green: roughly 2.4:1, against a house style whose stated floor is WCAG AA. It would have looked correct to me, because I checked it in the mode where it was correct. --color-accent-fg had the same defect independently and is repointed too. The token check now reports zero superseded literals, down from 30 files, and raw colour literals drop 246 -> 169. Closes #2275. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaYUaouG9jjhATyuxCKrQs |
||
|
|
30dfbce426 |
fix(typography): strip chrome italic; reserve italic for emphasis
Per the design rule "italic is for emphasis, not for design", removed
every chrome `font-style: italic` declaration across the frontend.
42 declarations gone across 24 files: empty-state placeholder copy,
loading messages, "no results" hints, ghost text, voice/role labels,
field placeholder text, brand wordmark, et al.
Markdown content emphasis is unaffected — `<em>` and `<i>` tags from
`*emphasis*` markup still render italic via browser default styling
(prose.css doesn't override em behavior). User-typed emphasis in
notes, journal entries, and chat messages keeps its italic.
Specific spots that lost the decorative italic:
- KnowledgeView .filter-label, .empty-narrator
- NoteEditorView .ef-label, link-suggest related
- ChatPanel .empty-msg, .empty-greeting, .role-label
- ChatMessage .role-assistant .role-label (the "Fable" voice tag —
was italic per the doc's Illuminated Transcript spec, but per the
new typography rule the speaker tag stays regular and lets the
border-left + glow do the bubble framing on their own)
- AppHeader .brand-text ("Fabled" wordmark)
- editor-shared.css .title-input::placeholder
- ProjectView .project-title-input::placeholder
- HomeView .urgency-loading
- WorkspaceTaskPanel .empty-group
- WeatherCard .weather-unavailable
- SharedWithMeView .empty-msg
- DiffView empty-state spans
- ToolCallCard .tool-event-more
- SettingsView 7 spots (.you-label, .geo-pending, hint text, etc.)
- + several other empty-state / hint text spots
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
ff498ce1a4 |
feat(design): surface phase PR 5 — Project + Workspace polish
Per the surface-phase spec for the Project list, Project view, and
3-panel Workspace cluster:
Button reclassification per Hybrid rule
- ProjectView:
- btn-workspace ("Open Workspace"): kept on accent gradient — the
workspace is the project's central feature moment, a Scribe-
flavored action, brand moment per the doc.
- btn-share: muted-outline → Bronze action-secondary
- btn-danger-outline (Delete project): generic-border + danger-on-
hover → Oxblood outline + filled hover (proper destructive)
- btn-save-panel: accent gradient → Moss action-primary
- btn-ms-confirm (milestone confirm): flat accent → Moss
- btn-ms-cancel: ghost → Bronze action-secondary
- .modal-btn-danger: --color-danger → --color-action-destructive
- ProjectListView:
- btn-primary ("+ New Project"): flat accent → Moss action-primary.
Empty-state CTA (.empty-action) keeps accent — that *is* a
brand moment per Hybrid, "create your first project".
- WorkspaceTaskPanel + WorkspaceNoteEditor:
- btn-delete-task / btn-delete: hover --color-danger → Oxblood
- btn-delete-confirm / btn-confirm-delete: --color-danger pair →
--color-action-destructive pair, with filled hover for stronger
affordance
- btn-save (WorkspaceNoteEditor): flat accent → Moss
- WorkspaceChatWidget:
- History toggle: replaced unicode ▾ with Lucide ChevronDown
(PR 1 carry-over for emoji-as-icon)
Two-weights-only
- Snapped every font-weight 600/700 to 500 across the cluster.
Borders kept (per structural-not-decorative rule)
- Milestone group cards: standalone containers, keep
- Project cards in list: standalone containers, keep
- Task slide-over panel: drawer modal, keep
- Workspace 3-panel separators: major section dividers, keep
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
93a3beb5d6 |
feat(design): surface phase PR 1 — Lucide icon migration + scale enforcement
Replaces every hand-inlined SVG in the chrome (60 across 15 files) with Lucide components. Snaps icon sizes to the doc's 16/24 scale — all icons in this pass land at 16. AppLogo wordmark stays as the legitimate "custom app icon" exception per the doc; GraphView's <svg> mount point for D3 stays as well. Replaces emoji-as-icons in clear button-affordance cases with their Lucide equivalents: ✕ → X (close/dismiss buttons across 8 files), ✓ → Check (ProjectView task-advance button), 🎤 → Mic (ChatPanel voice CTA), 📎 → Paperclip (ChatView context toggle), ↑ → ArrowUp (ChatInputBar Send), × → X (ChatPanel context-note remove), ☀/☾ → Sun/Moon (AppHeader theme toggle). Inline emoji punctuation in textual confirmation copy ("Saved ✓", "Created ✓", `done: "✓"` status maps, `'✓' : '📄'` interpolations) is left for surface-phase voice/tone touchups — replacing requires structural template changes and is best done per-component. Stroke weight stays at Lucide's default 2px; tightening to the doc's 1.5/1 is deferred per the surface-phase spec (option ii: drop-in + scale enforcement). Adds lucide-vue-next ^0.469.0 to frontend/package.json. Docker rebuild handles the install. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
71301f631d |
Workspace UI overhaul: rail note panel, split task detail, project goal header
- WorkspaceNoteEditor: replace toggling list/editor views with always-visible
left rail (155px) showing note list alongside editor pane; persist last-open
note per project in localStorage (workspace_note_{projectId})
- WorkspaceTaskPanel: add priority dot + due date on task rows; replace full
overlay detail with bottom-split (44% list / 56% detail); close button
replaces back nav; active row highlighted; fade transition
- WorkspaceView: show project goal in header instead of 'Workspace'; non-equal
panel widths (0.8fr / 1.1fr / 1.1fr); empty chat quick-action chips (Project
status / New note / Add tasks); prefill() helper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|
|
ef141f07f8 |
UI polish pass: word count, slash commands, task lists, graph peek, bulk delete, export
- WordCount component (toggle words/chars vs read time, persisted mode) - TipTap: TaskList/TaskItem extensions, slash command menu (H1-H3, lists, code, quote, task) - Markdown serializer: task list → `- [ ]` / `- [x]` roundtrip - GraphView: slide-in peek panel for note/task nodes (body, tags, linked nodes); tag nodes still navigate - ChatView: bulk-select conversations with two-click confirm delete + chat retention policy (default 90d) - NoteEditorView: pill tab bar with animated edit/preview toggle + WordCount in toolbar - WorkspaceNoteEditor: inline search with tag matching, inline new-note creation, WordCount - WorkspaceTaskPanel: task body rendered in slide-over + Edit link - Settings: data export (Markdown ZIP / JSON) via GET /api/export - Accessibility: skip-to-content link, aria-labels on all icon-only buttons - Fix: export route used non-existent fabledassistant.database — corrected to async_session() - Fix: ToolCallRecord.status type now includes "running" (was causing TS build error) - Dockerfile: upgrade npm to latest before install to suppress major-version notice - npm audit fix: patched minimatch (ReDoS) and rollup (path traversal) — 0 vulnerabilities Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
320e879788 |
Workspace polish: milestone selector, streaming fix, push fix, log quieting
- WorkspaceTaskPanel: add milestone <select> in task detail (PATCH /api/notes/:id), replace delete ✕ with trash can SVG icon - WorkspaceView: scroll to bottom when streaming ends so final message is visible without a page refresh - ToolCallCard: fix search_notes result count (was reading data.total; tool returns data.count), so results no longer show "0 found" - push.py: switch from deprecated WebPusher().send(vapid_private_key=...) to webpush() function (pywebpush 2.x API compatibility) - app.py: downgrade /api/health, /api/chat/status, and static asset requests from INFO to DEBUG in after_request logger to reduce log noise at default log level Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
74ebb8a87f |
Project Workspace view, abort button, session invalidation, workspace fixes
Workspace (/workspace/:projectId): - Three-panel layout (tasks / chat / notes) with CSS grid collapse toggles - WorkspaceTaskPanel: tasks grouped by milestone, collapsible groups, task detail slide-over with status cycling, TaskLogSection work log, and inline-confirm delete - WorkspaceNoteEditor: list view (sorted by updated_at, inline tag pills, inline-confirm delete) with editor view (TipTap, TagInput, Suggest tags, 60s autosave) - Persistent workspace conversation stored in localStorage per project; reused on return visits - Thinking enabled (think: true) with Reasoning block in streaming bubble - workspace_project_id backend pipeline: chat.py → generation_task.py → llm.py; system prompt uses project title so agent passes project="Title" to tools (fixes create_note failing with numeric project string) - SSE tool-call watcher bridges agent actions to panel updates - Height fix: workspace-root uses height 100%; app-content switches to overflow hidden via :has() selector - Entry point: "Open Workspace" button on ProjectView Abort button: - Stop button in ChatView header and WorkspaceView input bar - Calls existing cancelGeneration() / POST .../generation/cancel Session invalidation: - POST /api/auth/invalidate-sessions bumps session_version, keeps current session alive; useful after SSO/OAuth password rotation - Button in Settings → Active Sessions section Other: - Dashboard recent notes limit increased from 8 to 16 - Workspace chat abort replaces Send button while streaming Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |