2026-04-07 18:26:34 -05:00
|
|
|
import type {
|
|
|
|
|
Approval,
|
|
|
|
|
DashboardSummary,
|
|
|
|
|
HeartbeatRun,
|
|
|
|
|
InboxDismissal,
|
|
|
|
|
Issue,
|
|
|
|
|
JoinRequest,
|
|
|
|
|
} from "@paperclipai/shared";
|
2026-04-10 22:26:21 -05:00
|
|
|
import {
|
2026-04-11 06:49:23 -05:00
|
|
|
applyIssueFilters,
|
2026-04-10 22:26:21 -05:00
|
|
|
defaultIssueFilterState,
|
Sync/master post pap1497 followups 2026 04 15 (#3779)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - The board depends on issue, inbox, cost, and company-skill surfaces
to stay accurate and fast while agents are actively working
> - The PAP-1497 follow-up branch exposed a few rough edges in those
surfaces: stale active-run state on completed issues, missing creator
filters, oversized issue payload scans, and placeholder issue-route
parsing
> - Those gaps make the control plane harder to trust because operators
can see misleading run state, miss the right subset of work, or pay
extra query/render cost on large issue records
> - This pull request tightens those follow-ups across server and UI
code, and adds regression coverage for the affected paths
> - The benefit is a more reliable issue workflow, safer high-volume
cost aggregation, and clearer board/operator navigation
## What Changed
- Added the `v2026.415.0` release changelog entry.
- Fixed stale issue-run presentation after completion and reused the
shared issue-path parser so literal route placeholders no longer become
issue links.
- Added creator filters to the Issues page and Inbox, including
persisted filter-state normalization and regression coverage.
- Bounded issue detail/list project-mention scans and trimmed large
issue-list payload fields to keep issue reads lighter.
- Hardened company-skill list projection and cost/finance aggregation so
large markdown blobs and large summed values do not leak into list
responses or overflow 32-bit casts.
- Added targeted server/UI regression tests for company skills,
costs/finance, issue mention scanning, creator filters, inbox
normalization, and issue reference parsing.
## Verification
- `pnpm exec vitest run
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/costs-service.test.ts
server/src/__tests__/issues-goal-context-routes.test.ts
server/src/__tests__/issues-service.test.ts ui/src/lib/inbox.test.ts
ui/src/lib/issue-filters.test.ts ui/src/lib/issue-reference.test.ts`
- `gh pr checks 3779`
Current pass set on the PR head: `policy`, `verify`, `e2e`,
`security/snyk (cryppadotta)`, `Greptile Review`
## Risks
- Creator filter options are derived from the currently loaded
issue/agent data, so very sparse result sets may not surface every
historical creator until they appear in the active dataset.
- Cost/finance aggregate casts now use `double precision`; that removes
the current overflow risk, but future schema changes should keep
large-value aggregation behavior under review.
- Issue detail mention scanning now skips comment-body scans on the
detail route, so any consumer that relied on comment-only project
mentions there would need to fetch them separately.
## Model Used
- OpenAI Codex, GPT-5-based coding agent with terminal tool use and
local code execution in the Paperclip workspace. Exact internal model
ID/context-window exposure is not surfaced in this session.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-15 21:13:56 -05:00
|
|
|
normalizeIssueFilterState,
|
2026-04-10 22:26:21 -05:00
|
|
|
type IssueFilterState,
|
|
|
|
|
} from "./issue-filters";
|
Improve operator workflow QoL (#5291)
## Thinking Path
> - Paperclip is a control plane operators use repeatedly to supervise
agent companies.
> - Common operator workflows depend on fast scanning of inboxes, issue
sidebars, workspaces, cost totals, and runtime services.
> - Several small UI and service gaps made those workflows slower or
less clear.
> - This pull request groups the operator-facing QoL changes that can
stand alone from recovery and adapter work.
> - The benefit is a denser, clearer board experience for issue triage
and workspace operation.
## What Changed
- Added inbox assignee/project grouping and issue list token/runtime
totals.
- Improved issue properties with removable blocker chips and workspace
task links.
- Improved execution workspace layout, runtime controls, issues tab
default, and stopped-port reuse behavior.
- Added mobile markdown/routine dialog fixes, page title company names,
sidebar polish, and dashboard run task label cleanup.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/lib/inbox.test.ts
ui/src/components/IssueProperties.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
server/src/__tests__/workspace-runtime.test.ts
server/src/__tests__/costs-service.test.ts`
## Risks
- Medium UI risk because this touches several operator surfaces. The
branch is intentionally grouped around workflow/QoL files and keeps the
file count below the Greptile limit.
## Model Used
- OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with
shell/git/GitHub CLI tool use.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:30:44 -05:00
|
|
|
import { formatAssigneeUserLabel } from "./assignees";
|
2026-03-10 22:55:45 -05:00
|
|
|
|
|
|
|
|
export const RECENT_ISSUES_LIMIT = 100;
|
|
|
|
|
export const FAILED_RUN_STATUSES = new Set(["failed", "timed_out"]);
|
|
|
|
|
export const ACTIONABLE_APPROVAL_STATUSES = new Set(["pending", "revision_requested"]);
|
|
|
|
|
export const DISMISSED_KEY = "paperclip:inbox:dismissed";
|
2026-03-26 10:16:19 -05:00
|
|
|
export const READ_ITEMS_KEY = "paperclip:inbox:read-items";
|
2026-03-11 07:42:19 -05:00
|
|
|
export const INBOX_LAST_TAB_KEY = "paperclip:inbox:last-tab";
|
2026-04-02 11:45:15 -05:00
|
|
|
export const INBOX_ISSUE_COLUMNS_KEY = "paperclip:inbox:issue-columns";
|
2026-04-08 08:07:31 -05:00
|
|
|
export const INBOX_NESTING_KEY = "paperclip:inbox:nesting";
|
2026-04-09 10:26:17 -05:00
|
|
|
export const INBOX_GROUP_BY_KEY = "paperclip:inbox:group-by";
|
2026-04-10 22:26:21 -05:00
|
|
|
export const INBOX_FILTER_PREFERENCES_KEY_PREFIX = "paperclip:inbox:filters";
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
export const INBOX_COLLAPSED_GROUPS_KEY_PREFIX = "paperclip:inbox:collapsed-groups";
|
2026-03-26 08:19:16 -05:00
|
|
|
export type InboxTab = "mine" | "recent" | "unread" | "all";
|
2026-04-10 22:26:21 -05:00
|
|
|
export type InboxCategoryFilter =
|
|
|
|
|
| "everything"
|
|
|
|
|
| "issues_i_touched"
|
|
|
|
|
| "join_requests"
|
|
|
|
|
| "approvals"
|
|
|
|
|
| "failed_runs"
|
|
|
|
|
| "alerts";
|
2026-03-17 16:10:26 -05:00
|
|
|
export type InboxApprovalFilter = "all" | "actionable" | "resolved";
|
Improve operator workflow QoL (#5291)
## Thinking Path
> - Paperclip is a control plane operators use repeatedly to supervise
agent companies.
> - Common operator workflows depend on fast scanning of inboxes, issue
sidebars, workspaces, cost totals, and runtime services.
> - Several small UI and service gaps made those workflows slower or
less clear.
> - This pull request groups the operator-facing QoL changes that can
stand alone from recovery and adapter work.
> - The benefit is a denser, clearer board experience for issue triage
and workspace operation.
## What Changed
- Added inbox assignee/project grouping and issue list token/runtime
totals.
- Improved issue properties with removable blocker chips and workspace
task links.
- Improved execution workspace layout, runtime controls, issues tab
default, and stopped-port reuse behavior.
- Added mobile markdown/routine dialog fixes, page title company names,
sidebar polish, and dashboard run task label cleanup.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/lib/inbox.test.ts
ui/src/components/IssueProperties.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
server/src/__tests__/workspace-runtime.test.ts
server/src/__tests__/costs-service.test.ts`
## Risks
- Medium UI risk because this touches several operator surfaces. The
branch is intentionally grouped around workflow/QoL files and keeps the
file count below the Greptile limit.
## Model Used
- OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with
shell/git/GitHub CLI tool use.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:30:44 -05:00
|
|
|
export type InboxWorkItemGroupBy = "none" | "type" | "assignee" | "project" | "workspace";
|
2026-04-10 22:26:21 -05:00
|
|
|
export const inboxIssueColumns = [
|
|
|
|
|
"status",
|
|
|
|
|
"id",
|
|
|
|
|
"assignee",
|
|
|
|
|
"project",
|
|
|
|
|
"workspace",
|
|
|
|
|
"parent",
|
|
|
|
|
"labels",
|
|
|
|
|
"updated",
|
|
|
|
|
] as const;
|
2026-04-02 11:45:15 -05:00
|
|
|
export type InboxIssueColumn = (typeof inboxIssueColumns)[number];
|
|
|
|
|
export const DEFAULT_INBOX_ISSUE_COLUMNS: InboxIssueColumn[] = ["status", "id", "updated"];
|
2026-04-10 22:26:21 -05:00
|
|
|
export interface InboxFilterPreferences {
|
|
|
|
|
allCategoryFilter: InboxCategoryFilter;
|
|
|
|
|
allApprovalFilter: InboxApprovalFilter;
|
|
|
|
|
issueFilters: IssueFilterState;
|
|
|
|
|
}
|
2026-03-17 16:19:00 -05:00
|
|
|
export type InboxWorkItem =
|
|
|
|
|
| {
|
|
|
|
|
kind: "issue";
|
|
|
|
|
timestamp: number;
|
|
|
|
|
issue: Issue;
|
|
|
|
|
}
|
|
|
|
|
| {
|
|
|
|
|
kind: "approval";
|
|
|
|
|
timestamp: number;
|
|
|
|
|
approval: Approval;
|
2026-03-19 07:24:52 -05:00
|
|
|
}
|
|
|
|
|
| {
|
|
|
|
|
kind: "failed_run";
|
|
|
|
|
timestamp: number;
|
|
|
|
|
run: HeartbeatRun;
|
2026-03-24 07:53:05 -05:00
|
|
|
}
|
|
|
|
|
| {
|
|
|
|
|
kind: "join_request";
|
|
|
|
|
timestamp: number;
|
|
|
|
|
joinRequest: JoinRequest;
|
2026-03-17 16:19:00 -05:00
|
|
|
};
|
2026-03-10 22:55:45 -05:00
|
|
|
|
|
|
|
|
export interface InboxBadgeData {
|
|
|
|
|
inbox: number;
|
|
|
|
|
approvals: number;
|
|
|
|
|
failedRuns: number;
|
|
|
|
|
joinRequests: number;
|
2026-03-26 08:19:16 -05:00
|
|
|
mineIssues: number;
|
2026-03-10 22:55:45 -05:00
|
|
|
alerts: number;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 10:26:17 -05:00
|
|
|
export interface InboxWorkItemGroup {
|
|
|
|
|
key: string;
|
|
|
|
|
label: string | null;
|
|
|
|
|
items: InboxWorkItem[];
|
|
|
|
|
}
|
|
|
|
|
|
[codex] improve issue and routine UI responsiveness (#3744)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Operators rely on issue, inbox, and routine views to understand what
the company is doing in real time
> - Those views need to stay fast and readable even when issue lists,
markdown comments, and run metadata get large
> - The current branch had a coherent set of UI and live-update
improvements spread across issue search, issue detail rendering, routine
affordances, and workspace lookups
> - This pull request groups those board-facing changes into one
standalone branch that can merge independently of the heartbeat/runtime
work
> - The benefit is a faster, clearer issue and routine workflow without
changing the underlying task model
## What Changed
- Show routine execution issues by default and rename the filter to
`Hide routine runs` so the default state no longer looks like an active
filter.
- Show the routine name in the run dialog and tighten the issue
properties pane with a workspace link, copy-on-click behavior, and an
inline parent arrow.
- Reduce issue detail rerenders, keep queued issue chat mounted, improve
issues page search responsiveness, and speed up issues first paint.
- Add inbox "other search results", refresh visible issue runs after
status updates, and optimize workspace lookups through summary-mode
execution workspace queries.
- Improve markdown wrapping and scrolling behavior for long strings and
self-comment code blocks.
- Relax the markdown sanitizer assertion so the test still validates
safety after the new wrap-friendly inline styles.
## Verification
- `pnpm vitest run ui/src/components/IssuesList.test.tsx
ui/src/lib/inbox.test.ts ui/src/pages/Issues.test.tsx
ui/src/context/BreadcrumbContext.test.tsx
ui/src/context/LiveUpdatesProvider.test.ts
ui/src/components/MarkdownBody.test.tsx
ui/src/api/execution-workspaces.test.ts
server/src/__tests__/execution-workspaces-routes.test.ts`
## Risks
- This touches several issue-facing UI surfaces at once, so regressions
would most likely show up as stale rendering, search result mismatches,
or small markdown presentation differences.
- The workspace lookup optimization depends on the summary-mode route
shape staying aligned between server and UI.
## Model Used
- OpenAI Codex, GPT-5-based coding agent in the Codex CLI environment.
Exact backend model deployment ID was not exposed in-session.
Tool-assisted editing and shell execution were used.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-15 15:54:05 -05:00
|
|
|
export type InboxSearchSection = "none" | "archived" | "other";
|
|
|
|
|
|
|
|
|
|
export interface InboxGroupedSection {
|
|
|
|
|
key: string;
|
|
|
|
|
label: string | null;
|
|
|
|
|
displayItems: InboxWorkItem[];
|
|
|
|
|
childrenByIssueId: Map<string, Issue[]>;
|
|
|
|
|
searchSection: InboxSearchSection;
|
|
|
|
|
}
|
|
|
|
|
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
export interface InboxKeyboardGroupSection {
|
|
|
|
|
key: string;
|
[codex] Polish issue board workflows (#4224)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Human operators supervise that work through issue lists, issue
detail, comments, inbox groups, markdown references, and
profile/activity surfaces
> - The branch had many small UI fixes that improve the operator loop
but do not need to ship with backend runtime migrations
> - These changes belong together as board workflow polish because they
affect scanning, navigation, issue context, comment state, and markdown
clarity
> - This pull request groups the UI-only slice so it can merge
independently from runtime/backend changes
> - The benefit is a clearer board experience with better issue context,
steadier optimistic updates, and more predictable keyboard navigation
## What Changed
- Improves issue properties, sub-issue actions, blocker chips, and issue
list/detail refresh behavior.
- Adds blocker context above the issue composer and stabilizes
queued/interrupted comment UI state.
- Improves markdown issue/GitHub link rendering and opens external
markdown links in a new tab.
- Adds inbox group keyboard navigation and fold/unfold support.
- Polishes activity/avatar/profile/settings/workspace presentation
details.
## Verification
- `pnpm exec vitest run ui/src/components/IssueProperties.test.tsx
ui/src/components/IssueChatThread.test.tsx
ui/src/components/MarkdownBody.test.tsx ui/src/lib/inbox.test.ts
ui/src/lib/optimistic-issue-comments.test.ts`
## Risks
- Low to medium risk: changes are UI-focused but cover high-traffic
issue and inbox surfaces.
- This branch intentionally does not include the backend runtime changes
from the companion PR; where UI calls newer API filters, unsupported
servers should continue to fail visibly through existing API error
handling.
- Visual screenshots were not captured in this heartbeat; targeted
component/helper tests cover the changed behavior.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5-based coding agent runtime, shell/git tool use
enabled. Exact hosted model build and context window are not exposed in
this Paperclip heartbeat environment.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-04-21 12:25:34 -05:00
|
|
|
label?: string | null;
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
displayItems: InboxWorkItem[];
|
|
|
|
|
childrenByIssueId: ReadonlyMap<string, Issue[]>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type InboxKeyboardNavEntry =
|
[codex] Polish issue board workflows (#4224)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Human operators supervise that work through issue lists, issue
detail, comments, inbox groups, markdown references, and
profile/activity surfaces
> - The branch had many small UI fixes that improve the operator loop
but do not need to ship with backend runtime migrations
> - These changes belong together as board workflow polish because they
affect scanning, navigation, issue context, comment state, and markdown
clarity
> - This pull request groups the UI-only slice so it can merge
independently from runtime/backend changes
> - The benefit is a clearer board experience with better issue context,
steadier optimistic updates, and more predictable keyboard navigation
## What Changed
- Improves issue properties, sub-issue actions, blocker chips, and issue
list/detail refresh behavior.
- Adds blocker context above the issue composer and stabilizes
queued/interrupted comment UI state.
- Improves markdown issue/GitHub link rendering and opens external
markdown links in a new tab.
- Adds inbox group keyboard navigation and fold/unfold support.
- Polishes activity/avatar/profile/settings/workspace presentation
details.
## Verification
- `pnpm exec vitest run ui/src/components/IssueProperties.test.tsx
ui/src/components/IssueChatThread.test.tsx
ui/src/components/MarkdownBody.test.tsx ui/src/lib/inbox.test.ts
ui/src/lib/optimistic-issue-comments.test.ts`
## Risks
- Low to medium risk: changes are UI-focused but cover high-traffic
issue and inbox surfaces.
- This branch intentionally does not include the backend runtime changes
from the companion PR; where UI calls newer API filters, unsupported
servers should continue to fail visibly through existing API error
handling.
- Visual screenshots were not captured in this heartbeat; targeted
component/helper tests cover the changed behavior.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5-based coding agent runtime, shell/git tool use
enabled. Exact hosted model build and context window are not exposed in
this Paperclip heartbeat environment.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-04-21 12:25:34 -05:00
|
|
|
| {
|
|
|
|
|
type: "group";
|
|
|
|
|
groupKey: string;
|
|
|
|
|
label: string;
|
|
|
|
|
collapsed: boolean;
|
|
|
|
|
}
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
| {
|
|
|
|
|
type: "top";
|
|
|
|
|
itemKey: string;
|
|
|
|
|
item: InboxWorkItem;
|
|
|
|
|
}
|
|
|
|
|
| {
|
|
|
|
|
type: "child";
|
|
|
|
|
issueId: string;
|
|
|
|
|
issue: Issue;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export interface InboxProjectWorkspaceLookup {
|
|
|
|
|
name: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface InboxExecutionWorkspaceLookup {
|
|
|
|
|
name: string;
|
|
|
|
|
mode: "shared_workspace" | "isolated_workspace" | "operator_branch" | "adapter_managed" | "cloud_sandbox";
|
|
|
|
|
projectWorkspaceId: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface InboxWorkspaceGroupingOptions {
|
|
|
|
|
executionWorkspaceById?: ReadonlyMap<string, InboxExecutionWorkspaceLookup>;
|
|
|
|
|
projectWorkspaceById?: ReadonlyMap<string, InboxProjectWorkspaceLookup>;
|
|
|
|
|
defaultProjectWorkspaceIdByProjectId?: ReadonlyMap<string, string>;
|
Improve operator workflow QoL (#5291)
## Thinking Path
> - Paperclip is a control plane operators use repeatedly to supervise
agent companies.
> - Common operator workflows depend on fast scanning of inboxes, issue
sidebars, workspaces, cost totals, and runtime services.
> - Several small UI and service gaps made those workflows slower or
less clear.
> - This pull request groups the operator-facing QoL changes that can
stand alone from recovery and adapter work.
> - The benefit is a denser, clearer board experience for issue triage
and workspace operation.
## What Changed
- Added inbox assignee/project grouping and issue list token/runtime
totals.
- Improved issue properties with removable blocker chips and workspace
task links.
- Improved execution workspace layout, runtime controls, issues tab
default, and stopped-port reuse behavior.
- Added mobile markdown/routine dialog fixes, page title company names,
sidebar polish, and dashboard run task label cleanup.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/lib/inbox.test.ts
ui/src/components/IssueProperties.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
server/src/__tests__/workspace-runtime.test.ts
server/src/__tests__/costs-service.test.ts`
## Risks
- Medium UI risk because this touches several operator surfaces. The
branch is intentionally grouped around workflow/QoL files and keeps the
file count below the Greptile limit.
## Model Used
- OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with
shell/git/GitHub CLI tool use.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:30:44 -05:00
|
|
|
projectById?: ReadonlyMap<string, { name: string | null | undefined }>;
|
|
|
|
|
agentById?: ReadonlyMap<string, string | null | undefined>;
|
|
|
|
|
userLabelById?: ReadonlyMap<string, string>;
|
|
|
|
|
currentUserId?: string | null;
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-10 22:26:21 -05:00
|
|
|
const defaultInboxFilterPreferences: InboxFilterPreferences = {
|
|
|
|
|
allCategoryFilter: "everything",
|
|
|
|
|
allApprovalFilter: "all",
|
|
|
|
|
issueFilters: defaultIssueFilterState,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function normalizeInboxCategoryFilter(value: unknown): InboxCategoryFilter {
|
|
|
|
|
return value === "issues_i_touched"
|
|
|
|
|
|| value === "join_requests"
|
|
|
|
|
|| value === "approvals"
|
|
|
|
|
|| value === "failed_runs"
|
|
|
|
|
|| value === "alerts"
|
|
|
|
|
? value
|
|
|
|
|
: "everything";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function normalizeInboxApprovalFilter(value: unknown): InboxApprovalFilter {
|
|
|
|
|
return value === "actionable" || value === "resolved" ? value : "all";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getInboxFilterPreferencesStorageKey(companyId: string | null | undefined): string | null {
|
|
|
|
|
if (!companyId) return null;
|
|
|
|
|
return `${INBOX_FILTER_PREFERENCES_KEY_PREFIX}:${companyId}`;
|
|
|
|
|
}
|
|
|
|
|
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
function getInboxCollapsedGroupsStorageKey(companyId: string | null | undefined): string | null {
|
|
|
|
|
if (!companyId) return null;
|
|
|
|
|
return `${INBOX_COLLAPSED_GROUPS_KEY_PREFIX}:${companyId}`;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-10 22:26:21 -05:00
|
|
|
export function loadInboxFilterPreferences(
|
|
|
|
|
companyId: string | null | undefined,
|
|
|
|
|
): InboxFilterPreferences {
|
|
|
|
|
const storageKey = getInboxFilterPreferencesStorageKey(companyId);
|
|
|
|
|
if (!storageKey) {
|
|
|
|
|
return {
|
|
|
|
|
...defaultInboxFilterPreferences,
|
|
|
|
|
issueFilters: { ...defaultIssueFilterState },
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const raw = localStorage.getItem(storageKey);
|
|
|
|
|
if (!raw) {
|
|
|
|
|
return {
|
|
|
|
|
...defaultInboxFilterPreferences,
|
|
|
|
|
issueFilters: { ...defaultIssueFilterState },
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
const parsed = JSON.parse(raw) as Record<string, unknown>;
|
|
|
|
|
return {
|
|
|
|
|
allCategoryFilter: normalizeInboxCategoryFilter(parsed.allCategoryFilter),
|
|
|
|
|
allApprovalFilter: normalizeInboxApprovalFilter(parsed.allApprovalFilter),
|
|
|
|
|
issueFilters: normalizeIssueFilterState(parsed.issueFilters),
|
|
|
|
|
};
|
|
|
|
|
} catch {
|
|
|
|
|
return {
|
|
|
|
|
...defaultInboxFilterPreferences,
|
|
|
|
|
issueFilters: { ...defaultIssueFilterState },
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function saveInboxFilterPreferences(
|
|
|
|
|
companyId: string | null | undefined,
|
|
|
|
|
preferences: InboxFilterPreferences,
|
|
|
|
|
) {
|
|
|
|
|
const storageKey = getInboxFilterPreferencesStorageKey(companyId);
|
|
|
|
|
if (!storageKey) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem(
|
|
|
|
|
storageKey,
|
|
|
|
|
JSON.stringify({
|
|
|
|
|
allCategoryFilter: normalizeInboxCategoryFilter(preferences.allCategoryFilter),
|
|
|
|
|
allApprovalFilter: normalizeInboxApprovalFilter(preferences.allApprovalFilter),
|
|
|
|
|
issueFilters: normalizeIssueFilterState(preferences.issueFilters),
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
} catch {
|
|
|
|
|
// Ignore localStorage failures.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
export function loadCollapsedInboxGroupKeys(
|
|
|
|
|
companyId: string | null | undefined,
|
|
|
|
|
): Set<string> {
|
|
|
|
|
const storageKey = getInboxCollapsedGroupsStorageKey(companyId);
|
|
|
|
|
if (!storageKey) return new Set();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const raw = localStorage.getItem(storageKey);
|
|
|
|
|
if (!raw) return new Set();
|
|
|
|
|
const parsed = JSON.parse(raw);
|
Sync/master post pap1497 followups 2026 04 15 (#3779)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - The board depends on issue, inbox, cost, and company-skill surfaces
to stay accurate and fast while agents are actively working
> - The PAP-1497 follow-up branch exposed a few rough edges in those
surfaces: stale active-run state on completed issues, missing creator
filters, oversized issue payload scans, and placeholder issue-route
parsing
> - Those gaps make the control plane harder to trust because operators
can see misleading run state, miss the right subset of work, or pay
extra query/render cost on large issue records
> - This pull request tightens those follow-ups across server and UI
code, and adds regression coverage for the affected paths
> - The benefit is a more reliable issue workflow, safer high-volume
cost aggregation, and clearer board/operator navigation
## What Changed
- Added the `v2026.415.0` release changelog entry.
- Fixed stale issue-run presentation after completion and reused the
shared issue-path parser so literal route placeholders no longer become
issue links.
- Added creator filters to the Issues page and Inbox, including
persisted filter-state normalization and regression coverage.
- Bounded issue detail/list project-mention scans and trimmed large
issue-list payload fields to keep issue reads lighter.
- Hardened company-skill list projection and cost/finance aggregation so
large markdown blobs and large summed values do not leak into list
responses or overflow 32-bit casts.
- Added targeted server/UI regression tests for company skills,
costs/finance, issue mention scanning, creator filters, inbox
normalization, and issue reference parsing.
## Verification
- `pnpm exec vitest run
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/costs-service.test.ts
server/src/__tests__/issues-goal-context-routes.test.ts
server/src/__tests__/issues-service.test.ts ui/src/lib/inbox.test.ts
ui/src/lib/issue-filters.test.ts ui/src/lib/issue-reference.test.ts`
- `gh pr checks 3779`
Current pass set on the PR head: `policy`, `verify`, `e2e`,
`security/snyk (cryppadotta)`, `Greptile Review`
## Risks
- Creator filter options are derived from the currently loaded
issue/agent data, so very sparse result sets may not surface every
historical creator until they appear in the active dataset.
- Cost/finance aggregate casts now use `double precision`; that removes
the current overflow risk, but future schema changes should keep
large-value aggregation behavior under review.
- Issue detail mention scanning now skips comment-body scans on the
detail route, so any consumer that relied on comment-only project
mentions there would need to fetch them separately.
## Model Used
- OpenAI Codex, GPT-5-based coding agent with terminal tool use and
local code execution in the Paperclip workspace. Exact internal model
ID/context-window exposure is not surfaced in this session.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-15 21:13:56 -05:00
|
|
|
return new Set(Array.isArray(parsed) ? parsed.filter((entry): entry is string => typeof entry === "string") : []);
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
} catch {
|
|
|
|
|
return new Set();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function saveCollapsedInboxGroupKeys(
|
|
|
|
|
companyId: string | null | undefined,
|
|
|
|
|
groupKeys: ReadonlySet<string>,
|
|
|
|
|
) {
|
|
|
|
|
const storageKey = getInboxCollapsedGroupsStorageKey(companyId);
|
|
|
|
|
if (!storageKey) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem(storageKey, JSON.stringify([...groupKeys]));
|
|
|
|
|
} catch {
|
|
|
|
|
// Ignore localStorage failures.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 18:26:34 -05:00
|
|
|
export function loadDismissedInboxAlerts(): Set<string> {
|
2026-03-10 22:55:45 -05:00
|
|
|
try {
|
|
|
|
|
const raw = localStorage.getItem(DISMISSED_KEY);
|
2026-04-07 18:26:34 -05:00
|
|
|
if (!raw) return new Set();
|
|
|
|
|
const parsed = JSON.parse(raw);
|
|
|
|
|
if (!Array.isArray(parsed)) return new Set();
|
|
|
|
|
return new Set(parsed.filter((value): value is string => typeof value === "string" && value.startsWith("alert:")));
|
2026-03-10 22:55:45 -05:00
|
|
|
} catch {
|
|
|
|
|
return new Set();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 18:26:34 -05:00
|
|
|
export function saveDismissedInboxAlerts(ids: Set<string>) {
|
2026-03-11 07:42:19 -05:00
|
|
|
try {
|
|
|
|
|
localStorage.setItem(DISMISSED_KEY, JSON.stringify([...ids]));
|
|
|
|
|
} catch {
|
|
|
|
|
// Ignore localStorage failures.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 18:26:34 -05:00
|
|
|
export function buildInboxDismissedAtByKey(dismissals: InboxDismissal[]): Map<string, number> {
|
|
|
|
|
return new Map(
|
|
|
|
|
dismissals.map((dismissal) => [dismissal.itemKey, normalizeTimestamp(dismissal.dismissedAt)]),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isInboxEntityDismissed(
|
|
|
|
|
dismissedAtByKey: ReadonlyMap<string, number>,
|
|
|
|
|
itemKey: string,
|
|
|
|
|
activityAt: string | Date | null | undefined,
|
|
|
|
|
): boolean {
|
|
|
|
|
const dismissedAt = dismissedAtByKey.get(itemKey);
|
|
|
|
|
if (dismissedAt == null) return false;
|
|
|
|
|
return dismissedAt >= normalizeTimestamp(activityAt);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 10:16:19 -05:00
|
|
|
export function loadReadInboxItems(): Set<string> {
|
|
|
|
|
try {
|
|
|
|
|
const raw = localStorage.getItem(READ_ITEMS_KEY);
|
|
|
|
|
return raw ? new Set(JSON.parse(raw)) : new Set();
|
|
|
|
|
} catch {
|
|
|
|
|
return new Set();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function saveReadInboxItems(ids: Set<string>) {
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem(READ_ITEMS_KEY, JSON.stringify([...ids]));
|
|
|
|
|
} catch {
|
|
|
|
|
// Ignore localStorage failures.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 11:45:15 -05:00
|
|
|
export function normalizeInboxIssueColumns(columns: Iterable<string | InboxIssueColumn>): InboxIssueColumn[] {
|
|
|
|
|
const selected = new Set(columns);
|
|
|
|
|
return inboxIssueColumns.filter((column) => selected.has(column));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getAvailableInboxIssueColumns(enableWorkspaceColumn: boolean): InboxIssueColumn[] {
|
|
|
|
|
if (enableWorkspaceColumn) return [...inboxIssueColumns];
|
|
|
|
|
return inboxIssueColumns.filter((column) => column !== "workspace");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function loadInboxIssueColumns(): InboxIssueColumn[] {
|
|
|
|
|
try {
|
|
|
|
|
const raw = localStorage.getItem(INBOX_ISSUE_COLUMNS_KEY);
|
|
|
|
|
if (raw === null) return DEFAULT_INBOX_ISSUE_COLUMNS;
|
|
|
|
|
const parsed = JSON.parse(raw);
|
|
|
|
|
if (!Array.isArray(parsed)) return DEFAULT_INBOX_ISSUE_COLUMNS;
|
|
|
|
|
return normalizeInboxIssueColumns(parsed);
|
|
|
|
|
} catch {
|
|
|
|
|
return DEFAULT_INBOX_ISSUE_COLUMNS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function saveInboxIssueColumns(columns: InboxIssueColumn[]) {
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem(
|
|
|
|
|
INBOX_ISSUE_COLUMNS_KEY,
|
|
|
|
|
JSON.stringify(normalizeInboxIssueColumns(columns)),
|
|
|
|
|
);
|
|
|
|
|
} catch {
|
|
|
|
|
// Ignore localStorage failures.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 10:26:17 -05:00
|
|
|
export function loadInboxWorkItemGroupBy(): InboxWorkItemGroupBy {
|
|
|
|
|
try {
|
|
|
|
|
const raw = localStorage.getItem(INBOX_GROUP_BY_KEY);
|
Improve operator workflow QoL (#5291)
## Thinking Path
> - Paperclip is a control plane operators use repeatedly to supervise
agent companies.
> - Common operator workflows depend on fast scanning of inboxes, issue
sidebars, workspaces, cost totals, and runtime services.
> - Several small UI and service gaps made those workflows slower or
less clear.
> - This pull request groups the operator-facing QoL changes that can
stand alone from recovery and adapter work.
> - The benefit is a denser, clearer board experience for issue triage
and workspace operation.
## What Changed
- Added inbox assignee/project grouping and issue list token/runtime
totals.
- Improved issue properties with removable blocker chips and workspace
task links.
- Improved execution workspace layout, runtime controls, issues tab
default, and stopped-port reuse behavior.
- Added mobile markdown/routine dialog fixes, page title company names,
sidebar polish, and dashboard run task label cleanup.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/lib/inbox.test.ts
ui/src/components/IssueProperties.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
server/src/__tests__/workspace-runtime.test.ts
server/src/__tests__/costs-service.test.ts`
## Risks
- Medium UI risk because this touches several operator surfaces. The
branch is intentionally grouped around workflow/QoL files and keeps the
file count below the Greptile limit.
## Model Used
- OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with
shell/git/GitHub CLI tool use.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:30:44 -05:00
|
|
|
return raw === "type" || raw === "assignee" || raw === "project" || raw === "workspace" ? raw : "none";
|
2026-04-09 10:26:17 -05:00
|
|
|
} catch {
|
|
|
|
|
return "none";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function saveInboxWorkItemGroupBy(groupBy: InboxWorkItemGroupBy) {
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem(INBOX_GROUP_BY_KEY, groupBy);
|
|
|
|
|
} catch {
|
|
|
|
|
// Ignore localStorage failures.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
export function shouldResetInboxWorkspaceGrouping(
|
|
|
|
|
groupBy: InboxWorkItemGroupBy,
|
|
|
|
|
isolatedWorkspacesEnabled: boolean,
|
|
|
|
|
experimentalSettingsLoaded: boolean,
|
|
|
|
|
): boolean {
|
|
|
|
|
return experimentalSettingsLoaded && groupBy === "workspace" && !isolatedWorkspacesEnabled;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 10:26:17 -05:00
|
|
|
export function shouldIncludeRoutineExecutionIssue(
|
|
|
|
|
issue: Pick<Issue, "originKind">,
|
[codex] improve issue and routine UI responsiveness (#3744)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Operators rely on issue, inbox, and routine views to understand what
the company is doing in real time
> - Those views need to stay fast and readable even when issue lists,
markdown comments, and run metadata get large
> - The current branch had a coherent set of UI and live-update
improvements spread across issue search, issue detail rendering, routine
affordances, and workspace lookups
> - This pull request groups those board-facing changes into one
standalone branch that can merge independently of the heartbeat/runtime
work
> - The benefit is a faster, clearer issue and routine workflow without
changing the underlying task model
## What Changed
- Show routine execution issues by default and rename the filter to
`Hide routine runs` so the default state no longer looks like an active
filter.
- Show the routine name in the run dialog and tighten the issue
properties pane with a workspace link, copy-on-click behavior, and an
inline parent arrow.
- Reduce issue detail rerenders, keep queued issue chat mounted, improve
issues page search responsiveness, and speed up issues first paint.
- Add inbox "other search results", refresh visible issue runs after
status updates, and optimize workspace lookups through summary-mode
execution workspace queries.
- Improve markdown wrapping and scrolling behavior for long strings and
self-comment code blocks.
- Relax the markdown sanitizer assertion so the test still validates
safety after the new wrap-friendly inline styles.
## Verification
- `pnpm vitest run ui/src/components/IssuesList.test.tsx
ui/src/lib/inbox.test.ts ui/src/pages/Issues.test.tsx
ui/src/context/BreadcrumbContext.test.tsx
ui/src/context/LiveUpdatesProvider.test.ts
ui/src/components/MarkdownBody.test.tsx
ui/src/api/execution-workspaces.test.ts
server/src/__tests__/execution-workspaces-routes.test.ts`
## Risks
- This touches several issue-facing UI surfaces at once, so regressions
would most likely show up as stale rendering, search result mismatches,
or small markdown presentation differences.
- The workspace lookup optimization depends on the summary-mode route
shape staying aligned between server and UI.
## Model Used
- OpenAI Codex, GPT-5-based coding agent in the Codex CLI environment.
Exact backend model deployment ID was not exposed in-session.
Tool-assisted editing and shell execution were used.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-15 15:54:05 -05:00
|
|
|
hideRoutineExecutions: boolean,
|
2026-04-09 10:26:17 -05:00
|
|
|
): boolean {
|
[codex] improve issue and routine UI responsiveness (#3744)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Operators rely on issue, inbox, and routine views to understand what
the company is doing in real time
> - Those views need to stay fast and readable even when issue lists,
markdown comments, and run metadata get large
> - The current branch had a coherent set of UI and live-update
improvements spread across issue search, issue detail rendering, routine
affordances, and workspace lookups
> - This pull request groups those board-facing changes into one
standalone branch that can merge independently of the heartbeat/runtime
work
> - The benefit is a faster, clearer issue and routine workflow without
changing the underlying task model
## What Changed
- Show routine execution issues by default and rename the filter to
`Hide routine runs` so the default state no longer looks like an active
filter.
- Show the routine name in the run dialog and tighten the issue
properties pane with a workspace link, copy-on-click behavior, and an
inline parent arrow.
- Reduce issue detail rerenders, keep queued issue chat mounted, improve
issues page search responsiveness, and speed up issues first paint.
- Add inbox "other search results", refresh visible issue runs after
status updates, and optimize workspace lookups through summary-mode
execution workspace queries.
- Improve markdown wrapping and scrolling behavior for long strings and
self-comment code blocks.
- Relax the markdown sanitizer assertion so the test still validates
safety after the new wrap-friendly inline styles.
## Verification
- `pnpm vitest run ui/src/components/IssuesList.test.tsx
ui/src/lib/inbox.test.ts ui/src/pages/Issues.test.tsx
ui/src/context/BreadcrumbContext.test.tsx
ui/src/context/LiveUpdatesProvider.test.ts
ui/src/components/MarkdownBody.test.tsx
ui/src/api/execution-workspaces.test.ts
server/src/__tests__/execution-workspaces-routes.test.ts`
## Risks
- This touches several issue-facing UI surfaces at once, so regressions
would most likely show up as stale rendering, search result mismatches,
or small markdown presentation differences.
- The workspace lookup optimization depends on the summary-mode route
shape staying aligned between server and UI.
## Model Used
- OpenAI Codex, GPT-5-based coding agent in the Codex CLI environment.
Exact backend model deployment ID was not exposed in-session.
Tool-assisted editing and shell execution were used.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-15 15:54:05 -05:00
|
|
|
return !hideRoutineExecutions || issue.originKind !== "routine_execution";
|
2026-04-09 10:26:17 -05:00
|
|
|
}
|
|
|
|
|
|
[codex] improve issue and routine UI responsiveness (#3744)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Operators rely on issue, inbox, and routine views to understand what
the company is doing in real time
> - Those views need to stay fast and readable even when issue lists,
markdown comments, and run metadata get large
> - The current branch had a coherent set of UI and live-update
improvements spread across issue search, issue detail rendering, routine
affordances, and workspace lookups
> - This pull request groups those board-facing changes into one
standalone branch that can merge independently of the heartbeat/runtime
work
> - The benefit is a faster, clearer issue and routine workflow without
changing the underlying task model
## What Changed
- Show routine execution issues by default and rename the filter to
`Hide routine runs` so the default state no longer looks like an active
filter.
- Show the routine name in the run dialog and tighten the issue
properties pane with a workspace link, copy-on-click behavior, and an
inline parent arrow.
- Reduce issue detail rerenders, keep queued issue chat mounted, improve
issues page search responsiveness, and speed up issues first paint.
- Add inbox "other search results", refresh visible issue runs after
status updates, and optimize workspace lookups through summary-mode
execution workspace queries.
- Improve markdown wrapping and scrolling behavior for long strings and
self-comment code blocks.
- Relax the markdown sanitizer assertion so the test still validates
safety after the new wrap-friendly inline styles.
## Verification
- `pnpm vitest run ui/src/components/IssuesList.test.tsx
ui/src/lib/inbox.test.ts ui/src/pages/Issues.test.tsx
ui/src/context/BreadcrumbContext.test.tsx
ui/src/context/LiveUpdatesProvider.test.ts
ui/src/components/MarkdownBody.test.tsx
ui/src/api/execution-workspaces.test.ts
server/src/__tests__/execution-workspaces-routes.test.ts`
## Risks
- This touches several issue-facing UI surfaces at once, so regressions
would most likely show up as stale rendering, search result mismatches,
or small markdown presentation differences.
- The workspace lookup optimization depends on the summary-mode route
shape staying aligned between server and UI.
## Model Used
- OpenAI Codex, GPT-5-based coding agent in the Codex CLI environment.
Exact backend model deployment ID was not exposed in-session.
Tool-assisted editing and shell execution were used.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-15 15:54:05 -05:00
|
|
|
export function filterInboxIssues(issues: Issue[], hideRoutineExecutions: boolean): Issue[] {
|
|
|
|
|
if (!hideRoutineExecutions) return issues;
|
|
|
|
|
return issues.filter((issue) => shouldIncludeRoutineExecutionIssue(issue, hideRoutineExecutions));
|
2026-04-09 10:26:17 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-10 22:26:21 -05:00
|
|
|
export function matchesInboxIssueSearch(
|
|
|
|
|
issue: Pick<Issue, "title" | "identifier" | "description" | "executionWorkspaceId" | "projectId" | "projectWorkspaceId">,
|
|
|
|
|
query: string,
|
|
|
|
|
{
|
|
|
|
|
isolatedWorkspacesEnabled = false,
|
|
|
|
|
executionWorkspaceById,
|
|
|
|
|
projectWorkspaceById,
|
|
|
|
|
defaultProjectWorkspaceIdByProjectId,
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
}: InboxWorkspaceGroupingOptions & {
|
2026-04-10 22:26:21 -05:00
|
|
|
isolatedWorkspacesEnabled?: boolean;
|
|
|
|
|
} = {},
|
|
|
|
|
): boolean {
|
|
|
|
|
const normalizedQuery = query.trim().toLowerCase();
|
|
|
|
|
if (!normalizedQuery) return true;
|
|
|
|
|
if (issue.title.toLowerCase().includes(normalizedQuery)) return true;
|
|
|
|
|
if (issue.identifier?.toLowerCase().includes(normalizedQuery)) return true;
|
|
|
|
|
if (issue.description?.toLowerCase().includes(normalizedQuery)) return true;
|
|
|
|
|
if (!isolatedWorkspacesEnabled) return false;
|
|
|
|
|
|
|
|
|
|
const workspaceName = resolveIssueWorkspaceName(issue, {
|
|
|
|
|
executionWorkspaceById,
|
|
|
|
|
projectWorkspaceById,
|
|
|
|
|
defaultProjectWorkspaceIdByProjectId,
|
|
|
|
|
});
|
|
|
|
|
return workspaceName?.toLowerCase().includes(normalizedQuery) ?? false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getArchivedInboxSearchIssues({
|
|
|
|
|
visibleIssues,
|
|
|
|
|
searchableIssues,
|
|
|
|
|
query,
|
|
|
|
|
isolatedWorkspacesEnabled = false,
|
|
|
|
|
executionWorkspaceById,
|
|
|
|
|
projectWorkspaceById,
|
|
|
|
|
defaultProjectWorkspaceIdByProjectId,
|
|
|
|
|
}: {
|
|
|
|
|
visibleIssues: Issue[];
|
|
|
|
|
searchableIssues: Issue[];
|
|
|
|
|
query: string;
|
|
|
|
|
isolatedWorkspacesEnabled?: boolean;
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
executionWorkspaceById?: ReadonlyMap<string, InboxExecutionWorkspaceLookup>;
|
|
|
|
|
projectWorkspaceById?: ReadonlyMap<string, InboxProjectWorkspaceLookup>;
|
2026-04-10 22:26:21 -05:00
|
|
|
defaultProjectWorkspaceIdByProjectId?: ReadonlyMap<string, string>;
|
|
|
|
|
}): Issue[] {
|
|
|
|
|
const normalizedQuery = query.trim();
|
|
|
|
|
if (!normalizedQuery) return [];
|
|
|
|
|
|
|
|
|
|
const visibleIssueIds = new Set(visibleIssues.map((issue) => issue.id));
|
|
|
|
|
return searchableIssues
|
|
|
|
|
.filter((issue) => !visibleIssueIds.has(issue.id))
|
|
|
|
|
.filter((issue) =>
|
|
|
|
|
matchesInboxIssueSearch(issue, normalizedQuery, {
|
|
|
|
|
isolatedWorkspacesEnabled,
|
|
|
|
|
executionWorkspaceById,
|
|
|
|
|
projectWorkspaceById,
|
|
|
|
|
defaultProjectWorkspaceIdByProjectId,
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
.sort(sortIssuesByMostRecentActivity);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 06:57:49 -05:00
|
|
|
export function getInboxSearchSupplementIssues({
|
2026-04-11 06:49:23 -05:00
|
|
|
query,
|
|
|
|
|
filteredWorkItems,
|
|
|
|
|
archivedSearchIssues,
|
|
|
|
|
remoteIssues,
|
|
|
|
|
issueFilters,
|
|
|
|
|
currentUserId,
|
|
|
|
|
enableRoutineVisibilityFilter = false,
|
2026-04-24 15:50:32 -05:00
|
|
|
liveIssueIds,
|
2026-04-11 06:49:23 -05:00
|
|
|
}: {
|
|
|
|
|
query: string;
|
|
|
|
|
filteredWorkItems: InboxWorkItem[];
|
|
|
|
|
archivedSearchIssues: Issue[];
|
|
|
|
|
remoteIssues: Issue[];
|
|
|
|
|
issueFilters: IssueFilterState;
|
|
|
|
|
currentUserId?: string | null;
|
|
|
|
|
enableRoutineVisibilityFilter?: boolean;
|
2026-04-24 15:50:32 -05:00
|
|
|
liveIssueIds?: ReadonlySet<string>;
|
2026-04-11 06:49:23 -05:00
|
|
|
}): Issue[] {
|
|
|
|
|
const normalizedQuery = query.trim();
|
|
|
|
|
if (!normalizedQuery) return [];
|
2026-04-11 06:57:49 -05:00
|
|
|
const visibleIssueIds = new Set([
|
|
|
|
|
...filteredWorkItems
|
|
|
|
|
.filter((item): item is Extract<InboxWorkItem, { kind: "issue" }> => item.kind === "issue")
|
|
|
|
|
.map((item) => item.issue.id),
|
|
|
|
|
...archivedSearchIssues.map((issue) => issue.id),
|
|
|
|
|
]);
|
2026-04-24 15:50:32 -05:00
|
|
|
return applyIssueFilters(remoteIssues, issueFilters, currentUserId, enableRoutineVisibilityFilter, liveIssueIds)
|
2026-04-11 06:57:49 -05:00
|
|
|
.filter((issue) => !visibleIssueIds.has(issue.id));
|
2026-04-11 06:49:23 -05:00
|
|
|
}
|
|
|
|
|
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
function formatDefaultWorkspaceGroupLabel(name: string | null | undefined): string {
|
|
|
|
|
const normalizedName = name?.trim();
|
|
|
|
|
return normalizedName ? `${normalizedName} (default)` : "Default workspace";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function resolveDefaultProjectWorkspaceInfo(
|
|
|
|
|
issue: Pick<Issue, "projectId">,
|
|
|
|
|
{
|
|
|
|
|
projectWorkspaceById,
|
|
|
|
|
defaultProjectWorkspaceIdByProjectId,
|
|
|
|
|
}: Pick<InboxWorkspaceGroupingOptions, "projectWorkspaceById" | "defaultProjectWorkspaceIdByProjectId">,
|
|
|
|
|
): { id: string; label: string } | null {
|
|
|
|
|
if (!issue.projectId) return null;
|
|
|
|
|
const defaultProjectWorkspaceId = defaultProjectWorkspaceIdByProjectId?.get(issue.projectId) ?? null;
|
|
|
|
|
if (!defaultProjectWorkspaceId) return null;
|
|
|
|
|
return {
|
|
|
|
|
id: defaultProjectWorkspaceId,
|
|
|
|
|
label: formatDefaultWorkspaceGroupLabel(projectWorkspaceById?.get(defaultProjectWorkspaceId)?.name),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 11:45:15 -05:00
|
|
|
export function resolveIssueWorkspaceName(
|
|
|
|
|
issue: Pick<Issue, "executionWorkspaceId" | "projectId" | "projectWorkspaceId">,
|
|
|
|
|
{
|
|
|
|
|
executionWorkspaceById,
|
|
|
|
|
projectWorkspaceById,
|
|
|
|
|
defaultProjectWorkspaceIdByProjectId,
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
}: InboxWorkspaceGroupingOptions,
|
2026-04-02 11:45:15 -05:00
|
|
|
): string | null {
|
|
|
|
|
const defaultProjectWorkspaceId = issue.projectId
|
|
|
|
|
? defaultProjectWorkspaceIdByProjectId?.get(issue.projectId) ?? null
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
if (issue.executionWorkspaceId) {
|
|
|
|
|
const executionWorkspace = executionWorkspaceById?.get(issue.executionWorkspaceId) ?? null;
|
|
|
|
|
const linkedProjectWorkspaceId =
|
|
|
|
|
executionWorkspace?.projectWorkspaceId ?? issue.projectWorkspaceId ?? null;
|
|
|
|
|
const isDefaultSharedExecutionWorkspace =
|
|
|
|
|
executionWorkspace?.mode === "shared_workspace" && linkedProjectWorkspaceId === defaultProjectWorkspaceId;
|
|
|
|
|
if (isDefaultSharedExecutionWorkspace) return null;
|
|
|
|
|
|
|
|
|
|
const workspaceName = executionWorkspace?.name;
|
|
|
|
|
if (workspaceName) return workspaceName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (issue.projectWorkspaceId) {
|
|
|
|
|
if (issue.projectWorkspaceId === defaultProjectWorkspaceId) return null;
|
|
|
|
|
const workspaceName = projectWorkspaceById?.get(issue.projectWorkspaceId)?.name;
|
|
|
|
|
if (workspaceName) return workspaceName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
export function resolveIssueWorkspaceGroup(
|
|
|
|
|
issue: Pick<Issue, "executionWorkspaceId" | "projectId" | "projectWorkspaceId">,
|
|
|
|
|
{
|
|
|
|
|
executionWorkspaceById,
|
|
|
|
|
projectWorkspaceById,
|
|
|
|
|
defaultProjectWorkspaceIdByProjectId,
|
|
|
|
|
}: InboxWorkspaceGroupingOptions = {},
|
|
|
|
|
): { key: string; label: string } {
|
|
|
|
|
const defaultProjectWorkspace = resolveDefaultProjectWorkspaceInfo(issue, {
|
|
|
|
|
projectWorkspaceById,
|
|
|
|
|
defaultProjectWorkspaceIdByProjectId,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (issue.executionWorkspaceId) {
|
|
|
|
|
const executionWorkspace = executionWorkspaceById?.get(issue.executionWorkspaceId) ?? null;
|
|
|
|
|
const linkedProjectWorkspaceId =
|
|
|
|
|
executionWorkspace?.projectWorkspaceId ?? issue.projectWorkspaceId ?? null;
|
|
|
|
|
const isDefaultSharedExecutionWorkspace =
|
|
|
|
|
executionWorkspace?.mode === "shared_workspace"
|
|
|
|
|
&& linkedProjectWorkspaceId != null
|
|
|
|
|
&& linkedProjectWorkspaceId === defaultProjectWorkspace?.id;
|
|
|
|
|
|
|
|
|
|
if (isDefaultSharedExecutionWorkspace && defaultProjectWorkspace) {
|
|
|
|
|
return {
|
|
|
|
|
key: `workspace:project:${defaultProjectWorkspace.id}`,
|
|
|
|
|
label: defaultProjectWorkspace.label,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const workspaceName = executionWorkspace?.name?.trim();
|
|
|
|
|
if (workspaceName) {
|
|
|
|
|
return {
|
|
|
|
|
key: `workspace:execution:${issue.executionWorkspaceId}`,
|
|
|
|
|
label: workspaceName,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (issue.projectWorkspaceId) {
|
|
|
|
|
if (issue.projectWorkspaceId === defaultProjectWorkspace?.id) {
|
|
|
|
|
return {
|
|
|
|
|
key: `workspace:project:${defaultProjectWorkspace.id}`,
|
|
|
|
|
label: defaultProjectWorkspace.label,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const workspaceName = projectWorkspaceById?.get(issue.projectWorkspaceId)?.name?.trim();
|
|
|
|
|
if (workspaceName) {
|
|
|
|
|
return {
|
|
|
|
|
key: `workspace:project:${issue.projectWorkspaceId}`,
|
|
|
|
|
label: workspaceName,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (defaultProjectWorkspace) {
|
|
|
|
|
return {
|
|
|
|
|
key: `workspace:project:${defaultProjectWorkspace.id}`,
|
|
|
|
|
label: defaultProjectWorkspace.label,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
key: "workspace:none",
|
|
|
|
|
label: "No workspace",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-08 08:07:31 -05:00
|
|
|
export function loadInboxNesting(): boolean {
|
|
|
|
|
try {
|
|
|
|
|
const raw = localStorage.getItem(INBOX_NESTING_KEY);
|
|
|
|
|
return raw !== "false";
|
|
|
|
|
} catch {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function saveInboxNesting(enabled: boolean) {
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem(INBOX_NESTING_KEY, String(enabled));
|
|
|
|
|
} catch {
|
|
|
|
|
// Ignore localStorage failures.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-08 18:32:42 -05:00
|
|
|
export function resolveInboxNestingEnabled(preferenceEnabled: boolean, isMobile: boolean): boolean {
|
|
|
|
|
return preferenceEnabled && !isMobile;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-11 07:42:19 -05:00
|
|
|
export function loadLastInboxTab(): InboxTab {
|
|
|
|
|
try {
|
|
|
|
|
const raw = localStorage.getItem(INBOX_LAST_TAB_KEY);
|
2026-03-26 08:19:16 -05:00
|
|
|
if (raw === "all" || raw === "unread" || raw === "recent" || raw === "mine") return raw;
|
|
|
|
|
if (raw === "new") return "mine";
|
|
|
|
|
return "mine";
|
2026-03-11 07:42:19 -05:00
|
|
|
} catch {
|
2026-03-26 08:19:16 -05:00
|
|
|
return "mine";
|
2026-03-11 07:42:19 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function saveLastInboxTab(tab: InboxTab) {
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem(INBOX_LAST_TAB_KEY, tab);
|
|
|
|
|
} catch {
|
|
|
|
|
// Ignore localStorage failures.
|
|
|
|
|
}
|
2026-03-10 22:55:45 -05:00
|
|
|
}
|
|
|
|
|
|
2026-03-26 17:14:48 -05:00
|
|
|
export function isMineInboxTab(tab: InboxTab): boolean {
|
|
|
|
|
return tab === "mine";
|
|
|
|
|
}
|
|
|
|
|
|
feat: implement multi-user access and invite flows (#3784)
## Thinking Path
> - Paperclip is the control plane for autonomous AI companies.
> - V1 needs to stay local-first while also supporting shared,
authenticated deployments.
> - Human operators need real identities, company membership, invite
flows, profile surfaces, and company-scoped access controls.
> - Agents and operators also need the existing issue, inbox, workspace,
approval, and plugin flows to keep working under those authenticated
boundaries.
> - This branch accumulated the multi-user implementation, follow-up QA
fixes, workspace/runtime refinements, invite UX improvements,
release-branch conflict resolution, and review hardening.
> - This pull request consolidates that branch onto the current `master`
branch as a single reviewable PR.
> - The benefit is a complete multi-user implementation path with tests
and docs carried forward without dropping existing branch work.
## What Changed
- Added authenticated human-user access surfaces: auth/session routes,
company user directory, profile settings, company access/member
management, join requests, and invite management.
- Added invite creation, invite landing, onboarding, logo/branding,
invite grants, deduped join requests, and authenticated multi-user E2E
coverage.
- Tightened company-scoped and instance-admin authorization across
board, plugin, adapter, access, issue, and workspace routes.
- Added profile-image URL validation hardening, avatar preservation on
name-only profile updates, and join-request uniqueness migration cleanup
for pending human requests.
- Added an atomic member role/status/grants update path so Company
Access saves no longer leave partially updated permissions.
- Improved issue chat, inbox, assignee identity rendering,
sidebar/account/company navigation, workspace routing, and execution
workspace reuse behavior for multi-user operation.
- Added and updated server/UI tests covering auth, invites, membership,
issue workspace inheritance, plugin authz, inbox/chat behavior, and
multi-user flows.
- Merged current `public-gh/master` into this branch, resolved all
conflicts, and verified no `pnpm-lock.yaml` change is included in this
PR diff.
## Verification
- `pnpm exec vitest run server/src/__tests__/issues-service.test.ts
ui/src/components/IssueChatThread.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/plugin-routes-authz.test.ts`
- `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts
server/src/__tests__/workspace-runtime-service-authz.test.ts
server/src/__tests__/access-validators.test.ts`
- `pnpm exec vitest run
server/src/__tests__/authz-company-access.test.ts
server/src/__tests__/routines-routes.test.ts
server/src/__tests__/sidebar-preferences-routes.test.ts
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/openclaw-invite-prompt-route.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
server/src/__tests__/routines-e2e.test.ts`
- `pnpm exec vitest run server/src/__tests__/auth-routes.test.ts
ui/src/pages/CompanyAccess.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/db typecheck && pnpm --filter @paperclipai/server
typecheck`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm db:generate`
- `npx playwright test --config tests/e2e/playwright.config.ts --list`
- Confirmed branch has no uncommitted changes and is `0` commits behind
`public-gh/master` before PR creation.
- Confirmed no `pnpm-lock.yaml` change is staged or present in the PR
diff.
## Risks
- High review surface area: this PR contains the accumulated multi-user
branch plus follow-up fixes, so reviewers should focus especially on
company-boundary enforcement and authenticated-vs-local deployment
behavior.
- UI behavior changed across invites, inbox, issue chat, access
settings, and sidebar navigation; no browser screenshots are included in
this branch-consolidation PR.
- Plugin install, upgrade, and lifecycle/config mutations now require
instance-admin access, which is intentional but may change expectations
for non-admin board users.
- A join-request dedupe migration rejects duplicate pending human
requests before creating unique indexes; deployments with unusual
historical duplicates should review the migration behavior.
- Company member role/status/grant saves now use a new combined
endpoint; older separate endpoints remain for compatibility.
- Full production build was not run locally in this heartbeat; CI should
cover the full matrix.
## Model Used
- OpenAI Codex coding agent, GPT-5-based model, CLI/tool-use
environment. Exact deployed model identifier and context window were not
exposed by the runtime.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
Note on screenshots: this is a branch-consolidation PR for an
already-developed multi-user branch, and no browser screenshots were
captured during this heartbeat.
---------
Co-authored-by: dotta <dotta@example.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:44:19 -05:00
|
|
|
export function shouldShowCompanyAlerts(tab: InboxTab): boolean {
|
|
|
|
|
return tab === "all";
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-28 16:24:23 -05:00
|
|
|
export function resolveInboxSelectionIndex(
|
|
|
|
|
previousIndex: number,
|
|
|
|
|
itemCount: number,
|
|
|
|
|
): number {
|
|
|
|
|
if (itemCount === 0) return -1;
|
2026-03-28 16:45:44 -05:00
|
|
|
if (previousIndex < 0) return -1;
|
2026-03-28 16:24:23 -05:00
|
|
|
return Math.min(previousIndex, itemCount - 1);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-28 16:45:44 -05:00
|
|
|
export function getInboxKeyboardSelectionIndex(
|
|
|
|
|
previousIndex: number,
|
|
|
|
|
itemCount: number,
|
|
|
|
|
direction: "next" | "previous",
|
|
|
|
|
): number {
|
|
|
|
|
if (itemCount === 0) return -1;
|
|
|
|
|
if (previousIndex < 0) return 0;
|
|
|
|
|
return direction === "next"
|
|
|
|
|
? Math.min(previousIndex + 1, itemCount - 1)
|
|
|
|
|
: Math.max(previousIndex - 1, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-10 22:55:45 -05:00
|
|
|
export function getLatestFailedRunsByAgent(runs: HeartbeatRun[]): HeartbeatRun[] {
|
|
|
|
|
const sorted = [...runs].sort(
|
|
|
|
|
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
|
|
|
|
|
);
|
|
|
|
|
const latestByAgent = new Map<string, HeartbeatRun>();
|
|
|
|
|
|
|
|
|
|
for (const run of sorted) {
|
|
|
|
|
if (!latestByAgent.has(run.agentId)) {
|
|
|
|
|
latestByAgent.set(run.agentId, run);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Array.from(latestByAgent.values()).filter((run) => FAILED_RUN_STATUSES.has(run.status));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function normalizeTimestamp(value: string | Date | null | undefined): number {
|
|
|
|
|
if (!value) return 0;
|
|
|
|
|
const timestamp = new Date(value).getTime();
|
|
|
|
|
return Number.isFinite(timestamp) ? timestamp : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function issueLastActivityTimestamp(issue: Issue): number {
|
2026-04-03 07:24:33 -05:00
|
|
|
const lastActivityAt = normalizeTimestamp(issue.lastActivityAt);
|
|
|
|
|
if (lastActivityAt > 0) return lastActivityAt;
|
|
|
|
|
|
2026-03-10 22:55:45 -05:00
|
|
|
const lastExternalCommentAt = normalizeTimestamp(issue.lastExternalCommentAt);
|
|
|
|
|
if (lastExternalCommentAt > 0) return lastExternalCommentAt;
|
|
|
|
|
|
2026-04-01 14:52:53 -07:00
|
|
|
return normalizeTimestamp(issue.updatedAt);
|
2026-03-10 22:55:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function sortIssuesByMostRecentActivity(a: Issue, b: Issue): number {
|
|
|
|
|
const activityDiff = issueLastActivityTimestamp(b) - issueLastActivityTimestamp(a);
|
|
|
|
|
if (activityDiff !== 0) return activityDiff;
|
|
|
|
|
return normalizeTimestamp(b.updatedAt) - normalizeTimestamp(a.updatedAt);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-11 09:02:23 -05:00
|
|
|
export function getRecentTouchedIssues(issues: Issue[]): Issue[] {
|
|
|
|
|
return [...issues].sort(sortIssuesByMostRecentActivity).slice(0, RECENT_ISSUES_LIMIT);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-10 22:55:45 -05:00
|
|
|
export function getUnreadTouchedIssues(issues: Issue[]): Issue[] {
|
|
|
|
|
return issues.filter((issue) => issue.isUnreadForMe);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-17 16:10:26 -05:00
|
|
|
export function getApprovalsForTab(
|
|
|
|
|
approvals: Approval[],
|
|
|
|
|
tab: InboxTab,
|
|
|
|
|
filter: InboxApprovalFilter,
|
feat: implement multi-user access and invite flows (#3784)
## Thinking Path
> - Paperclip is the control plane for autonomous AI companies.
> - V1 needs to stay local-first while also supporting shared,
authenticated deployments.
> - Human operators need real identities, company membership, invite
flows, profile surfaces, and company-scoped access controls.
> - Agents and operators also need the existing issue, inbox, workspace,
approval, and plugin flows to keep working under those authenticated
boundaries.
> - This branch accumulated the multi-user implementation, follow-up QA
fixes, workspace/runtime refinements, invite UX improvements,
release-branch conflict resolution, and review hardening.
> - This pull request consolidates that branch onto the current `master`
branch as a single reviewable PR.
> - The benefit is a complete multi-user implementation path with tests
and docs carried forward without dropping existing branch work.
## What Changed
- Added authenticated human-user access surfaces: auth/session routes,
company user directory, profile settings, company access/member
management, join requests, and invite management.
- Added invite creation, invite landing, onboarding, logo/branding,
invite grants, deduped join requests, and authenticated multi-user E2E
coverage.
- Tightened company-scoped and instance-admin authorization across
board, plugin, adapter, access, issue, and workspace routes.
- Added profile-image URL validation hardening, avatar preservation on
name-only profile updates, and join-request uniqueness migration cleanup
for pending human requests.
- Added an atomic member role/status/grants update path so Company
Access saves no longer leave partially updated permissions.
- Improved issue chat, inbox, assignee identity rendering,
sidebar/account/company navigation, workspace routing, and execution
workspace reuse behavior for multi-user operation.
- Added and updated server/UI tests covering auth, invites, membership,
issue workspace inheritance, plugin authz, inbox/chat behavior, and
multi-user flows.
- Merged current `public-gh/master` into this branch, resolved all
conflicts, and verified no `pnpm-lock.yaml` change is included in this
PR diff.
## Verification
- `pnpm exec vitest run server/src/__tests__/issues-service.test.ts
ui/src/components/IssueChatThread.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/plugin-routes-authz.test.ts`
- `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts
server/src/__tests__/workspace-runtime-service-authz.test.ts
server/src/__tests__/access-validators.test.ts`
- `pnpm exec vitest run
server/src/__tests__/authz-company-access.test.ts
server/src/__tests__/routines-routes.test.ts
server/src/__tests__/sidebar-preferences-routes.test.ts
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/openclaw-invite-prompt-route.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
server/src/__tests__/routines-e2e.test.ts`
- `pnpm exec vitest run server/src/__tests__/auth-routes.test.ts
ui/src/pages/CompanyAccess.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/db typecheck && pnpm --filter @paperclipai/server
typecheck`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm db:generate`
- `npx playwright test --config tests/e2e/playwright.config.ts --list`
- Confirmed branch has no uncommitted changes and is `0` commits behind
`public-gh/master` before PR creation.
- Confirmed no `pnpm-lock.yaml` change is staged or present in the PR
diff.
## Risks
- High review surface area: this PR contains the accumulated multi-user
branch plus follow-up fixes, so reviewers should focus especially on
company-boundary enforcement and authenticated-vs-local deployment
behavior.
- UI behavior changed across invites, inbox, issue chat, access
settings, and sidebar navigation; no browser screenshots are included in
this branch-consolidation PR.
- Plugin install, upgrade, and lifecycle/config mutations now require
instance-admin access, which is intentional but may change expectations
for non-admin board users.
- A join-request dedupe migration rejects duplicate pending human
requests before creating unique indexes; deployments with unusual
historical duplicates should review the migration behavior.
- Company member role/status/grant saves now use a new combined
endpoint; older separate endpoints remain for compatibility.
- Full production build was not run locally in this heartbeat; CI should
cover the full matrix.
## Model Used
- OpenAI Codex coding agent, GPT-5-based model, CLI/tool-use
environment. Exact deployed model identifier and context window were not
exposed by the runtime.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
Note on screenshots: this is a branch-consolidation PR for an
already-developed multi-user branch, and no browser screenshots were
captured during this heartbeat.
---------
Co-authored-by: dotta <dotta@example.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:44:19 -05:00
|
|
|
currentUserId?: string | null,
|
2026-03-17 16:10:26 -05:00
|
|
|
): Approval[] {
|
|
|
|
|
const sortedApprovals = [...approvals].sort(
|
|
|
|
|
(a, b) => normalizeTimestamp(b.updatedAt) - normalizeTimestamp(a.updatedAt),
|
|
|
|
|
);
|
|
|
|
|
|
feat: implement multi-user access and invite flows (#3784)
## Thinking Path
> - Paperclip is the control plane for autonomous AI companies.
> - V1 needs to stay local-first while also supporting shared,
authenticated deployments.
> - Human operators need real identities, company membership, invite
flows, profile surfaces, and company-scoped access controls.
> - Agents and operators also need the existing issue, inbox, workspace,
approval, and plugin flows to keep working under those authenticated
boundaries.
> - This branch accumulated the multi-user implementation, follow-up QA
fixes, workspace/runtime refinements, invite UX improvements,
release-branch conflict resolution, and review hardening.
> - This pull request consolidates that branch onto the current `master`
branch as a single reviewable PR.
> - The benefit is a complete multi-user implementation path with tests
and docs carried forward without dropping existing branch work.
## What Changed
- Added authenticated human-user access surfaces: auth/session routes,
company user directory, profile settings, company access/member
management, join requests, and invite management.
- Added invite creation, invite landing, onboarding, logo/branding,
invite grants, deduped join requests, and authenticated multi-user E2E
coverage.
- Tightened company-scoped and instance-admin authorization across
board, plugin, adapter, access, issue, and workspace routes.
- Added profile-image URL validation hardening, avatar preservation on
name-only profile updates, and join-request uniqueness migration cleanup
for pending human requests.
- Added an atomic member role/status/grants update path so Company
Access saves no longer leave partially updated permissions.
- Improved issue chat, inbox, assignee identity rendering,
sidebar/account/company navigation, workspace routing, and execution
workspace reuse behavior for multi-user operation.
- Added and updated server/UI tests covering auth, invites, membership,
issue workspace inheritance, plugin authz, inbox/chat behavior, and
multi-user flows.
- Merged current `public-gh/master` into this branch, resolved all
conflicts, and verified no `pnpm-lock.yaml` change is included in this
PR diff.
## Verification
- `pnpm exec vitest run server/src/__tests__/issues-service.test.ts
ui/src/components/IssueChatThread.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/plugin-routes-authz.test.ts`
- `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts
server/src/__tests__/workspace-runtime-service-authz.test.ts
server/src/__tests__/access-validators.test.ts`
- `pnpm exec vitest run
server/src/__tests__/authz-company-access.test.ts
server/src/__tests__/routines-routes.test.ts
server/src/__tests__/sidebar-preferences-routes.test.ts
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/openclaw-invite-prompt-route.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
server/src/__tests__/routines-e2e.test.ts`
- `pnpm exec vitest run server/src/__tests__/auth-routes.test.ts
ui/src/pages/CompanyAccess.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/db typecheck && pnpm --filter @paperclipai/server
typecheck`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm db:generate`
- `npx playwright test --config tests/e2e/playwright.config.ts --list`
- Confirmed branch has no uncommitted changes and is `0` commits behind
`public-gh/master` before PR creation.
- Confirmed no `pnpm-lock.yaml` change is staged or present in the PR
diff.
## Risks
- High review surface area: this PR contains the accumulated multi-user
branch plus follow-up fixes, so reviewers should focus especially on
company-boundary enforcement and authenticated-vs-local deployment
behavior.
- UI behavior changed across invites, inbox, issue chat, access
settings, and sidebar navigation; no browser screenshots are included in
this branch-consolidation PR.
- Plugin install, upgrade, and lifecycle/config mutations now require
instance-admin access, which is intentional but may change expectations
for non-admin board users.
- A join-request dedupe migration rejects duplicate pending human
requests before creating unique indexes; deployments with unusual
historical duplicates should review the migration behavior.
- Company member role/status/grant saves now use a new combined
endpoint; older separate endpoints remain for compatibility.
- Full production build was not run locally in this heartbeat; CI should
cover the full matrix.
## Model Used
- OpenAI Codex coding agent, GPT-5-based model, CLI/tool-use
environment. Exact deployed model identifier and context window were not
exposed by the runtime.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
Note on screenshots: this is a branch-consolidation PR for an
already-developed multi-user branch, and no browser screenshots were
captured during this heartbeat.
---------
Co-authored-by: dotta <dotta@example.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:44:19 -05:00
|
|
|
if (tab === "mine") {
|
[codex] Polish issue and operator workflow UI (#4090)
## Thinking Path
> - Paperclip operators spend much of their time in issues, inboxes,
selectors, and rich comment threads.
> - Small interaction problems in those surfaces slow down supervision
of AI-agent work.
> - The branch included related operator quality-of-life fixes for issue
layout, inbox actions, recent selectors, mobile inputs, and chat
rendering stability.
> - These changes are UI-focused and can land independently from
workspace navigation and access-profile work.
> - This pull request groups the operator QoL fixes into one standalone
branch.
> - The benefit is a more stable and efficient board workflow for issue
triage and task editing.
## What Changed
- Widened issue detail content and added a desktop inbox archive action.
- Fixed mobile text-field zoom by keeping touch input font sizes at
16px.
- Prioritized recent picker selections for assignees/projects in issue
and routine flows.
- Showed actionable approvals in the Mine inbox model.
- Fixed issue chat renderer state crashes and hardened tests.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/components/IssueChatThread.test.tsx
ui/src/lib/inbox.test.ts ui/src/lib/recent-selections.test.ts`
- Split integration check: merged last after the other
[PAP-1614](/PAP/issues/PAP-1614) branches with no merge conflicts.
- Confirmed this branch does not include `pnpm-lock.yaml`.
## Risks
- Low to medium risk: mostly UI state, layout, and selection-priority
behavior.
- Visual layout and mobile zoom behavior may need browser/device QA
beyond component tests.
- No database migrations are included.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5.4 tool-enabled coding model, agentic
code-editing/runtime with local shell and GitHub CLI access; exact
context window and reasoning mode are not exposed by the Paperclip
harness.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-20 06:16:41 -05:00
|
|
|
return sortedApprovals.filter((approval) => isApprovalVisibleInMine(approval, currentUserId));
|
feat: implement multi-user access and invite flows (#3784)
## Thinking Path
> - Paperclip is the control plane for autonomous AI companies.
> - V1 needs to stay local-first while also supporting shared,
authenticated deployments.
> - Human operators need real identities, company membership, invite
flows, profile surfaces, and company-scoped access controls.
> - Agents and operators also need the existing issue, inbox, workspace,
approval, and plugin flows to keep working under those authenticated
boundaries.
> - This branch accumulated the multi-user implementation, follow-up QA
fixes, workspace/runtime refinements, invite UX improvements,
release-branch conflict resolution, and review hardening.
> - This pull request consolidates that branch onto the current `master`
branch as a single reviewable PR.
> - The benefit is a complete multi-user implementation path with tests
and docs carried forward without dropping existing branch work.
## What Changed
- Added authenticated human-user access surfaces: auth/session routes,
company user directory, profile settings, company access/member
management, join requests, and invite management.
- Added invite creation, invite landing, onboarding, logo/branding,
invite grants, deduped join requests, and authenticated multi-user E2E
coverage.
- Tightened company-scoped and instance-admin authorization across
board, plugin, adapter, access, issue, and workspace routes.
- Added profile-image URL validation hardening, avatar preservation on
name-only profile updates, and join-request uniqueness migration cleanup
for pending human requests.
- Added an atomic member role/status/grants update path so Company
Access saves no longer leave partially updated permissions.
- Improved issue chat, inbox, assignee identity rendering,
sidebar/account/company navigation, workspace routing, and execution
workspace reuse behavior for multi-user operation.
- Added and updated server/UI tests covering auth, invites, membership,
issue workspace inheritance, plugin authz, inbox/chat behavior, and
multi-user flows.
- Merged current `public-gh/master` into this branch, resolved all
conflicts, and verified no `pnpm-lock.yaml` change is included in this
PR diff.
## Verification
- `pnpm exec vitest run server/src/__tests__/issues-service.test.ts
ui/src/components/IssueChatThread.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/plugin-routes-authz.test.ts`
- `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts
server/src/__tests__/workspace-runtime-service-authz.test.ts
server/src/__tests__/access-validators.test.ts`
- `pnpm exec vitest run
server/src/__tests__/authz-company-access.test.ts
server/src/__tests__/routines-routes.test.ts
server/src/__tests__/sidebar-preferences-routes.test.ts
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/openclaw-invite-prompt-route.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
server/src/__tests__/routines-e2e.test.ts`
- `pnpm exec vitest run server/src/__tests__/auth-routes.test.ts
ui/src/pages/CompanyAccess.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/db typecheck && pnpm --filter @paperclipai/server
typecheck`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm db:generate`
- `npx playwright test --config tests/e2e/playwright.config.ts --list`
- Confirmed branch has no uncommitted changes and is `0` commits behind
`public-gh/master` before PR creation.
- Confirmed no `pnpm-lock.yaml` change is staged or present in the PR
diff.
## Risks
- High review surface area: this PR contains the accumulated multi-user
branch plus follow-up fixes, so reviewers should focus especially on
company-boundary enforcement and authenticated-vs-local deployment
behavior.
- UI behavior changed across invites, inbox, issue chat, access
settings, and sidebar navigation; no browser screenshots are included in
this branch-consolidation PR.
- Plugin install, upgrade, and lifecycle/config mutations now require
instance-admin access, which is intentional but may change expectations
for non-admin board users.
- A join-request dedupe migration rejects duplicate pending human
requests before creating unique indexes; deployments with unusual
historical duplicates should review the migration behavior.
- Company member role/status/grant saves now use a new combined
endpoint; older separate endpoints remain for compatibility.
- Full production build was not run locally in this heartbeat; CI should
cover the full matrix.
## Model Used
- OpenAI Codex coding agent, GPT-5-based model, CLI/tool-use
environment. Exact deployed model identifier and context window were not
exposed by the runtime.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
Note on screenshots: this is a branch-consolidation PR for an
already-developed multi-user branch, and no browser screenshots were
captured during this heartbeat.
---------
Co-authored-by: dotta <dotta@example.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:44:19 -05:00
|
|
|
}
|
|
|
|
|
if (tab === "recent") return sortedApprovals;
|
2026-03-17 16:10:26 -05:00
|
|
|
if (tab === "unread") {
|
|
|
|
|
return sortedApprovals.filter((approval) => ACTIONABLE_APPROVAL_STATUSES.has(approval.status));
|
|
|
|
|
}
|
|
|
|
|
if (filter === "all") return sortedApprovals;
|
|
|
|
|
|
|
|
|
|
return sortedApprovals.filter((approval) => {
|
|
|
|
|
const isActionable = ACTIONABLE_APPROVAL_STATUSES.has(approval.status);
|
|
|
|
|
return filter === "actionable" ? isActionable : !isActionable;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
[codex] Polish issue and operator workflow UI (#4090)
## Thinking Path
> - Paperclip operators spend much of their time in issues, inboxes,
selectors, and rich comment threads.
> - Small interaction problems in those surfaces slow down supervision
of AI-agent work.
> - The branch included related operator quality-of-life fixes for issue
layout, inbox actions, recent selectors, mobile inputs, and chat
rendering stability.
> - These changes are UI-focused and can land independently from
workspace navigation and access-profile work.
> - This pull request groups the operator QoL fixes into one standalone
branch.
> - The benefit is a more stable and efficient board workflow for issue
triage and task editing.
## What Changed
- Widened issue detail content and added a desktop inbox archive action.
- Fixed mobile text-field zoom by keeping touch input font sizes at
16px.
- Prioritized recent picker selections for assignees/projects in issue
and routine flows.
- Showed actionable approvals in the Mine inbox model.
- Fixed issue chat renderer state crashes and hardened tests.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/components/IssueChatThread.test.tsx
ui/src/lib/inbox.test.ts ui/src/lib/recent-selections.test.ts`
- Split integration check: merged last after the other
[PAP-1614](/PAP/issues/PAP-1614) branches with no merge conflicts.
- Confirmed this branch does not include `pnpm-lock.yaml`.
## Risks
- Low to medium risk: mostly UI state, layout, and selection-priority
behavior.
- Visual layout and mobile zoom behavior may need browser/device QA
beyond component tests.
- No database migrations are included.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5.4 tool-enabled coding model, agentic
code-editing/runtime with local shell and GitHub CLI access; exact
context window and reasoning mode are not exposed by the Paperclip
harness.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-20 06:16:41 -05:00
|
|
|
export function isApprovalVisibleInMine(
|
|
|
|
|
approval: Approval,
|
|
|
|
|
currentUserId?: string | null,
|
|
|
|
|
): boolean {
|
|
|
|
|
if (ACTIONABLE_APPROVAL_STATUSES.has(approval.status)) return true;
|
|
|
|
|
if (!currentUserId) return false;
|
|
|
|
|
return approval.requestedByUserId === currentUserId || approval.decidedByUserId === currentUserId;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-17 16:19:00 -05:00
|
|
|
export function approvalActivityTimestamp(approval: Approval): number {
|
|
|
|
|
const updatedAt = normalizeTimestamp(approval.updatedAt);
|
|
|
|
|
if (updatedAt > 0) return updatedAt;
|
|
|
|
|
return normalizeTimestamp(approval.createdAt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getInboxWorkItems({
|
|
|
|
|
issues,
|
|
|
|
|
approvals,
|
2026-03-19 07:24:52 -05:00
|
|
|
failedRuns = [],
|
2026-03-24 07:53:05 -05:00
|
|
|
joinRequests = [],
|
2026-03-17 16:19:00 -05:00
|
|
|
}: {
|
|
|
|
|
issues: Issue[];
|
|
|
|
|
approvals: Approval[];
|
2026-03-19 07:24:52 -05:00
|
|
|
failedRuns?: HeartbeatRun[];
|
2026-03-24 07:53:05 -05:00
|
|
|
joinRequests?: JoinRequest[];
|
2026-03-17 16:19:00 -05:00
|
|
|
}): InboxWorkItem[] {
|
|
|
|
|
return [
|
|
|
|
|
...issues.map((issue) => ({
|
|
|
|
|
kind: "issue" as const,
|
|
|
|
|
timestamp: issueLastActivityTimestamp(issue),
|
|
|
|
|
issue,
|
|
|
|
|
})),
|
|
|
|
|
...approvals.map((approval) => ({
|
|
|
|
|
kind: "approval" as const,
|
|
|
|
|
timestamp: approvalActivityTimestamp(approval),
|
|
|
|
|
approval,
|
|
|
|
|
})),
|
2026-03-19 07:24:52 -05:00
|
|
|
...failedRuns.map((run) => ({
|
|
|
|
|
kind: "failed_run" as const,
|
|
|
|
|
timestamp: normalizeTimestamp(run.createdAt),
|
|
|
|
|
run,
|
|
|
|
|
})),
|
2026-03-24 07:53:05 -05:00
|
|
|
...joinRequests.map((joinRequest) => ({
|
|
|
|
|
kind: "join_request" as const,
|
|
|
|
|
timestamp: normalizeTimestamp(joinRequest.createdAt),
|
|
|
|
|
joinRequest,
|
|
|
|
|
})),
|
2026-03-17 16:19:00 -05:00
|
|
|
].sort((a, b) => {
|
|
|
|
|
const timestampDiff = b.timestamp - a.timestamp;
|
|
|
|
|
if (timestampDiff !== 0) return timestampDiff;
|
|
|
|
|
|
|
|
|
|
if (a.kind === "issue" && b.kind === "issue") {
|
|
|
|
|
return sortIssuesByMostRecentActivity(a.issue, b.issue);
|
|
|
|
|
}
|
|
|
|
|
if (a.kind === "approval" && b.kind === "approval") {
|
|
|
|
|
return approvalActivityTimestamp(b.approval) - approvalActivityTimestamp(a.approval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return a.kind === "approval" ? -1 : 1;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 10:26:17 -05:00
|
|
|
const inboxWorkItemKindOrder: InboxWorkItem["kind"][] = [
|
|
|
|
|
"issue",
|
|
|
|
|
"approval",
|
|
|
|
|
"failed_run",
|
|
|
|
|
"join_request",
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const inboxWorkItemKindLabels: Record<InboxWorkItem["kind"], string> = {
|
|
|
|
|
issue: "Issues",
|
|
|
|
|
approval: "Approvals",
|
|
|
|
|
failed_run: "Failed runs",
|
|
|
|
|
join_request: "Join requests",
|
|
|
|
|
};
|
|
|
|
|
|
Improve operator workflow QoL (#5291)
## Thinking Path
> - Paperclip is a control plane operators use repeatedly to supervise
agent companies.
> - Common operator workflows depend on fast scanning of inboxes, issue
sidebars, workspaces, cost totals, and runtime services.
> - Several small UI and service gaps made those workflows slower or
less clear.
> - This pull request groups the operator-facing QoL changes that can
stand alone from recovery and adapter work.
> - The benefit is a denser, clearer board experience for issue triage
and workspace operation.
## What Changed
- Added inbox assignee/project grouping and issue list token/runtime
totals.
- Improved issue properties with removable blocker chips and workspace
task links.
- Improved execution workspace layout, runtime controls, issues tab
default, and stopped-port reuse behavior.
- Added mobile markdown/routine dialog fixes, page title company names,
sidebar polish, and dashboard run task label cleanup.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/lib/inbox.test.ts
ui/src/components/IssueProperties.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
server/src/__tests__/workspace-runtime.test.ts
server/src/__tests__/costs-service.test.ts`
## Risks
- Medium UI risk because this touches several operator surfaces. The
branch is intentionally grouped around workflow/QoL files and keeps the
file count below the Greptile limit.
## Model Used
- OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with
shell/git/GitHub CLI tool use.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:30:44 -05:00
|
|
|
function resolveIssueAssigneeGroup(
|
|
|
|
|
issue: Pick<Issue, "assigneeAgentId" | "assigneeUserId">,
|
|
|
|
|
{
|
|
|
|
|
agentById,
|
|
|
|
|
currentUserId,
|
|
|
|
|
userLabelById,
|
|
|
|
|
}: Pick<InboxWorkspaceGroupingOptions, "agentById" | "currentUserId" | "userLabelById">,
|
|
|
|
|
): { key: string; label: string } {
|
|
|
|
|
if (issue.assigneeAgentId) {
|
|
|
|
|
const agentName = agentById?.get(issue.assigneeAgentId)?.trim();
|
|
|
|
|
return {
|
|
|
|
|
key: `assignee:agent:${issue.assigneeAgentId}`,
|
|
|
|
|
label: agentName || issue.assigneeAgentId.slice(0, 8),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (issue.assigneeUserId) {
|
|
|
|
|
return {
|
|
|
|
|
key: `assignee:user:${issue.assigneeUserId}`,
|
|
|
|
|
label: formatAssigneeUserLabel(issue.assigneeUserId, currentUserId, userLabelById) ?? "User",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { key: "assignee:none", label: "Unassigned" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function resolveIssueProjectGroup(
|
|
|
|
|
issue: Pick<Issue, "projectId">,
|
|
|
|
|
{ projectById }: Pick<InboxWorkspaceGroupingOptions, "projectById">,
|
|
|
|
|
): { key: string; label: string } {
|
|
|
|
|
if (!issue.projectId) return { key: "project:none", label: "No project" };
|
|
|
|
|
|
|
|
|
|
const projectName = projectById?.get(issue.projectId)?.name?.trim();
|
|
|
|
|
return {
|
|
|
|
|
key: `project:${issue.projectId}`,
|
|
|
|
|
label: projectName || issue.projectId.slice(0, 8),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function groupInboxWorkItemsByIssueGroup(
|
|
|
|
|
items: InboxWorkItem[],
|
|
|
|
|
resolveIssueGroup: (issue: Issue) => { key: string; label: string },
|
|
|
|
|
): InboxWorkItemGroup[] {
|
|
|
|
|
const groups = new Map<string, { label: string; items: InboxWorkItem[]; latestTimestamp: number }>();
|
|
|
|
|
for (const item of items) {
|
|
|
|
|
const resolvedGroup = item.kind === "issue"
|
|
|
|
|
? resolveIssueGroup(item.issue)
|
|
|
|
|
: { key: `kind:${item.kind}`, label: inboxWorkItemKindLabels[item.kind] };
|
|
|
|
|
const existing = groups.get(resolvedGroup.key);
|
|
|
|
|
if (existing) {
|
|
|
|
|
existing.items.push(item);
|
|
|
|
|
existing.latestTimestamp = Math.max(existing.latestTimestamp, item.timestamp);
|
|
|
|
|
} else {
|
|
|
|
|
groups.set(resolvedGroup.key, {
|
|
|
|
|
label: resolvedGroup.label,
|
|
|
|
|
items: [item],
|
|
|
|
|
latestTimestamp: item.timestamp,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return [...groups.entries()]
|
|
|
|
|
.map(([key, value]) => ({
|
|
|
|
|
key,
|
|
|
|
|
label: value.label,
|
|
|
|
|
items: value.items,
|
|
|
|
|
latestTimestamp: value.latestTimestamp,
|
|
|
|
|
}))
|
|
|
|
|
.sort((a, b) => {
|
|
|
|
|
const timestampDiff = b.latestTimestamp - a.latestTimestamp;
|
|
|
|
|
if (timestampDiff !== 0) return timestampDiff;
|
|
|
|
|
return a.label.localeCompare(b.label);
|
|
|
|
|
})
|
|
|
|
|
.map(({ key, label, items: groupItems }) => ({
|
|
|
|
|
key,
|
|
|
|
|
label,
|
|
|
|
|
items: groupItems,
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-09 10:26:17 -05:00
|
|
|
export function groupInboxWorkItems(
|
|
|
|
|
items: InboxWorkItem[],
|
|
|
|
|
groupBy: InboxWorkItemGroupBy,
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
options: InboxWorkspaceGroupingOptions = {},
|
2026-04-09 10:26:17 -05:00
|
|
|
): InboxWorkItemGroup[] {
|
|
|
|
|
if (groupBy === "none") {
|
|
|
|
|
return [{ key: "__all", label: null, items }];
|
|
|
|
|
}
|
|
|
|
|
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
if (groupBy === "workspace") {
|
Improve operator workflow QoL (#5291)
## Thinking Path
> - Paperclip is a control plane operators use repeatedly to supervise
agent companies.
> - Common operator workflows depend on fast scanning of inboxes, issue
sidebars, workspaces, cost totals, and runtime services.
> - Several small UI and service gaps made those workflows slower or
less clear.
> - This pull request groups the operator-facing QoL changes that can
stand alone from recovery and adapter work.
> - The benefit is a denser, clearer board experience for issue triage
and workspace operation.
## What Changed
- Added inbox assignee/project grouping and issue list token/runtime
totals.
- Improved issue properties with removable blocker chips and workspace
task links.
- Improved execution workspace layout, runtime controls, issues tab
default, and stopped-port reuse behavior.
- Added mobile markdown/routine dialog fixes, page title company names,
sidebar polish, and dashboard run task label cleanup.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/lib/inbox.test.ts
ui/src/components/IssueProperties.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
server/src/__tests__/workspace-runtime.test.ts
server/src/__tests__/costs-service.test.ts`
## Risks
- Medium UI risk because this touches several operator surfaces. The
branch is intentionally grouped around workflow/QoL files and keeps the
file count below the Greptile limit.
## Model Used
- OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with
shell/git/GitHub CLI tool use.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:30:44 -05:00
|
|
|
return groupInboxWorkItemsByIssueGroup(items, (issue) => resolveIssueWorkspaceGroup(issue, options));
|
|
|
|
|
}
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
|
Improve operator workflow QoL (#5291)
## Thinking Path
> - Paperclip is a control plane operators use repeatedly to supervise
agent companies.
> - Common operator workflows depend on fast scanning of inboxes, issue
sidebars, workspaces, cost totals, and runtime services.
> - Several small UI and service gaps made those workflows slower or
less clear.
> - This pull request groups the operator-facing QoL changes that can
stand alone from recovery and adapter work.
> - The benefit is a denser, clearer board experience for issue triage
and workspace operation.
## What Changed
- Added inbox assignee/project grouping and issue list token/runtime
totals.
- Improved issue properties with removable blocker chips and workspace
task links.
- Improved execution workspace layout, runtime controls, issues tab
default, and stopped-port reuse behavior.
- Added mobile markdown/routine dialog fixes, page title company names,
sidebar polish, and dashboard run task label cleanup.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/lib/inbox.test.ts
ui/src/components/IssueProperties.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
server/src/__tests__/workspace-runtime.test.ts
server/src/__tests__/costs-service.test.ts`
## Risks
- Medium UI risk because this touches several operator surfaces. The
branch is intentionally grouped around workflow/QoL files and keeps the
file count below the Greptile limit.
## Model Used
- OpenAI GPT-5 Codex via Paperclip `codex_local` adapter, with
shell/git/GitHub CLI tool use.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-06 06:30:44 -05:00
|
|
|
if (groupBy === "assignee") {
|
|
|
|
|
return groupInboxWorkItemsByIssueGroup(items, (issue) => resolveIssueAssigneeGroup(issue, options));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (groupBy === "project") {
|
|
|
|
|
return groupInboxWorkItemsByIssueGroup(items, (issue) => resolveIssueProjectGroup(issue, options));
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-09 10:26:17 -05:00
|
|
|
const groups = new Map<InboxWorkItem["kind"], InboxWorkItem[]>();
|
|
|
|
|
for (const item of items) {
|
|
|
|
|
const existing = groups.get(item.kind) ?? [];
|
|
|
|
|
existing.push(item);
|
|
|
|
|
groups.set(item.kind, existing);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const orderedGroups: InboxWorkItemGroup[] = [];
|
|
|
|
|
for (const kind of inboxWorkItemKindOrder) {
|
|
|
|
|
const groupItems = groups.get(kind) ?? [];
|
|
|
|
|
if (groupItems.length === 0) continue;
|
|
|
|
|
orderedGroups.push({
|
|
|
|
|
key: kind,
|
|
|
|
|
label: inboxWorkItemKindLabels[kind],
|
|
|
|
|
items: groupItems,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return orderedGroups;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-08 07:52:57 -05:00
|
|
|
/**
|
|
|
|
|
* Groups parent-child issues in a flat InboxWorkItem list.
|
|
|
|
|
*
|
|
|
|
|
* - Children whose parent is also in the list are removed from the top level
|
|
|
|
|
* and stored in `childrenByIssueId`.
|
|
|
|
|
* - The parent's sort timestamp becomes max(parent, children) so that a group
|
|
|
|
|
* with a recently-updated child floats to the top.
|
|
|
|
|
* - If a parent is absent (e.g. archived), children remain as independent roots.
|
|
|
|
|
*/
|
|
|
|
|
export function buildInboxNesting(items: InboxWorkItem[]): {
|
|
|
|
|
displayItems: InboxWorkItem[];
|
|
|
|
|
childrenByIssueId: Map<string, Issue[]>;
|
|
|
|
|
} {
|
|
|
|
|
const issueItems: (InboxWorkItem & { kind: "issue" })[] = [];
|
|
|
|
|
const nonIssueItems: InboxWorkItem[] = [];
|
|
|
|
|
for (const item of items) {
|
|
|
|
|
if (item.kind === "issue") issueItems.push(item as InboxWorkItem & { kind: "issue" });
|
|
|
|
|
else nonIssueItems.push(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const issueIdSet = new Set(issueItems.map((i) => i.issue.id));
|
|
|
|
|
const childrenByIssueId = new Map<string, Issue[]>();
|
|
|
|
|
const childIds = new Set<string>();
|
|
|
|
|
|
|
|
|
|
for (const item of issueItems) {
|
|
|
|
|
const { issue } = item;
|
|
|
|
|
if (issue.parentId && issueIdSet.has(issue.parentId)) {
|
|
|
|
|
childIds.add(issue.id);
|
|
|
|
|
const arr = childrenByIssueId.get(issue.parentId) ?? [];
|
|
|
|
|
arr.push(issue);
|
|
|
|
|
childrenByIssueId.set(issue.parentId, arr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-01 11:58:53 -05:00
|
|
|
const subtreeActivityTimestamp = (issue: Issue, seen: ReadonlySet<string> = new Set()): number => {
|
|
|
|
|
const ownTimestamp = issueLastActivityTimestamp(issue);
|
|
|
|
|
if (seen.has(issue.id)) return ownTimestamp;
|
|
|
|
|
const nextSeen = new Set(seen);
|
|
|
|
|
nextSeen.add(issue.id);
|
|
|
|
|
const children = childrenByIssueId.get(issue.id) ?? [];
|
|
|
|
|
if (children.length === 0) return ownTimestamp;
|
|
|
|
|
return Math.max(
|
|
|
|
|
ownTimestamp,
|
|
|
|
|
...children.map((child) => subtreeActivityTimestamp(child, nextSeen)),
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Sort each child list by most recent descendant activity, not just direct issue activity.
|
2026-04-08 07:52:57 -05:00
|
|
|
for (const children of childrenByIssueId.values()) {
|
2026-05-01 11:58:53 -05:00
|
|
|
children.sort((a, b) => {
|
|
|
|
|
const activityDiff = subtreeActivityTimestamp(b) - subtreeActivityTimestamp(a);
|
|
|
|
|
if (activityDiff !== 0) return activityDiff;
|
|
|
|
|
return sortIssuesByMostRecentActivity(a, b);
|
|
|
|
|
});
|
2026-04-08 07:52:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build root issue items with group-adjusted timestamps
|
|
|
|
|
const rootIssueItems: InboxWorkItem[] = issueItems
|
|
|
|
|
.filter((item) => !childIds.has(item.issue.id))
|
|
|
|
|
.map((item) => {
|
|
|
|
|
const children = childrenByIssueId.get(item.issue.id);
|
|
|
|
|
if (!children?.length) return item;
|
2026-05-01 11:58:53 -05:00
|
|
|
const maxChildTs = Math.max(...children.map((child) => subtreeActivityTimestamp(child)));
|
2026-04-08 07:52:57 -05:00
|
|
|
return { ...item, timestamp: Math.max(item.timestamp, maxChildTs) };
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Merge and re-sort
|
|
|
|
|
const displayItems = [...rootIssueItems, ...nonIssueItems].sort((a, b) => {
|
|
|
|
|
const diff = b.timestamp - a.timestamp;
|
|
|
|
|
if (diff !== 0) return diff;
|
|
|
|
|
if (a.kind === "issue" && b.kind === "issue") {
|
|
|
|
|
return sortIssuesByMostRecentActivity(a.issue, b.issue);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return { displayItems, childrenByIssueId };
|
|
|
|
|
}
|
|
|
|
|
|
[codex] improve issue and routine UI responsiveness (#3744)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Operators rely on issue, inbox, and routine views to understand what
the company is doing in real time
> - Those views need to stay fast and readable even when issue lists,
markdown comments, and run metadata get large
> - The current branch had a coherent set of UI and live-update
improvements spread across issue search, issue detail rendering, routine
affordances, and workspace lookups
> - This pull request groups those board-facing changes into one
standalone branch that can merge independently of the heartbeat/runtime
work
> - The benefit is a faster, clearer issue and routine workflow without
changing the underlying task model
## What Changed
- Show routine execution issues by default and rename the filter to
`Hide routine runs` so the default state no longer looks like an active
filter.
- Show the routine name in the run dialog and tighten the issue
properties pane with a workspace link, copy-on-click behavior, and an
inline parent arrow.
- Reduce issue detail rerenders, keep queued issue chat mounted, improve
issues page search responsiveness, and speed up issues first paint.
- Add inbox "other search results", refresh visible issue runs after
status updates, and optimize workspace lookups through summary-mode
execution workspace queries.
- Improve markdown wrapping and scrolling behavior for long strings and
self-comment code blocks.
- Relax the markdown sanitizer assertion so the test still validates
safety after the new wrap-friendly inline styles.
## Verification
- `pnpm vitest run ui/src/components/IssuesList.test.tsx
ui/src/lib/inbox.test.ts ui/src/pages/Issues.test.tsx
ui/src/context/BreadcrumbContext.test.tsx
ui/src/context/LiveUpdatesProvider.test.ts
ui/src/components/MarkdownBody.test.tsx
ui/src/api/execution-workspaces.test.ts
server/src/__tests__/execution-workspaces-routes.test.ts`
## Risks
- This touches several issue-facing UI surfaces at once, so regressions
would most likely show up as stale rendering, search result mismatches,
or small markdown presentation differences.
- The workspace lookup optimization depends on the summary-mode route
shape staying aligned between server and UI.
## Model Used
- OpenAI Codex, GPT-5-based coding agent in the Codex CLI environment.
Exact backend model deployment ID was not exposed in-session.
Tool-assisted editing and shell execution were used.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-15 15:54:05 -05:00
|
|
|
export function buildGroupedInboxSections(
|
|
|
|
|
items: InboxWorkItem[],
|
|
|
|
|
groupBy: InboxWorkItemGroupBy,
|
|
|
|
|
workspaceGrouping: InboxWorkspaceGroupingOptions,
|
|
|
|
|
options?: { keyPrefix?: string; searchSection?: InboxSearchSection; nestingEnabled?: boolean },
|
|
|
|
|
): InboxGroupedSection[] {
|
|
|
|
|
const keyPrefix = options?.keyPrefix ?? "";
|
|
|
|
|
const searchSection = options?.searchSection ?? "none";
|
|
|
|
|
const nestingEnabled = options?.nestingEnabled ?? false;
|
|
|
|
|
|
|
|
|
|
return groupInboxWorkItems(items, groupBy, workspaceGrouping).map((group) => {
|
|
|
|
|
const nestedGroup = nestingEnabled && group.items.some((item) => item.kind === "issue")
|
|
|
|
|
? buildInboxNesting(group.items)
|
|
|
|
|
: { displayItems: group.items, childrenByIssueId: new Map<string, Issue[]>() };
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
key: `${keyPrefix}${group.key}`,
|
|
|
|
|
label: group.label,
|
|
|
|
|
displayItems: nestedGroup.displayItems,
|
|
|
|
|
childrenByIssueId: nestedGroup.childrenByIssueId,
|
|
|
|
|
searchSection,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
export function getInboxWorkItemKey(item: InboxWorkItem): string {
|
|
|
|
|
if (item.kind === "issue") return `issue:${item.issue.id}`;
|
|
|
|
|
if (item.kind === "approval") return `approval:${item.approval.id}`;
|
|
|
|
|
if (item.kind === "failed_run") return `run:${item.run.id}`;
|
|
|
|
|
return `join:${item.joinRequest.id}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function buildInboxKeyboardNavEntries(
|
|
|
|
|
groupedSections: ReadonlyArray<InboxKeyboardGroupSection>,
|
|
|
|
|
collapsedGroupKeys: ReadonlySet<string>,
|
|
|
|
|
collapsedInboxParents: ReadonlySet<string>,
|
|
|
|
|
): InboxKeyboardNavEntry[] {
|
|
|
|
|
const entries: InboxKeyboardNavEntry[] = [];
|
|
|
|
|
|
|
|
|
|
for (const group of groupedSections) {
|
[codex] Polish issue board workflows (#4224)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - Human operators supervise that work through issue lists, issue
detail, comments, inbox groups, markdown references, and
profile/activity surfaces
> - The branch had many small UI fixes that improve the operator loop
but do not need to ship with backend runtime migrations
> - These changes belong together as board workflow polish because they
affect scanning, navigation, issue context, comment state, and markdown
clarity
> - This pull request groups the UI-only slice so it can merge
independently from runtime/backend changes
> - The benefit is a clearer board experience with better issue context,
steadier optimistic updates, and more predictable keyboard navigation
## What Changed
- Improves issue properties, sub-issue actions, blocker chips, and issue
list/detail refresh behavior.
- Adds blocker context above the issue composer and stabilizes
queued/interrupted comment UI state.
- Improves markdown issue/GitHub link rendering and opens external
markdown links in a new tab.
- Adds inbox group keyboard navigation and fold/unfold support.
- Polishes activity/avatar/profile/settings/workspace presentation
details.
## Verification
- `pnpm exec vitest run ui/src/components/IssueProperties.test.tsx
ui/src/components/IssueChatThread.test.tsx
ui/src/components/MarkdownBody.test.tsx ui/src/lib/inbox.test.ts
ui/src/lib/optimistic-issue-comments.test.ts`
## Risks
- Low to medium risk: changes are UI-focused but cover high-traffic
issue and inbox surfaces.
- This branch intentionally does not include the backend runtime changes
from the companion PR; where UI calls newer API filters, unsupported
servers should continue to fail visibly through existing API error
handling.
- Visual screenshots were not captured in this heartbeat; targeted
component/helper tests cover the changed behavior.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5-based coding agent runtime, shell/git tool use
enabled. Exact hosted model build and context window are not exposed in
this Paperclip heartbeat environment.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-04-21 12:25:34 -05:00
|
|
|
const isCollapsed = collapsedGroupKeys.has(group.key);
|
|
|
|
|
if (group.label) {
|
|
|
|
|
entries.push({
|
|
|
|
|
type: "group",
|
|
|
|
|
groupKey: group.key,
|
|
|
|
|
label: group.label,
|
|
|
|
|
collapsed: isCollapsed,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (isCollapsed) continue;
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
|
2026-05-01 11:58:53 -05:00
|
|
|
const addIssueChildren = (issueId: string, seen: ReadonlySet<string>) => {
|
|
|
|
|
const children = group.childrenByIssueId.get(issueId);
|
|
|
|
|
if (!children?.length || collapsedInboxParents.has(issueId)) return;
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
|
|
|
|
|
for (const child of children) {
|
2026-05-01 11:58:53 -05:00
|
|
|
if (seen.has(child.id)) continue;
|
|
|
|
|
const nextSeen = new Set(seen);
|
|
|
|
|
nextSeen.add(child.id);
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
entries.push({
|
|
|
|
|
type: "child",
|
|
|
|
|
issueId: child.id,
|
|
|
|
|
issue: child,
|
|
|
|
|
});
|
2026-05-01 11:58:53 -05:00
|
|
|
addIssueChildren(child.id, nextSeen);
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
}
|
2026-05-01 11:58:53 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (const item of group.displayItems) {
|
|
|
|
|
entries.push({
|
|
|
|
|
type: "top",
|
|
|
|
|
itemKey: `${group.key}:${getInboxWorkItemKey(item)}`,
|
|
|
|
|
item,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (item.kind !== "issue") continue;
|
|
|
|
|
addIssueChildren(item.issue.id, new Set([item.issue.id]));
|
[codex] Improve workspace runtime and navigation ergonomics (#3680)
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies
> - That operator experience depends not just on issue chat, but also on
how workspaces, inbox groups, and navigation state behave over
long-running sessions
> - The current branch included a separate cluster of workspace-runtime
controls, inbox grouping, sidebar ordering, and worktree lifecycle fixes
> - Those changes cross server, shared contracts, database state, and UI
navigation, but they still form one coherent operator workflow area
> - This pull request isolates the workspace/runtime and navigation
ergonomics work into one standalone branch
> - The benefit is better workspace recovery and navigation persistence
without forcing reviewers through the unrelated issue-detail/chat work
## What Changed
- Improved execution workspace and project workspace controls, request
wiring, layout, and JSON editor ergonomics
- Hardened linked worktree reuse/startup behavior and documented the
`worktree repair` flow for recovering linked worktrees safely
- Added inbox workspace grouping, mobile collapse, archive undo,
keyboard navigation, shared group-header styling, and persisted
collapsed-group behavior
- Added persistent sidebar order preferences with the supporting DB
migration, shared/server contracts, routes, services, hooks, and UI
integration
- Scoped issue-list preferences by context and added targeted UI/server
tests for workspace controls, inbox behavior, sidebar preferences, and
worktree validation
## Verification
- `pnpm vitest run
server/src/__tests__/sidebar-preferences-routes.test.ts
ui/src/pages/Inbox.test.tsx
ui/src/components/ProjectWorkspaceSummaryCard.test.tsx
ui/src/components/WorkspaceRuntimeControls.test.tsx
ui/src/api/workspace-runtime-control.test.ts`
- `server/src/__tests__/workspace-runtime.test.ts` was attempted, but
the embedded Postgres suite self-skipped/hung on this host after
reporting an init-script issue, so it is not counted as a local pass
here
## Risks
- Medium: this branch includes migration-backed preference storage plus
worktree/runtime behavior, so merge review should pay attention to state
persistence and worktree recovery semantics
- The sidebar preference migration is standalone, but it should still be
watched for conflicts if another migration lands first
## Model Used
- OpenAI Codex coding agent (GPT-5-class runtime in Codex CLI; exact
deployed model ID is not exposed in this environment), reasoning
enabled, tool use and local code execution enabled
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-14 12:57:11 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return entries;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-17 16:10:26 -05:00
|
|
|
export function shouldShowInboxSection({
|
|
|
|
|
tab,
|
|
|
|
|
hasItems,
|
2026-03-26 08:19:16 -05:00
|
|
|
showOnMine,
|
2026-03-17 16:10:26 -05:00
|
|
|
showOnRecent,
|
|
|
|
|
showOnUnread,
|
|
|
|
|
showOnAll,
|
|
|
|
|
}: {
|
|
|
|
|
tab: InboxTab;
|
|
|
|
|
hasItems: boolean;
|
2026-03-26 08:19:16 -05:00
|
|
|
showOnMine: boolean;
|
2026-03-17 16:10:26 -05:00
|
|
|
showOnRecent: boolean;
|
|
|
|
|
showOnUnread: boolean;
|
|
|
|
|
showOnAll: boolean;
|
|
|
|
|
}): boolean {
|
|
|
|
|
if (!hasItems) return false;
|
2026-03-26 08:19:16 -05:00
|
|
|
if (tab === "mine") return showOnMine;
|
2026-03-17 16:10:26 -05:00
|
|
|
if (tab === "recent") return showOnRecent;
|
|
|
|
|
if (tab === "unread") return showOnUnread;
|
|
|
|
|
return showOnAll;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-10 22:55:45 -05:00
|
|
|
export function computeInboxBadgeData({
|
|
|
|
|
approvals,
|
|
|
|
|
joinRequests,
|
|
|
|
|
dashboard,
|
|
|
|
|
heartbeatRuns,
|
2026-03-26 08:19:16 -05:00
|
|
|
mineIssues,
|
2026-04-07 18:26:34 -05:00
|
|
|
dismissedAlerts,
|
|
|
|
|
dismissedAtByKey,
|
feat: implement multi-user access and invite flows (#3784)
## Thinking Path
> - Paperclip is the control plane for autonomous AI companies.
> - V1 needs to stay local-first while also supporting shared,
authenticated deployments.
> - Human operators need real identities, company membership, invite
flows, profile surfaces, and company-scoped access controls.
> - Agents and operators also need the existing issue, inbox, workspace,
approval, and plugin flows to keep working under those authenticated
boundaries.
> - This branch accumulated the multi-user implementation, follow-up QA
fixes, workspace/runtime refinements, invite UX improvements,
release-branch conflict resolution, and review hardening.
> - This pull request consolidates that branch onto the current `master`
branch as a single reviewable PR.
> - The benefit is a complete multi-user implementation path with tests
and docs carried forward without dropping existing branch work.
## What Changed
- Added authenticated human-user access surfaces: auth/session routes,
company user directory, profile settings, company access/member
management, join requests, and invite management.
- Added invite creation, invite landing, onboarding, logo/branding,
invite grants, deduped join requests, and authenticated multi-user E2E
coverage.
- Tightened company-scoped and instance-admin authorization across
board, plugin, adapter, access, issue, and workspace routes.
- Added profile-image URL validation hardening, avatar preservation on
name-only profile updates, and join-request uniqueness migration cleanup
for pending human requests.
- Added an atomic member role/status/grants update path so Company
Access saves no longer leave partially updated permissions.
- Improved issue chat, inbox, assignee identity rendering,
sidebar/account/company navigation, workspace routing, and execution
workspace reuse behavior for multi-user operation.
- Added and updated server/UI tests covering auth, invites, membership,
issue workspace inheritance, plugin authz, inbox/chat behavior, and
multi-user flows.
- Merged current `public-gh/master` into this branch, resolved all
conflicts, and verified no `pnpm-lock.yaml` change is included in this
PR diff.
## Verification
- `pnpm exec vitest run server/src/__tests__/issues-service.test.ts
ui/src/components/IssueChatThread.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/plugin-routes-authz.test.ts`
- `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts
server/src/__tests__/workspace-runtime-service-authz.test.ts
server/src/__tests__/access-validators.test.ts`
- `pnpm exec vitest run
server/src/__tests__/authz-company-access.test.ts
server/src/__tests__/routines-routes.test.ts
server/src/__tests__/sidebar-preferences-routes.test.ts
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/openclaw-invite-prompt-route.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
server/src/__tests__/routines-e2e.test.ts`
- `pnpm exec vitest run server/src/__tests__/auth-routes.test.ts
ui/src/pages/CompanyAccess.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/db typecheck && pnpm --filter @paperclipai/server
typecheck`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm db:generate`
- `npx playwright test --config tests/e2e/playwright.config.ts --list`
- Confirmed branch has no uncommitted changes and is `0` commits behind
`public-gh/master` before PR creation.
- Confirmed no `pnpm-lock.yaml` change is staged or present in the PR
diff.
## Risks
- High review surface area: this PR contains the accumulated multi-user
branch plus follow-up fixes, so reviewers should focus especially on
company-boundary enforcement and authenticated-vs-local deployment
behavior.
- UI behavior changed across invites, inbox, issue chat, access
settings, and sidebar navigation; no browser screenshots are included in
this branch-consolidation PR.
- Plugin install, upgrade, and lifecycle/config mutations now require
instance-admin access, which is intentional but may change expectations
for non-admin board users.
- A join-request dedupe migration rejects duplicate pending human
requests before creating unique indexes; deployments with unusual
historical duplicates should review the migration behavior.
- Company member role/status/grant saves now use a new combined
endpoint; older separate endpoints remain for compatibility.
- Full production build was not run locally in this heartbeat; CI should
cover the full matrix.
## Model Used
- OpenAI Codex coding agent, GPT-5-based model, CLI/tool-use
environment. Exact deployed model identifier and context window were not
exposed by the runtime.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
Note on screenshots: this is a branch-consolidation PR for an
already-developed multi-user branch, and no browser screenshots were
captured during this heartbeat.
---------
Co-authored-by: dotta <dotta@example.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:44:19 -05:00
|
|
|
currentUserId,
|
2026-03-10 22:55:45 -05:00
|
|
|
}: {
|
|
|
|
|
approvals: Approval[];
|
|
|
|
|
joinRequests: JoinRequest[];
|
|
|
|
|
dashboard: DashboardSummary | undefined;
|
|
|
|
|
heartbeatRuns: HeartbeatRun[];
|
2026-03-26 08:19:16 -05:00
|
|
|
mineIssues: Issue[];
|
2026-04-07 18:26:34 -05:00
|
|
|
dismissedAlerts: Set<string>;
|
|
|
|
|
dismissedAtByKey: ReadonlyMap<string, number>;
|
feat: implement multi-user access and invite flows (#3784)
## Thinking Path
> - Paperclip is the control plane for autonomous AI companies.
> - V1 needs to stay local-first while also supporting shared,
authenticated deployments.
> - Human operators need real identities, company membership, invite
flows, profile surfaces, and company-scoped access controls.
> - Agents and operators also need the existing issue, inbox, workspace,
approval, and plugin flows to keep working under those authenticated
boundaries.
> - This branch accumulated the multi-user implementation, follow-up QA
fixes, workspace/runtime refinements, invite UX improvements,
release-branch conflict resolution, and review hardening.
> - This pull request consolidates that branch onto the current `master`
branch as a single reviewable PR.
> - The benefit is a complete multi-user implementation path with tests
and docs carried forward without dropping existing branch work.
## What Changed
- Added authenticated human-user access surfaces: auth/session routes,
company user directory, profile settings, company access/member
management, join requests, and invite management.
- Added invite creation, invite landing, onboarding, logo/branding,
invite grants, deduped join requests, and authenticated multi-user E2E
coverage.
- Tightened company-scoped and instance-admin authorization across
board, plugin, adapter, access, issue, and workspace routes.
- Added profile-image URL validation hardening, avatar preservation on
name-only profile updates, and join-request uniqueness migration cleanup
for pending human requests.
- Added an atomic member role/status/grants update path so Company
Access saves no longer leave partially updated permissions.
- Improved issue chat, inbox, assignee identity rendering,
sidebar/account/company navigation, workspace routing, and execution
workspace reuse behavior for multi-user operation.
- Added and updated server/UI tests covering auth, invites, membership,
issue workspace inheritance, plugin authz, inbox/chat behavior, and
multi-user flows.
- Merged current `public-gh/master` into this branch, resolved all
conflicts, and verified no `pnpm-lock.yaml` change is included in this
PR diff.
## Verification
- `pnpm exec vitest run server/src/__tests__/issues-service.test.ts
ui/src/components/IssueChatThread.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/plugin-routes-authz.test.ts`
- `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts
server/src/__tests__/workspace-runtime-service-authz.test.ts
server/src/__tests__/access-validators.test.ts`
- `pnpm exec vitest run
server/src/__tests__/authz-company-access.test.ts
server/src/__tests__/routines-routes.test.ts
server/src/__tests__/sidebar-preferences-routes.test.ts
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/openclaw-invite-prompt-route.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
server/src/__tests__/routines-e2e.test.ts`
- `pnpm exec vitest run server/src/__tests__/auth-routes.test.ts
ui/src/pages/CompanyAccess.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/db typecheck && pnpm --filter @paperclipai/server
typecheck`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm db:generate`
- `npx playwright test --config tests/e2e/playwright.config.ts --list`
- Confirmed branch has no uncommitted changes and is `0` commits behind
`public-gh/master` before PR creation.
- Confirmed no `pnpm-lock.yaml` change is staged or present in the PR
diff.
## Risks
- High review surface area: this PR contains the accumulated multi-user
branch plus follow-up fixes, so reviewers should focus especially on
company-boundary enforcement and authenticated-vs-local deployment
behavior.
- UI behavior changed across invites, inbox, issue chat, access
settings, and sidebar navigation; no browser screenshots are included in
this branch-consolidation PR.
- Plugin install, upgrade, and lifecycle/config mutations now require
instance-admin access, which is intentional but may change expectations
for non-admin board users.
- A join-request dedupe migration rejects duplicate pending human
requests before creating unique indexes; deployments with unusual
historical duplicates should review the migration behavior.
- Company member role/status/grant saves now use a new combined
endpoint; older separate endpoints remain for compatibility.
- Full production build was not run locally in this heartbeat; CI should
cover the full matrix.
## Model Used
- OpenAI Codex coding agent, GPT-5-based model, CLI/tool-use
environment. Exact deployed model identifier and context window were not
exposed by the runtime.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
Note on screenshots: this is a branch-consolidation PR for an
already-developed multi-user branch, and no browser screenshots were
captured during this heartbeat.
---------
Co-authored-by: dotta <dotta@example.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:44:19 -05:00
|
|
|
currentUserId?: string | null;
|
2026-03-10 22:55:45 -05:00
|
|
|
}): InboxBadgeData {
|
2026-03-26 10:16:19 -05:00
|
|
|
const actionableApprovals = approvals.filter(
|
|
|
|
|
(approval) =>
|
[codex] Polish issue and operator workflow UI (#4090)
## Thinking Path
> - Paperclip operators spend much of their time in issues, inboxes,
selectors, and rich comment threads.
> - Small interaction problems in those surfaces slow down supervision
of AI-agent work.
> - The branch included related operator quality-of-life fixes for issue
layout, inbox actions, recent selectors, mobile inputs, and chat
rendering stability.
> - These changes are UI-focused and can land independently from
workspace navigation and access-profile work.
> - This pull request groups the operator QoL fixes into one standalone
branch.
> - The benefit is a more stable and efficient board workflow for issue
triage and task editing.
## What Changed
- Widened issue detail content and added a desktop inbox archive action.
- Fixed mobile text-field zoom by keeping touch input font sizes at
16px.
- Prioritized recent picker selections for assignees/projects in issue
and routine flows.
- Showed actionable approvals in the Mine inbox model.
- Fixed issue chat renderer state crashes and hardened tests.
## Verification
- `pnpm install --frozen-lockfile`
- `pnpm exec vitest run ui/src/components/IssueChatThread.test.tsx
ui/src/lib/inbox.test.ts ui/src/lib/recent-selections.test.ts`
- Split integration check: merged last after the other
[PAP-1614](/PAP/issues/PAP-1614) branches with no merge conflicts.
- Confirmed this branch does not include `pnpm-lock.yaml`.
## Risks
- Low to medium risk: mostly UI state, layout, and selection-priority
behavior.
- Visual layout and mobile zoom behavior may need browser/device QA
beyond component tests.
- No database migrations are included.
> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.
## Model Used
- OpenAI Codex, GPT-5.4 tool-enabled coding model, agentic
code-editing/runtime with local shell and GitHub CLI access; exact
context window and reasoning mode are not exposed by the Paperclip
harness.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-20 06:16:41 -05:00
|
|
|
isApprovalVisibleInMine(approval, currentUserId) &&
|
2026-03-26 10:16:19 -05:00
|
|
|
ACTIONABLE_APPROVAL_STATUSES.has(approval.status) &&
|
2026-04-07 18:26:34 -05:00
|
|
|
!isInboxEntityDismissed(dismissedAtByKey, `approval:${approval.id}`, approval.updatedAt),
|
2026-03-10 22:55:45 -05:00
|
|
|
).length;
|
|
|
|
|
const failedRuns = getLatestFailedRunsByAgent(heartbeatRuns).filter(
|
2026-04-07 18:26:34 -05:00
|
|
|
(run) => !isInboxEntityDismissed(dismissedAtByKey, `run:${run.id}`, run.createdAt),
|
2026-03-10 22:55:45 -05:00
|
|
|
).length;
|
2026-03-26 10:16:19 -05:00
|
|
|
const visibleJoinRequests = joinRequests.filter(
|
2026-04-07 18:26:34 -05:00
|
|
|
(jr) => !isInboxEntityDismissed(dismissedAtByKey, `join:${jr.id}`, jr.updatedAt ?? jr.createdAt),
|
2026-03-26 10:16:19 -05:00
|
|
|
).length;
|
2026-04-02 18:21:55 +08:00
|
|
|
const visibleMineIssues = mineIssues.filter((issue) => issue.isUnreadForMe).length;
|
2026-03-10 22:55:45 -05:00
|
|
|
const agentErrorCount = dashboard?.agents.error ?? 0;
|
|
|
|
|
const monthBudgetCents = dashboard?.costs.monthBudgetCents ?? 0;
|
|
|
|
|
const monthUtilizationPercent = dashboard?.costs.monthUtilizationPercent ?? 0;
|
|
|
|
|
const showAggregateAgentError =
|
|
|
|
|
agentErrorCount > 0 &&
|
|
|
|
|
failedRuns === 0 &&
|
2026-04-07 18:26:34 -05:00
|
|
|
!dismissedAlerts.has("alert:agent-errors");
|
2026-03-10 22:55:45 -05:00
|
|
|
const showBudgetAlert =
|
|
|
|
|
monthBudgetCents > 0 &&
|
|
|
|
|
monthUtilizationPercent >= 80 &&
|
2026-04-07 18:26:34 -05:00
|
|
|
!dismissedAlerts.has("alert:budget");
|
2026-03-10 22:55:45 -05:00
|
|
|
const alerts = Number(showAggregateAgentError) + Number(showBudgetAlert);
|
|
|
|
|
|
|
|
|
|
return {
|
feat: implement multi-user access and invite flows (#3784)
## Thinking Path
> - Paperclip is the control plane for autonomous AI companies.
> - V1 needs to stay local-first while also supporting shared,
authenticated deployments.
> - Human operators need real identities, company membership, invite
flows, profile surfaces, and company-scoped access controls.
> - Agents and operators also need the existing issue, inbox, workspace,
approval, and plugin flows to keep working under those authenticated
boundaries.
> - This branch accumulated the multi-user implementation, follow-up QA
fixes, workspace/runtime refinements, invite UX improvements,
release-branch conflict resolution, and review hardening.
> - This pull request consolidates that branch onto the current `master`
branch as a single reviewable PR.
> - The benefit is a complete multi-user implementation path with tests
and docs carried forward without dropping existing branch work.
## What Changed
- Added authenticated human-user access surfaces: auth/session routes,
company user directory, profile settings, company access/member
management, join requests, and invite management.
- Added invite creation, invite landing, onboarding, logo/branding,
invite grants, deduped join requests, and authenticated multi-user E2E
coverage.
- Tightened company-scoped and instance-admin authorization across
board, plugin, adapter, access, issue, and workspace routes.
- Added profile-image URL validation hardening, avatar preservation on
name-only profile updates, and join-request uniqueness migration cleanup
for pending human requests.
- Added an atomic member role/status/grants update path so Company
Access saves no longer leave partially updated permissions.
- Improved issue chat, inbox, assignee identity rendering,
sidebar/account/company navigation, workspace routing, and execution
workspace reuse behavior for multi-user operation.
- Added and updated server/UI tests covering auth, invites, membership,
issue workspace inheritance, plugin authz, inbox/chat behavior, and
multi-user flows.
- Merged current `public-gh/master` into this branch, resolved all
conflicts, and verified no `pnpm-lock.yaml` change is included in this
PR diff.
## Verification
- `pnpm exec vitest run server/src/__tests__/issues-service.test.ts
ui/src/components/IssueChatThread.test.tsx ui/src/pages/Inbox.test.tsx`
- `pnpm run preflight:workspace-links && pnpm exec vitest run
server/src/__tests__/plugin-routes-authz.test.ts`
- `pnpm exec vitest run server/src/__tests__/plugin-routes-authz.test.ts
server/src/__tests__/workspace-runtime-service-authz.test.ts
server/src/__tests__/access-validators.test.ts`
- `pnpm exec vitest run
server/src/__tests__/authz-company-access.test.ts
server/src/__tests__/routines-routes.test.ts
server/src/__tests__/sidebar-preferences-routes.test.ts
server/src/__tests__/approval-routes-idempotency.test.ts
server/src/__tests__/openclaw-invite-prompt-route.test.ts
server/src/__tests__/agent-cross-tenant-authz-routes.test.ts
server/src/__tests__/routines-e2e.test.ts`
- `pnpm exec vitest run server/src/__tests__/auth-routes.test.ts
ui/src/pages/CompanyAccess.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/db typecheck && pnpm --filter @paperclipai/server
typecheck`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm db:generate`
- `npx playwright test --config tests/e2e/playwright.config.ts --list`
- Confirmed branch has no uncommitted changes and is `0` commits behind
`public-gh/master` before PR creation.
- Confirmed no `pnpm-lock.yaml` change is staged or present in the PR
diff.
## Risks
- High review surface area: this PR contains the accumulated multi-user
branch plus follow-up fixes, so reviewers should focus especially on
company-boundary enforcement and authenticated-vs-local deployment
behavior.
- UI behavior changed across invites, inbox, issue chat, access
settings, and sidebar navigation; no browser screenshots are included in
this branch-consolidation PR.
- Plugin install, upgrade, and lifecycle/config mutations now require
instance-admin access, which is intentional but may change expectations
for non-admin board users.
- A join-request dedupe migration rejects duplicate pending human
requests before creating unique indexes; deployments with unusual
historical duplicates should review the migration behavior.
- Company member role/status/grant saves now use a new combined
endpoint; older separate endpoints remain for compatibility.
- Full production build was not run locally in this heartbeat; CI should
cover the full matrix.
## Model Used
- OpenAI Codex coding agent, GPT-5-based model, CLI/tool-use
environment. Exact deployed model identifier and context window were not
exposed by the runtime.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
Note on screenshots: this is a branch-consolidation PR for an
already-developed multi-user branch, and no browser screenshots were
captured during this heartbeat.
---------
Co-authored-by: dotta <dotta@example.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:44:19 -05:00
|
|
|
// The inbox badge reflects personal/actionable work, not company-wide health alerts.
|
|
|
|
|
inbox: actionableApprovals + visibleJoinRequests + failedRuns + visibleMineIssues,
|
2026-03-10 22:55:45 -05:00
|
|
|
approvals: actionableApprovals,
|
|
|
|
|
failedRuns,
|
2026-03-26 10:16:19 -05:00
|
|
|
joinRequests: visibleJoinRequests,
|
2026-03-26 08:19:16 -05:00
|
|
|
mineIssues: visibleMineIssues,
|
2026-03-10 22:55:45 -05:00
|
|
|
alerts,
|
|
|
|
|
};
|
|
|
|
|
}
|