Merge remote-tracking branch 'public-gh/master' into paperclip-subissues

* public-gh/master: (55 commits)
  fix(issue-documents): address greptile review
  Update packages/shared/src/validators/issue.ts
  feat(ui): add issue document copy and download actions
  fix(ui): unify new issue upload action
  feat(ui): stage issue files before create
  feat(ui): handle issue document edit conflicts
  fix(ui): refresh issue documents from live events
  feat(ui): deep link issue documents
  fix(ui): streamline issue document chrome
  fix(ui): collapse empty document and attachment states
  fix(ui): simplify document card body layout
  fix(issues): address document review comments
  feat(issues): add issue documents and inline editing
  docs: add agent evals framework plan
  fix(cli): quote env values with special characters
  Fix worktree seed source selection
  fix: address greptile follow-up
  docs: add paperclip skill tightening plan
  fix: isolate codex home in worktrees
  Add worktree UI branding
  ...

# Conflicts:
#	packages/db/src/migrations/meta/0028_snapshot.json
#	packages/db/src/migrations/meta/_journal.json
#	packages/shared/src/index.ts
#	server/src/routes/issues.ts
#	ui/src/api/issues.ts
#	ui/src/components/NewIssueDialog.tsx
#	ui/src/pages/IssueDetail.tsx
This commit is contained in:
Dotta
2026-03-14 12:24:40 -05:00
136 changed files with 17867 additions and 1511 deletions

View File

@@ -95,6 +95,11 @@ export type {
Issue,
IssueAssigneeAdapterOverrides,
IssueComment,
IssueDocument,
IssueDocumentSummary,
DocumentRevision,
DocumentFormat,
LegacyPlanDocument,
IssueAttachment,
IssueLabel,
Goal,
@@ -188,6 +193,9 @@ export {
issueWorkProductReviewStateSchema,
updateExecutionWorkspaceSchema,
executionWorkspaceStatusSchema,
issueDocumentFormatSchema,
issueDocumentKeySchema,
upsertIssueDocumentSchema,
type CreateIssue,
type CreateIssueLabel,
type UpdateIssue,
@@ -198,6 +206,8 @@ export {
type CreateIssueWorkProduct,
type UpdateIssueWorkProduct,
type UpdateExecutionWorkspace,
type IssueDocumentFormat,
type UpsertIssueDocument,
createGoalSchema,
updateGoalSchema,
type CreateGoal,

View File

@@ -34,6 +34,11 @@ export type {
Issue,
IssueAssigneeAdapterOverrides,
IssueComment,
IssueDocument,
IssueDocumentSummary,
DocumentRevision,
DocumentFormat,
LegacyPlanDocument,
IssueAncestor,
IssueAncestorProject,
IssueAncestorGoal,

View File

@@ -51,6 +51,49 @@ export interface IssueAssigneeAdapterOverrides {
useProjectWorkspace?: boolean;
}
export type DocumentFormat = "markdown";
export interface IssueDocumentSummary {
id: string;
companyId: string;
issueId: string;
key: string;
title: string | null;
format: DocumentFormat;
latestRevisionId: string | null;
latestRevisionNumber: number;
createdByAgentId: string | null;
createdByUserId: string | null;
updatedByAgentId: string | null;
updatedByUserId: string | null;
createdAt: Date;
updatedAt: Date;
}
export interface IssueDocument extends IssueDocumentSummary {
body: string;
}
export interface DocumentRevision {
id: string;
companyId: string;
documentId: string;
issueId: string;
key: string;
revisionNumber: number;
body: string;
changeSummary: string | null;
createdByAgentId: string | null;
createdByUserId: string | null;
createdAt: Date;
}
export interface LegacyPlanDocument {
key: "plan";
body: string;
source: "issue_description";
}
export interface Issue {
id: string;
companyId: string;
@@ -85,6 +128,9 @@ export interface Issue {
hiddenAt: Date | null;
labelIds?: string[];
labels?: IssueLabel[];
planDocument?: IssueDocument | null;
documentSummaries?: IssueDocumentSummary[];
legacyPlanDocument?: LegacyPlanDocument | null;
project?: Project | null;
goal?: Goal | null;
currentExecutionWorkspace?: ExecutionWorkspace | null;

View File

@@ -78,6 +78,10 @@ export const wakeAgentSchema = z.object({
reason: z.string().optional().nullable(),
payload: z.record(z.unknown()).optional().nullable(),
idempotencyKey: z.string().optional().nullable(),
forceFreshSession: z.preprocess(
(value) => (value === null ? undefined : value),
z.boolean().optional().default(false),
),
});
export type WakeAgent = z.infer<typeof wakeAgentSchema>;

View File

@@ -66,6 +66,9 @@ export {
addIssueCommentSchema,
linkIssueApprovalSchema,
createIssueAttachmentMetadataSchema,
issueDocumentFormatSchema,
issueDocumentKeySchema,
upsertIssueDocumentSchema,
type CreateIssue,
type CreateIssueLabel,
type UpdateIssue,
@@ -74,6 +77,8 @@ export {
type AddIssueComment,
type LinkIssueApproval,
type CreateIssueAttachmentMetadata,
type IssueDocumentFormat,
type UpsertIssueDocument,
} from "./issue.js";
export {

View File

@@ -97,3 +97,25 @@ export const createIssueAttachmentMetadataSchema = z.object({
});
export type CreateIssueAttachmentMetadata = z.infer<typeof createIssueAttachmentMetadataSchema>;
export const ISSUE_DOCUMENT_FORMATS = ["markdown"] as const;
export const issueDocumentFormatSchema = z.enum(ISSUE_DOCUMENT_FORMATS);
export const issueDocumentKeySchema = z
.string()
.trim()
.min(1)
.max(64)
.regex(/^[a-z0-9][a-z0-9_-]*$/, "Document key must be lowercase letters, numbers, _ or -");
export const upsertIssueDocumentSchema = z.object({
title: z.string().trim().max(200).nullable().optional(),
format: issueDocumentFormatSchema,
body: z.string().max(524288),
changeSummary: z.string().trim().max(500).nullable().optional(),
baseRevisionId: z.string().uuid().nullable().optional(),
});
export type IssueDocumentFormat = z.infer<typeof issueDocumentFormatSchema>;
export type UpsertIssueDocument = z.infer<typeof upsertIssueDocumentSchema>;