fix(a11y): add type=button and aria-expanded to bare <button> elements — Batch 22 (QUA-200)#1548
Closed
hungdqdesign wants to merge 246 commits intopaperclipai:masterfrom
Closed
Conversation
…03 flood Add assertAgentRunCheckoutOwnership check to the document PUT endpoint, matching behavior of other issue mutation endpoints (PATCH, release, comments). Include retryable: false in conflict error details so agents stop retrying when checkout has expired or been reassigned. Closes #1256 Co-Authored-By: Paperclip <noreply@paperclip.ing> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ing tables When a database has existing tables but no drizzle migration journal (the "no-migration-journal-non-empty-db" case), applyPendingMigrations previously threw "automatic migration is unsafe". This blocked system PostgreSQL users from starting the server after upgrades. Now, applyPendingMigrations bootstraps the journal by walking each migration in order and checking whether its DDL objects (tables, columns, indexes, constraints) already exist in the schema. Migrations whose objects are present are recorded in the journal without re-running. The first migration with clearly absent objects is treated as genuinely pending and applied normally. Closes #1211 Co-Authored-By: Paperclip <noreply@paperclip.ing> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add test covering the checkout adoption path where logActivity is called with action "issue.checkout_lock_adopted" when a run takes over a stale checkout lock. Co-Authored-By: Paperclip <noreply@paperclip.ing>
…itor, preserve config on re-onboard - Add "gemini_local" to AGENT_ADAPTER_TYPES constant (fixes #1195) - Add null guard for MarkdownEditor value prop to prevent setMarkdown crash (fixes #1227) - Merge existing config.json values during onboard --yes instead of overwriting, preserving user customizations like server.host and deploymentMode (fixes #1196) Co-Authored-By: Paperclip <noreply@paperclip.ing>
…on insertion
Chrome/Chromium and Electron silently ignore document.execCommand("insertText"),
causing @mention selection to insert nothing. Switch to Range.deleteContents() +
Range.insertNode() with a synthetic InputEvent so Lexical picks up the change.
Adds defensive markdown state sync in case the InputEvent does not propagate.
Fixes #1294
Co-Authored-By: Paperclip <noreply@paperclip.ing>
…al status When a subtask status changes to done or cancelled, the parent task's assignee agent is now woken immediately via the heartbeat system. This enables manager agents to advance multi-step workflows without waiting for the next timer tick. Fixes #1280 Co-Authored-By: Paperclip <noreply@paperclip.ing>
After dependency updates, drizzle-orm 0.38.4 could not be resolved by some package managers, causing "Cannot find package drizzle-orm" errors at runtime. Upgrading to 0.41.0 across cli, db, and server packages resolves the issue. Closes GH #1243 Co-Authored-By: Paperclip <noreply@paperclip.ing>
… error better-auth@1.4.18 requires drizzle-orm >= 0.41.0 as a peer dependency. The previous version (0.38.4) did not satisfy this requirement, causing npm/npx installs to fail with "Cannot find package 'drizzle-orm'" when better-auth's drizzle adapter tried to import it. Fixes #1243 Co-Authored-By: Paperclip <noreply@paperclip.ing> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a child subtask transitions to done or cancelled, the parent issue's assigned agent now receives a wakeup with reason "child_issue_completed". This enables manager agents to react immediately to subtask completions instead of waiting for the next timer-based heartbeat interval. Co-Authored-By: Paperclip <noreply@paperclip.ing> 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>
…1245) The release() method only cleared assigneeAgentId and checkoutRunId but left executionRunId, executionAgentNameKey, and executionLockedAt intact. This caused permanent stale locks after unclean agent session ends, making subsequent checkout attempts return 409 Conflict with no recovery path other than direct SQL. Now release() nulls all three execution lock fields, matching the behavior of releaseIssueExecutionAndPromote() in the heartbeat service. Closes #1245 Co-Authored-By: Paperclip <noreply@paperclip.ing>
…ned deferred wakes (#1269) When an agent reassigns an issue via PATCH, the update cleared checkoutRunId but left executionRunId/executionAgentNameKey/ executionLockedAt intact. This caused the new assignee's wake to be deferred (waiting for the old execution to release), but releaseIssueExecutionAndPromote could not find the issue if the execution context had shifted, leaving the deferred wake permanently orphaned. Now, changing the assignee also clears all three execution lock fields, so the new assignee's wake goes through immediately without hitting the deferred path. Closes #1269 Co-Authored-By: Paperclip <noreply@paperclip.ing>
…wn crash (#1227) MDXEditor's setMarkdown() crashes with TypeError when receiving null (null.trim()). This happened when AgentConfigForm stored null for empty markdown fields (capabilities, bootstrapPromptTemplate) via the `v || null` pattern. Add `?? ""` guards in MarkdownEditor at the setMarkdown() call site and the initial markdown prop, so null values are safely coerced to empty strings. Closes #1227 Co-Authored-By: Paperclip <noreply@paperclip.ing>
…tibility (#1263) On Windows, Node.js ESM loader requires file:// URLs for dynamic imports. Raw absolute paths like C:\Users\... fail with ERR_UNSUPPORTED_ESM_URL_SCHEME. Use pathToFileURL() before calling import(), matching the pattern already used in cli/src/commands/run.ts. Co-Authored-By: Paperclip <noreply@paperclip.ing> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Node.js fetch/undici throws when GET or HEAD requests include a body. Skip body serialization and content-type header for these methods. Co-Authored-By: Paperclip <noreply@paperclip.ing> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ts' errors Fixes two issues causing GH #1352 (migration fails on fresh install): 1. applyPendingMigrationsManually now checks each SQL statement against the database state before executing it, skipping statements for objects that already exist (tables, columns, indexes, constraints). This makes migration application idempotent and safe for shared databases or partially-failed prior runs. 2. applyPendingMigrations now handles the 'no-migration-journal-non-empty-db' case gracefully instead of throwing. It reconciles the migration history from existing schema state and then applies remaining migrations with per-statement safety checks. Co-Authored-By: Paperclip <noreply@paperclip.ing>
- heartbeat.ts: fix deriveNormalizedUsageDelta to return 0 (not current value) when token counts are non-monotonic, preventing billing over/under-charge - costs.ts: add 'from > to' date range validation in parseDateRange to reject invalid date ranges early - issues.ts: replace non-null assertion (!) with explicit null check + notFound error on issue query results after checkout adoption - ui/vite.config.ts: add allowedHosts for paperclip.openclawbot.vn Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nt permission auto-reject (#1362) When an agent's instructions file lives outside the project cwd (e.g. in ~/.paperclip/instances/.../agents/), Claude CLI treats that directory as "external_directory" and auto-rejects permission requests. This causes a loop where the agent repeatedly requests and gets denied permission. Fix: pass the instructions file directory via --add-dir so Claude has read access to sibling files. Skip when the directory is already inside the project cwd to avoid redundant entries. 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>
Gateway only supports v2 payload format (without platform/deviceFamily fields). Adapter was building v3 payload causing Ed25519 signature mismatch → "device signature invalid". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove no-op reconcilePendingMigrationHistory call in the no-migration-journal-non-empty-db branch (P1: the function always returned early because inspectMigrations reports a different reason when the journal table doesn't exist yet) - Destructure reconcilePendingMigrationHistory result instead of assigning to unused variable (P2) - Remove hardcoded allowedHosts domain from shared Vite config (P2) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous exact-equality check only caught when instructionsFileDir was the skillsDir root itself, missing subdirectories. Using startsWith ensures any path under skillsDir is correctly skipped. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…#1391) Commander's .requiredOption() validates before the action handler runs, preventing resolveCommandContext() from applying context profile fallback for companyId. Switch to .option() and let resolveCommandContext() with requireCompany: true handle validation, which provides a better error message listing all alternatives (--company-id, env var, or context profile). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… without journal The no-migration-journal-non-empty-db branch was dead code: it called inspectMigrations again (which returned the same state since no journal table was created), then checked for "pending-migrations" reason which could never match, always falling through to throw. Fix: call applyPendingMigrationsManually directly with initialState.pendingMigrations. This function already handles the full flow: creates the journal table via ensureMigrationJournalTable, skips already-applied statements, and records each migration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-id (#1391) Commander.js .requiredOption() validates before the action handler runs, preventing resolveCommandContext() from applying the context profile or env var fallback. Change to .option() in all 7 occurrences across 5 files. The requireCompany check in resolveCommandContext() already provides a clear error message when no company ID is available from any source (flag, env var, or context profile). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cancelActiveForAgent sent SIGTERM but immediately deleted the process from runningProcesses, orphaning children that ignore SIGTERM. Now matches cancelRunInternal: schedules SIGKILL after graceSec and defers cleanup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ers from agent worktree modifications
Two branches (parent-wake-on-child-completion and subtask-completion-wakes-parent) added the same parent-wake logic. Removed the duplicate declaration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolved trivial ordering conflict in issues.ts patch fields. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolved conflict keeping HEAD variable naming (isBodyless). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolved conflict keeping master's simpler applyPendingMigrationsManually approach for non-empty DB migration bootstrap. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolved conflicts in onboarding assets keeping master versions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolved MarkdownEditor conflict keeping null-safe value guard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Post-merge fix: body was renamed to payload but reference wasn't updated. Also removed unused hasBody variable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s — Batch 22 (QUA-200)
HTML spec: <button> without explicit type defaults to type="submit" inside <form>.
Best practice: always declare type="button" for non-submit buttons.
Files fixed:
- agent-config-primitives.tsx CollapsibleSection: type=button + aria-expanded={open}
- NewGoalDialog.tsx: 7 popover trigger/option buttons — type=button
- NewProjectDialog.tsx: 4 popover trigger/option buttons — type=button
- GoalProperties.tsx: PopoverTrigger button — type=button
- PriorityIcon.tsx: priority selector trigger — type=button
- MarkdownEditor.tsx: @mention dropdown options — type=button
- SidebarAgents.tsx: "New agent" button — type=button
- FilterBar.tsx: "Remove filter" badge button — type=button
WCAG 2.1: programmatic correctness, prevents accidental form submission.
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
Thêm
type=\"button\"vào các<button>không có explicit type, vàaria-expandedvào CollapsibleSection.Root cause:
<button>không cótypemặc định làtype=\"submit\"bên trong<form>. Dù các dialogs này không dùng<form>, đây vẫn là best practice theo HTML spec và giúp tránh bug tiềm ẩn khi code được refactor.Files changed
agent-config-primitives.tsxCollapsibleSectiontype=\"button\"+aria-expanded={open}NewGoalDialog.tsxNewProjectDialog.tsxGoalProperties.tsxPriorityIcon.tsxMarkdownEditor.tsxSidebarAgents.tsxFilterBar.tsxA11Y notes
CollapsibleSection:aria-expanded={open}communicates expand/collapse state to screen readerstype=\"button\"— programmatic correctnessTest plan
npx tsc --noEmitpass ✅Closes QUA-200
🤖 Generated with Claude Code