fix(a11y): add aria attributes to AgentIconPicker, StatusIcon, PageTabBar, InlineEditor, PackageFileTree (QUA-193)#1532
Closed
hungdqdesign wants to merge 111 commits intopaperclipai:masterfrom
Closed
Conversation
… and add missing models (#1357) Cursor CLI now rejects "auto" as a model selection with "Cannot use this model: auto". Change the default to "composer-2" and add "composer-2" + "composer-2-fast" to the fallback model list. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…awbot.vn Add allowedHosts: "all" to vite server config so that requests from custom domain behind Cloudflare are not blocked. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ers from agent worktree modifications
… production deployments
Break the monolithic AgentDetail page into focused, maintainable modules: - AgentDetail.tsx: slim orchestrator (593 LOC, down from 3988) - agent-detail/OverviewTab.tsx: dashboard with charts, issues, costs - agent-detail/InstructionsTab.tsx: instructions bundle editor - agent-detail/ConfigurationTab.tsx: agent config form + permissions + keys - agent-detail/SkillsTab.tsx: skill management - agent-detail/RunsTab.tsx: run list + run detail (lazy loaded via React.lazy) - agent-detail/LogViewer.tsx: live transcript/log viewer - agent-detail/KeysTab.tsx: API key management - agent-detail/WorkspaceOperations.tsx: workspace operation UI - agent-detail/utils.ts: shared utilities and types RunsTab is lazy-loaded for better initial page performance. No functional changes — pure extraction refactor. QUA-123 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…calls When /agents/:id/wakeup is called directly (not via the checkout route), the contextSnapshot lacks issueId/projectId/workspaceId, causing the run to fall back to agent_home instead of the project workspace. Now enqueueWakeup auto-detects the agent's in-progress checked-out issue and enriches the context with issueId, projectId, and projectWorkspaceId. Also persists resolved projectId to contextSnapshot when only issueId was provided. Fixes #1387 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… locks (QUA-12) release() now clears executionRunId, executionAgentNameKey, and executionLockedAt alongside checkoutRunId. Previously these fields persisted after release, causing permanent stale locks that blocked re-checkout by other agents. Adds unit tests verifying all execution fields are nulled on release. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nsert (#QUA-91) Gemini adapter output sometimes contains null bytes (0x00) which PostgreSQL rejects in TEXT and JSONB columns. Add stripNullBytes() sanitization at the DB write layer (setRunStatus + appendRunEvent) to protect against any adapter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On Windows with WIN1252 system locale, child process stdout/stderr
default to the system encoding, causing crashes when adapter output
contains Unicode characters. Add setEncoding("utf8") on streams
immediately after spawn, matching the pattern used in codex-local.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…#1465) Users running adapters like codex_local with non-standard models (e.g. grok-4.20-beta) were blocked by the hardcoded model dropdown. Now: - ModelDropdown shows a "Use <custom>" option when search doesn't match any known model - InlineEntitySelector gains allowCustomValue prop for the same behavior - NewIssueDialog model override selector enables custom values - Custom model values display correctly in trigger buttons Closes #1465 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ers from agent worktree modifications
… production deployments
…nsert (#QUA-91) Gemini adapter output sometimes contains null bytes (0x00) which PostgreSQL rejects in TEXT and JSONB columns. Add stripNullBytes() sanitization at the DB write layer (setRunStatus + appendRunEvent) to protect against any adapter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On Windows with WIN1252 system locale, child process stdout/stderr
default to the system encoding, causing crashes when adapter output
contains Unicode characters. Add setEncoding("utf8") on streams
immediately after spawn, matching the pattern used in codex-local.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… and add missing models (#1357) Cursor CLI now rejects "auto" as a model selection with "Cannot use this model: auto". Change the default to "composer-2" and add "composer-2" + "composer-2-fast" to the fallback model list. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…awbot.vn Add allowedHosts: "all" to vite server config so that requests from custom domain behind Cloudflare are not blocked. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cancelActiveForAgentInternal now matches cancelRunInternal's escalation pattern: SIGTERM → grace period → SIGKILL. The runningProcesses entry is deferred until after the grace window to prevent orphaned processes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…1461) The codex adapter's getQuotaWindows spawns the codex CLI in its class constructor. If codex is not installed, spawn emits ENOENT which can crash the server when the Costs → Providers page is loaded. Wrap each adapter.getQuotaWindows() call in try-catch to handle both synchronous throws and async rejections gracefully. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…#1165) enqueueWakeup can throw (budget blocked, agent state conflict, etc). Without a try-catch inside the tickTimers loop, one failing agent aborts the entire tick — silently stopping all scheduled heartbeats. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… local_trusted mode
When a bearer token is present but fails validation (expired JWT, invalid key),
the default local_trusted board actor was not cleared, allowing unauthenticated
requests to inherit full board-level access. This enabled agents with expired
auth to perform destructive operations like deleting other agents.
Now clears the actor to { type: "none" } when a bearer token is present before
validation, so only successful verification restores the proper actor type.
Fixes #1314
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jwtConfig() only read PAPERCLIP_AGENT_JWT_SECRET, but server startup (index.ts) accepts BETTER_AUTH_SECRET as a fallback. When only BETTER_AUTH_SECRET is set (common in local dev), all agent runs failed to get PAPERCLIP_API_KEY injected. Align the fallback chain so local agents authenticate correctly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…th EPERM
On Windows without Developer Mode, symlink creation fails with EPERM.
The new symlinkOrCopy helper catches EPERM and falls back to
fs.cp(source, target, {recursive: true}), allowing skills to be
installed without requiring elevated privileges.
Closes #1464
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rt node cards (QUA-170)
…ment button (QUA-171) title attr is not reliably announced by screen readers — aria-label is correct. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-tabs refactor(ui): split AgentDetail.tsx into tab-based modules
fix(ui): allow custom model input for adapters
A queued heartbeat run that never started (startedAt IS NULL) is now treated as stale in isTerminalOrMissingHeartbeatRun(), allowing checkout to supersede its executionRunId lock. Also added a final fallback in checkout() that clears stale executionRunId locks regardless of issue status, preventing permanent 409 conflicts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… (QUA-165)
- aria-label={expanded ? "Collapse" : "Expand"} for screen reader context
- aria-expanded={expanded} to announce state changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e (QUA-166, QUA-167) - Projects page: add status filter bar (All / Backlog / Planned / In Progress / Completed) with count badges and localStorage persistence (key: projects:statusFilter) - ApprovalCard: show Loader2 spinner + "Approving..."/"Rejecting..." label while mutation is pending, so users get clear feedback on action progress Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cuments (QUA-189) - PropertiesPanel: Close button aria-label="Close properties panel" - NewGoalDialog: Expand/Minimize + Close buttons aria-label - NewProjectDialog: Expand/Minimize + Close buttons aria-label - Sidebar: Search button aria-label="Search" - NewAgentDialog: Close button aria-label="Close" - IssuesList: Add-issue-to-group button aria-label with group name - CompanySkills: Add skill button aria-label="Add skill" - IssueDetail: More options PopoverTrigger button aria-label="More options" - IssueDocumentsSection: Copy + Document actions buttons add aria-label alongside title WCAG 2.1 SC 4.1.2 (Name, Role, Value) — Level AA Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oard nav (QUA-168)
- Add scope="col" to all 6 <th> elements for screen reader compatibility
- Add aria-label="Routines" to <table> element
- Add tabIndex={0}, role="button", aria-label, and onKeyDown (Enter/Space)
to clickable <tr> rows so keyboard users can navigate to routine details
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…icCard onClick variants (QUA-169)
…A-183) CommentThread.tsx: - CopyMarkdownButton: add aria-label="Copy as markdown" - Sort toggle button: add aria-label matching sort state description - Attach image button: add aria-label="Attach image" IssueDetail.tsx: - Copy button (mobile + desktop): add aria-label="Copy issue as markdown" - Properties button (mobile): add aria-label="Show properties" - Properties button (desktop): add aria-label="Show properties" - Delete attachment button: add aria-label="Delete attachment" BudgetPolicyCard.tsx: - Add htmlFor="budget-policy-input" to label - Add id="budget-policy-input" to Input - Fixes WCAG 2.1 SC 1.3.1 form label association Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…on to load more (QUA-183) - Use React.useId() in BudgetPolicyCard to generate unique id per instance, preventing duplicate id when component renders in a loop (Costs page) - Add type="button" to Load more activity button in IssueDetail.tsx - Make CLI company-id option optional in activity/agent/dashboard commands Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Standardize the software development lifecycle for the Engineering team: intake → spec → dev → QA → release. Includes roles, checklists, templates, Definition of Done, and code review guidelines. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…9, QUA-170) Add visible focus indicators for keyboard navigation (WCAG 2.4.7): - EntityRow: focus-visible outline on clickable rows - MetricCard: focus-visible outline on onClick variant - OrgChart: focus-visible outline on node cards Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add missing aria-label attributes to 4 icon-only buttons: - Minimize/Maximize toggle button - Close button - Remove document button - Remove attachment button Fixes WCAG 2.1 SC 4.1.2 (Name, Role, Value) Level AA violations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ory leak (QUA-87, QUA-89) - budgets.ts: batch-fetch observed amounts to avoid N+1 queries in evaluateBudgetPolicies - heartbeat.ts: convert activeRunExecutions from Set to Map<runId, timestamp> with 4h TTL cleanup to prevent unbounded memory growth if entries are never removed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- docs/plans/sdlc-flowchart.md: Mermaid flowchart of intake → spec → dev → QA → release - docs/templates/spec-template.md: Implementation spec template for issue comments - docs/templates/qa-ux-a11y-checklist.md: QA/UX/A11Y review checklist template Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts: # ui/src/pages/IssueDetail.tsx
…bBar, InlineEditor, PackageFileTree (QUA-193) Batch 16 A11Y fixes: - AgentIconPicker: add aria-label to icon picker buttons (title alone not sufficient) - StatusIcon: wrap circle span in button with aria-label when !showLabel - PageTabBar: add aria-label="Select page" to mobile select element - InlineEditor: add role/tabIndex/onKeyDown to display mode clickable element - PackageFileTree: add aria-label to file row checkbox input Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
|
Too many files changed for review. ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
aria-label={name}cho icon picker buttons (trước đó chỉ dùngtitle)!showLabel, wrap circle trong<button>vớiaria-labelvàaria-haspopup="listbox"thay vì bare spanaria-label="Select page"cho mobile<select>role="button",tabIndex={0},onKeyDownhandler cho DisplayTag display modearia-label={\Select file: ${node.name}`}` cho file row checkboxA11Y Compliance
Test plan
npx tsc --noEmitpass — không có TypeScript errorsnpx vitest runpass — không có regressionsCloses QUA-193
🤖 Generated with Claude Code