exponential-sdk 1.24.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1007,6 +1007,20 @@ interface TrpcClient {
1007
1007
  generateEmbeddings?: boolean;
1008
1008
  }) => Promise<unknown>;
1009
1009
  };
1010
+ get: {
1011
+ query: (input: {
1012
+ id: string;
1013
+ }) => Promise<unknown>;
1014
+ };
1015
+ update: {
1016
+ mutate: (input: {
1017
+ id: string;
1018
+ title?: string;
1019
+ description?: string;
1020
+ tags?: string[];
1021
+ readStatus?: string;
1022
+ }) => Promise<unknown>;
1023
+ };
1010
1024
  setReadStatus: {
1011
1025
  mutate: (input: {
1012
1026
  id: string;
@@ -4425,6 +4439,13 @@ interface ResourceCreateInput {
4425
4439
  /** Defaults to true server-side; a no-op when there is no content to embed. */
4426
4440
  generateEmbeddings?: boolean;
4427
4441
  }
4442
+ /** Fields `update` may change. `tags` replaces the whole set. */
4443
+ interface ResourceUpdateInput {
4444
+ title?: string;
4445
+ description?: string;
4446
+ tags?: string[];
4447
+ readStatus?: ReadStatus;
4448
+ }
4428
4449
  interface ResourceReadState {
4429
4450
  id: string;
4430
4451
  readStatus: ReadStatus | string;
@@ -4443,11 +4464,20 @@ declare class ResourcesApi {
4443
4464
  constructor(client: TrpcClient);
4444
4465
  list(options?: ResourceListOptions): Promise<ResourceListResult>;
4445
4466
  create(input: ResourceCreateInput): Promise<Resource>;
4446
- /** Save a link to the Reading list: a `bookmark` in `to_read`, not embedded. */
4467
+ get(id: string): Promise<Resource>;
4468
+ update(id: string, input: ResourceUpdateInput): Promise<Resource>;
4469
+ /**
4470
+ * Save a link to the Reading list: a `bookmark` in `to_read`, not embedded.
4471
+ *
4472
+ * `tags` are added to the ones the link already has. The server dedupes by
4473
+ * URL and would replace the set on re-save, so the link is saved untagged
4474
+ * (which leaves existing tags alone) and the union written after.
4475
+ */
4447
4476
  save(input: {
4448
4477
  url: string;
4449
4478
  title?: string;
4450
4479
  note?: string;
4480
+ tags?: string[];
4451
4481
  workspaceId?: string;
4452
4482
  readStatus?: ReadStatus;
4453
4483
  }): Promise<Resource>;
@@ -5032,4 +5062,4 @@ declare class ExponentialClient {
5032
5062
  });
5033
5063
  }
5034
5064
 
5035
- export { type Action, type ActionComment, type ActionCommentAddInput, type ActionCommentUpdateInput, type ActionCreateInput, type ActionOutput, type ActionStatus, type ActionUpdateInput, type ActionUpsertBySourceInput, type ActionUpsertBySourceResult, type ActionsListOutput, type AddInteractionInput, type AgentRunStatus, AgentRunsApi, type AppendEventsResult, type Area, type AreaCreateInput, type AreaListOptions, type ClaimedRun, type CommentAuthor, type Contact, type ContactCreateInput, type ContactInteraction, type ContactListOutput, type ContactUpdateInput, type ContactsListOptions, type ConversationMessage, DEFAULT_GAP_MINUTES, type DayReport, type DayReportActionRow, type DayReportEntry, type DayReportProductRow, type Deal, type DealActivity, type DealCreateInput, type DealMoveInput, type DealUpdateInput, type Decision, type DecisionAdrRef, type DecisionChainRef, type DecisionCreateInput, type DecisionDecider, type DecisionDeciderInput, type DecisionEvidenceTurn, type DecisionFeatureRef, type DecisionLink, type DecisionListOptions, type DecisionListRow, type DecisionMeetingRef, type DecisionOccurrenceRef, type DecisionProductRef, type DecisionProjectRef, type DecisionReviewState, type DecisionSetStatusInput, type DecisionSource, type DecisionStatus, type DecisionTicketRef, type DecisionUpdateInput, type DecisionUserRef, type DraftDecisionsResult, type EnrichContactResult, type Epic, type EpicCreateInput, type EpicListOptions, type EpicPriority, type EpicStatus, type EpicUpdateInput, ExponentialClient, type ExponentialConfig, type Feature, type FeatureComment, type FeatureCommentCreateInput, type FeatureCommentReplyInput, type FeatureCommentThreadInput, type FeatureCommentUpdateInput, type FeatureCreateInput, type FeatureKeyResultLink, type FeatureLinkPageInput, type FeatureListOptions, type FeatureScope, type FeatureScopeStatus, type FeatureStatus, type FeatureUpdateInput, type FinishInput, type FinishResult, type GlobalSearchOptions, type GlobalSearchOutput, type Goal, type GoalChildSummary, type GoalComment, type GoalCommentAddInput, type GoalCommentUpdateInput, type GoalCreateInput, type GoalHealth, type GoalKeyResultSummary, type GoalLifeDomain, type GoalListOptions, type GoalPeriod, type GoalProjectSummary, type GoalSetParentInput, type GoalSetStatusInput, type GoalStats, type GoalStatsOptions, type GoalStatus, type GoalTreeNode, type GoalTreeOptions, type GoalUpdateInput, type GoalUserSummary, type GoalWritableStatus, type HeartbeatResult, type InteractionDirection, type InteractionType, type KanbanStatus, type KeyResult, type KeyResultByObjectiveOptions, type KeyResultCheckIn, type KeyResultCheckInInput, type KeyResultCreateInput, type KeyResultFeatureLink, type KeyResultListOptions, type KeyResultProjectLink, type KeyResultStatus, type KeyResultUnit, type KeyResultUpdateInput, type KnowledgePage, type KnowledgeSearchOptions, type KnowledgeSearchOutput, type KnowledgeSearchResult, type KnowledgeSourceType, type LabelCreateInput, type LabelListOptions, type ListForEntityInput, type Meeting, type MeetingActionSummary, type MeetingCreateInput, type MeetingDecisions, type MeetingListOptions, type MeetingParticipant, type MeetingParticipantInput, type MeetingProjectRef, type MeetingSourceIntegration, type MeetingTypeFilter, type MeetingUpdateInput, type MeetingWorkspaceRef, type ObjectiveWithKeyResults, type Organization, type OrganizationCreateInput, type OrganizationListOutput, type OrganizationSize, type OrganizationsListOptions, type OverdueCohort, type OverdueTriage, type OverdueTriageRow, type PageComment, type PageCommentCreateInput, type PageCommentUpdateInput, type PageCreateInput, type PageDiff, type PageDiffOptions, type PageDiffSide, type PageGetFormat, type PageGetOptions, type PageHistory, type PageHistoryOptions, type PageListOptions, type PageOutlineEntry, type PageRestoreOptions, type PageRevision, type PageRevisionAuthor, type PageRevisionDetail, type PageRevisionKind, type PageSearchOptions, type PageSearchOutput, type PageSearchResult, type PageUpdateInput, type Pipeline, type PipelineStage, type Priority, type Product, type ProductCreateInput, type ProductUpdateInput, type Project, type ProjectDetail, type ProjectKeyResultLink, type ProjectOutput, type ProjectPriority, type ProjectStatus, type ProjectUpdateInput, type ProjectsListOptions, type ProjectsListOutput, ROUND_MINUTES, type ReadStatus, type Requirement, type RequirementCreateInput, type RequirementKind, type RequirementListOptions, type Resource, type ResourceContentType, type ResourceCreateInput, type ResourceListOptions, type ResourceListResult, type ResourceReadState, type RunMessage, type RunnerEvent, type RunnerEventKind, type ScopeCreateInput, type ScopeListOptions, type ScopeUpdateInput, type SearchResult, type SearchResultType, type SearchResultWorkspace, type SetEntityTagsInput, type SetEntityTagsResult, type Tag, type TagEntityType, type TagListResult, type Ticket, type TicketAssignee, type TicketComment, type TicketCommentAddInput, type TicketCommentUpdateInput, type TicketCreateInput, type TicketDependencyEdge, type TicketDetail, type TicketListOptions, type TicketSearchOptions, type TicketStatus, type TicketType, type TicketUpdateInput, TimeApi, type TimeConfirmDayResult, type TimeEntry, type TimeEntrySource, type TimeEntryStatus, type TimeLogBatchResult, type TimeLogInput, type TimeLogOutcome, type TimeLogResult, type TodaysActionRow, type TodaysActions, type TodaysActionsGroup, type UserStory, type UserStoryCreateInput, type UserStoryListOptions, type UserStoryUpdateInput, type WorklogSegment, type Workspace, type WorkspaceMember, type WorkspaceOutput, type WorkspacesListOutput, clearConfig, createConfigStore, getConfigPath, isAuthenticated, isTRPCError, loadConfig, saveConfig, segmentConversation };
5065
+ export { type Action, type ActionComment, type ActionCommentAddInput, type ActionCommentUpdateInput, type ActionCreateInput, type ActionOutput, type ActionStatus, type ActionUpdateInput, type ActionUpsertBySourceInput, type ActionUpsertBySourceResult, type ActionsListOutput, type AddInteractionInput, type AgentRunStatus, AgentRunsApi, type AppendEventsResult, type Area, type AreaCreateInput, type AreaListOptions, type ClaimedRun, type CommentAuthor, type Contact, type ContactCreateInput, type ContactInteraction, type ContactListOutput, type ContactUpdateInput, type ContactsListOptions, type ConversationMessage, DEFAULT_GAP_MINUTES, type DayReport, type DayReportActionRow, type DayReportEntry, type DayReportProductRow, type Deal, type DealActivity, type DealCreateInput, type DealMoveInput, type DealUpdateInput, type Decision, type DecisionAdrRef, type DecisionChainRef, type DecisionCreateInput, type DecisionDecider, type DecisionDeciderInput, type DecisionEvidenceTurn, type DecisionFeatureRef, type DecisionLink, type DecisionListOptions, type DecisionListRow, type DecisionMeetingRef, type DecisionOccurrenceRef, type DecisionProductRef, type DecisionProjectRef, type DecisionReviewState, type DecisionSetStatusInput, type DecisionSource, type DecisionStatus, type DecisionTicketRef, type DecisionUpdateInput, type DecisionUserRef, type DraftDecisionsResult, type EnrichContactResult, type Epic, type EpicCreateInput, type EpicListOptions, type EpicPriority, type EpicStatus, type EpicUpdateInput, ExponentialClient, type ExponentialConfig, type Feature, type FeatureComment, type FeatureCommentCreateInput, type FeatureCommentReplyInput, type FeatureCommentThreadInput, type FeatureCommentUpdateInput, type FeatureCreateInput, type FeatureKeyResultLink, type FeatureLinkPageInput, type FeatureListOptions, type FeatureScope, type FeatureScopeStatus, type FeatureStatus, type FeatureUpdateInput, type FinishInput, type FinishResult, type GlobalSearchOptions, type GlobalSearchOutput, type Goal, type GoalChildSummary, type GoalComment, type GoalCommentAddInput, type GoalCommentUpdateInput, type GoalCreateInput, type GoalHealth, type GoalKeyResultSummary, type GoalLifeDomain, type GoalListOptions, type GoalPeriod, type GoalProjectSummary, type GoalSetParentInput, type GoalSetStatusInput, type GoalStats, type GoalStatsOptions, type GoalStatus, type GoalTreeNode, type GoalTreeOptions, type GoalUpdateInput, type GoalUserSummary, type GoalWritableStatus, type HeartbeatResult, type InteractionDirection, type InteractionType, type KanbanStatus, type KeyResult, type KeyResultByObjectiveOptions, type KeyResultCheckIn, type KeyResultCheckInInput, type KeyResultCreateInput, type KeyResultFeatureLink, type KeyResultListOptions, type KeyResultProjectLink, type KeyResultStatus, type KeyResultUnit, type KeyResultUpdateInput, type KnowledgePage, type KnowledgeSearchOptions, type KnowledgeSearchOutput, type KnowledgeSearchResult, type KnowledgeSourceType, type LabelCreateInput, type LabelListOptions, type ListForEntityInput, type Meeting, type MeetingActionSummary, type MeetingCreateInput, type MeetingDecisions, type MeetingListOptions, type MeetingParticipant, type MeetingParticipantInput, type MeetingProjectRef, type MeetingSourceIntegration, type MeetingTypeFilter, type MeetingUpdateInput, type MeetingWorkspaceRef, type ObjectiveWithKeyResults, type Organization, type OrganizationCreateInput, type OrganizationListOutput, type OrganizationSize, type OrganizationsListOptions, type OverdueCohort, type OverdueTriage, type OverdueTriageRow, type PageComment, type PageCommentCreateInput, type PageCommentUpdateInput, type PageCreateInput, type PageDiff, type PageDiffOptions, type PageDiffSide, type PageGetFormat, type PageGetOptions, type PageHistory, type PageHistoryOptions, type PageListOptions, type PageOutlineEntry, type PageRestoreOptions, type PageRevision, type PageRevisionAuthor, type PageRevisionDetail, type PageRevisionKind, type PageSearchOptions, type PageSearchOutput, type PageSearchResult, type PageUpdateInput, type Pipeline, type PipelineStage, type Priority, type Product, type ProductCreateInput, type ProductUpdateInput, type Project, type ProjectDetail, type ProjectKeyResultLink, type ProjectOutput, type ProjectPriority, type ProjectStatus, type ProjectUpdateInput, type ProjectsListOptions, type ProjectsListOutput, ROUND_MINUTES, type ReadStatus, type Requirement, type RequirementCreateInput, type RequirementKind, type RequirementListOptions, type Resource, type ResourceContentType, type ResourceCreateInput, type ResourceListOptions, type ResourceListResult, type ResourceReadState, type ResourceUpdateInput, type RunMessage, type RunnerEvent, type RunnerEventKind, type ScopeCreateInput, type ScopeListOptions, type ScopeUpdateInput, type SearchResult, type SearchResultType, type SearchResultWorkspace, type SetEntityTagsInput, type SetEntityTagsResult, type Tag, type TagEntityType, type TagListResult, type Ticket, type TicketAssignee, type TicketComment, type TicketCommentAddInput, type TicketCommentUpdateInput, type TicketCreateInput, type TicketDependencyEdge, type TicketDetail, type TicketListOptions, type TicketSearchOptions, type TicketStatus, type TicketType, type TicketUpdateInput, TimeApi, type TimeConfirmDayResult, type TimeEntry, type TimeEntrySource, type TimeEntryStatus, type TimeLogBatchResult, type TimeLogInput, type TimeLogOutcome, type TimeLogResult, type TodaysActionRow, type TodaysActions, type TodaysActionsGroup, type UserStory, type UserStoryCreateInput, type UserStoryListOptions, type UserStoryUpdateInput, type WorklogSegment, type Workspace, type WorkspaceMember, type WorkspaceOutput, type WorkspacesListOutput, clearConfig, createConfigStore, getConfigPath, isAuthenticated, isTRPCError, loadConfig, saveConfig, segmentConversation };
package/dist/index.js CHANGED
@@ -1149,9 +1149,23 @@ var ResourcesApi = class {
1149
1149
  const result = await this.client.resource.create.mutate(input);
1150
1150
  return result.resource;
1151
1151
  }
1152
- /** Save a link to the Reading list: a `bookmark` in `to_read`, not embedded. */
1152
+ async get(id) {
1153
+ const result = await this.client.resource.get.query({ id });
1154
+ return result.resource;
1155
+ }
1156
+ async update(id, input) {
1157
+ const result = await this.client.resource.update.mutate({ id, ...input });
1158
+ return result.resource;
1159
+ }
1160
+ /**
1161
+ * Save a link to the Reading list: a `bookmark` in `to_read`, not embedded.
1162
+ *
1163
+ * `tags` are added to the ones the link already has. The server dedupes by
1164
+ * URL and would replace the set on re-save, so the link is saved untagged
1165
+ * (which leaves existing tags alone) and the union written after.
1166
+ */
1153
1167
  async save(input) {
1154
- return await this.create({
1168
+ const resource = await this.create({
1155
1169
  title: input.title?.trim() || hostnameOf(input.url) || input.url,
1156
1170
  url: input.url,
1157
1171
  description: input.note,
@@ -1160,6 +1174,10 @@ var ResourcesApi = class {
1160
1174
  generateEmbeddings: false,
1161
1175
  workspaceId: input.workspaceId
1162
1176
  });
1177
+ const existing = resource.tags ?? [];
1178
+ const added = (input.tags ?? []).filter((t) => !existing.includes(t));
1179
+ if (added.length === 0) return resource;
1180
+ return await this.update(resource.id, { tags: [...existing, ...added] });
1163
1181
  }
1164
1182
  async setReadStatus(id, readStatus) {
1165
1183
  return await this.client.resource.setReadStatus.mutate({ id, readStatus });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/actions.ts","../src/actionComments.ts","../src/featureComments.ts","../src/pageComments.ts","../src/goalComments.ts","../src/goals.ts","../src/keyResults.ts","../src/projects.ts","../src/workspaces.ts","../src/contacts.ts","../src/decisions.ts","../src/organizations.ts","../src/pipelines.ts","../src/tickets.ts","../src/products.ts","../src/features.ts","../src/userStories.ts","../src/epics.ts","../src/labels.ts","../src/areas.ts","../src/meetings.ts","../src/pages.ts","../src/resources.ts","../src/requirements.ts","../src/scopes.ts","../src/search.ts","../src/time.ts","../src/agentRuns.ts","../src/config.ts","../src/segment.ts","../src/index.ts"],"sourcesContent":["import { createTRPCClient, httpBatchLink, TRPCClientError } from '@trpc/client';\nimport superjson from 'superjson';\n\ntype ActionInput = {\n assigneeId?: string;\n};\n\ntype KanbanInput = {\n projectId?: string;\n assigneeId?: string;\n kanbanStatus?: 'BACKLOG' | 'TODO' | 'IN_PROGRESS' | 'IN_REVIEW' | 'DONE' | 'CANCELLED';\n};\n\ntype TodayInput = {\n workspaceId?: string;\n};\n\ntype DateRangeInput = {\n startDate: Date;\n endDate: Date;\n workspaceId?: string;\n};\n\ntype ProjectInput = {\n include?: {\n actions?: boolean;\n };\n workspaceId?: string;\n};\n\n/**\n * `project.update` as the server declares it: `name`, `status` and `priority`\n * are REQUIRED on every call, the rest are optional and only written when\n * present. `ProjectsApi.update` fills the required three from the current\n * project so callers can still pass a partial.\n */\ntype ProjectUpdateApiInput = {\n id: string;\n name: string;\n status: 'ACTIVE' | 'ON_HOLD' | 'COMPLETED' | 'CANCELLED';\n priority: 'HIGH' | 'MEDIUM' | 'LOW' | 'NONE';\n description?: string;\n productId?: string | null;\n workspaceId?: string | null;\n driId?: string | null;\n goalIds?: string[];\n outcomeIds?: string[];\n keyResultIds?: string[];\n lifeDomainIds?: number[];\n reviewDate?: Date | null;\n nextActionDate?: Date | null;\n startDate?: Date | null;\n endDate?: Date | null;\n};\n\ntype ActionStatus = 'ACTIVE' | 'COMPLETED' | 'CANCELLED' | 'DELETED' | 'DRAFT';\ntype ActionKanbanStatus = 'BACKLOG' | 'TODO' | 'IN_PROGRESS' | 'IN_REVIEW' | 'DONE' | 'CANCELLED';\ntype ActionPriority = 'Quick' | 'Scheduled' | '1st Priority' | '2nd Priority' | '3rd Priority' | '4th Priority' | '5th Priority' | 'Errand' | 'Remember' | 'Watch' | 'Someday Maybe';\n\ntype ActionCreateInput = {\n name: string;\n description?: string;\n projectId?: string;\n workspaceId?: string;\n dueDate?: Date;\n scheduledStart?: Date;\n scheduledEnd?: Date;\n duration?: number;\n priority?: ActionPriority;\n status?: ActionStatus;\n epicId?: string;\n effortEstimate?: number;\n blockedByIds?: string[];\n};\n\n// ── Goals (objectives) and key results ──────────────────────────────────────\n// Objectives are `Goal` rows with INTEGER ids; key results are `KeyResult` rows\n// with cuid ids. `period` is a free-form string (\"Q3-2026\", \"Annual-2026\").\n\ntype GoalStatusInput = 'planned' | 'active' | 'completed' | 'archived';\n/** Reads and `updateGoalStatus` also accept `on-hold`; `updateGoal` does not. */\ntype GoalQueryStatusInput = GoalStatusInput | 'on-hold';\n\ntype GoalCreateProcedureInput = {\n title: string;\n description?: string;\n whyThisGoal?: string;\n notes?: string;\n dueDate?: Date;\n period?: string;\n status?: GoalStatusInput;\n lifeDomainId?: number;\n projectId?: string;\n outcomeIds?: string[];\n driUserId?: string;\n workspaceId?: string;\n parentGoalId?: number;\n icon?: string | null;\n iconColor?: string | null;\n};\n\ntype GoalUpdateProcedureInput = {\n id: number;\n title?: string;\n description?: string | null;\n whyThisGoal?: string | null;\n notes?: string | null;\n dueDate?: Date | null;\n period?: string | null;\n status?: GoalStatusInput;\n lifeDomainId?: number | null;\n projectId?: string | null;\n projectIds?: string[];\n outcomeIds?: string[];\n driUserId?: string | null;\n workspaceId?: string | null;\n parentGoalId?: number | null;\n displayOrder?: number;\n icon?: string | null;\n iconColor?: string | null;\n};\n\ntype KeyResultStatusInput =\n | 'not-started'\n | 'on-track'\n | 'at-risk'\n | 'off-track'\n | 'achieved';\n\ntype KeyResultUnitInput = 'percent' | 'count' | 'currency' | 'hours' | 'custom';\n\ntype KeyResultCreateProcedureInput = {\n goalId: number;\n title: string;\n description?: string;\n targetValue: number;\n startValue?: number;\n currentValue?: number;\n unit?: KeyResultUnitInput;\n unitLabel?: string;\n period: string;\n periodStart?: Date;\n periodEnd?: Date;\n driUserId?: string;\n workspaceId?: string;\n};\n\ntype KeyResultUpdateProcedureInput = {\n id: string;\n title?: string;\n description?: string;\n targetValue?: number;\n currentValue?: number;\n startValue?: number;\n unit?: KeyResultUnitInput;\n unitLabel?: string;\n status?: KeyResultStatusInput;\n confidence?: number;\n driUserId?: string;\n goalId?: number;\n};\n\ntype ActionUpdateInput = {\n id: string;\n name?: string;\n description?: string;\n projectId?: string;\n workspaceId?: string | null;\n dueDate?: Date | null;\n scheduledStart?: Date | null;\n scheduledEnd?: Date | null;\n duration?: number | null;\n priority?: ActionPriority;\n status?: ActionStatus;\n kanbanStatus?: ActionKanbanStatus;\n epicId?: string | null;\n effortEstimate?: number | null;\n blockedByIds?: string[];\n};\n\ntype MeetingParticipantPersonInput = {\n userId?: string;\n contactId?: string;\n email?: string;\n name?: string;\n};\n\ntype MeetingCreateProcedureInput = {\n title: string;\n transcription: string;\n description?: string;\n notes?: string;\n meetingDate?: Date;\n projectId?: string;\n workspaceId?: string;\n participants?: MeetingParticipantPersonInput[];\n};\n\ntype MeetingUpdateDetailsProcedureInput = {\n id: string;\n description?: string;\n notes?: string;\n summary?: string;\n transcription?: string;\n workspaceId?: string | null;\n meetingDate?: Date | null;\n};\n\n// ── Decisions (ADR-0060) ────────────────────────────────────────────────────\n// One model behind both meeting panels: an OPEN QUESTION is a decision whose\n// status is `OPEN`. Every procedure is workspace-scoped except\n// `listForMeeting`, which resolves the workspace from the meeting.\n\ntype DecisionStatusInput =\n | 'OPEN'\n | 'PROPOSED'\n | 'ACCEPTED'\n | 'SUPERSEDED'\n | 'DEPRECATED';\n\ntype DecisionSourceInput = 'MEETING' | 'MANUAL' | 'AGENT';\n\ntype DecisionEvidenceInput = {\n turnIndex: number;\n speaker?: string | null;\n startTime?: number | null;\n text: string;\n};\n\ntype DecisionDeciderProcedureInput = {\n userId?: string | null;\n name: string;\n email?: string | null;\n};\n\ntype DecisionCreateProcedureInput = {\n workspaceId: string;\n statement: string;\n body?: string | null;\n status?: DecisionStatusInput;\n source?: DecisionSourceInput;\n decidedAt?: Date | null;\n ownerId?: string | null;\n transcriptionSessionId?: string | null;\n occurrenceId?: string | null;\n productId?: string | null;\n projectId?: string | null;\n goalId?: number | null;\n keyResultId?: string | null;\n deciders?: DecisionDeciderProcedureInput[];\n evidence?: DecisionEvidenceInput[];\n};\n\ntype DecisionUpdateProcedureInput = {\n workspaceId: string;\n decisionId: string;\n statement?: string;\n body?: string | null;\n decidedAt?: Date | null;\n ownerId?: string | null;\n productId?: string | null;\n projectId?: string | null;\n goalId?: number | null;\n keyResultId?: string | null;\n adrDocumentId?: string | null;\n};\n\ntype ActionUpsertBySourceInput = {\n sourceType: string;\n sourceId: string;\n name: string;\n workspaceId: string;\n description?: string;\n projectId?: string | null;\n ticketId?: string | null;\n};\n\ntype TimeEntryCreateInput = {\n actionId: string;\n startedAt: Date;\n endedAt: Date;\n source?: 'manual' | 'claude-desktop' | 'agent-run';\n status?: 'PROPOSED' | 'CONFIRMED';\n sourceRef?: string;\n note?: string;\n};\n\nexport interface TrpcClient {\n transcription: {\n getAllTranscriptions: {\n query: (input?: {\n includeArchived?: boolean;\n workspaceId?: string;\n meetingType?: 'all' | 'mine' | 'one_on_one' | 'customer' | 'internal';\n }) => Promise<unknown[]>;\n };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n createManualTranscription: {\n mutate: (input: MeetingCreateProcedureInput) => Promise<unknown>;\n };\n updateDetails: {\n mutate: (input: MeetingUpdateDetailsProcedureInput) => Promise<unknown>;\n };\n updateTitle: {\n mutate: (input: { id: string; title: string }) => Promise<unknown>;\n };\n deleteTranscription: {\n mutate: (input: { id: string }) => Promise<unknown>;\n };\n bulkDeleteTranscriptions: {\n mutate: (input: { ids: string[] }) => Promise<unknown>;\n };\n };\n search: {\n global: {\n query: (input: { query: string; workspaceId?: string; limit?: number }) => Promise<unknown>;\n };\n knowledge: {\n query: (input: {\n query: string;\n workspaceId: string;\n limit?: number;\n sourceTypes?: ('transcription' | 'resource' | 'document' | 'page')[];\n }) => Promise<unknown>;\n };\n };\n action: {\n getAll: { query: (input?: ActionInput) => Promise<unknown[]> };\n getKanbanActions: { query: (input?: KanbanInput) => Promise<unknown[]> };\n getToday: { query: (input?: TodayInput) => Promise<unknown[]> };\n getTodaysActions: { query: (input?: TodayInput) => Promise<unknown> };\n getOverdueTriage: { query: (input?: TodayInput) => Promise<unknown> };\n getByDateRange: { query: (input: DateRangeInput) => Promise<unknown[]> };\n getProjectActions: { query: (input: { projectId: string; assigneeId?: string }) => Promise<unknown[]> };\n create: { mutate: (input: ActionCreateInput) => Promise<unknown> };\n update: { mutate: (input: ActionUpdateInput) => Promise<unknown> };\n /** Idempotent create keyed on (workspaceId, sourceType, sourceId). */\n upsertBySource: { mutate: (input: ActionUpsertBySourceInput) => Promise<unknown> };\n bulkReschedule: { mutate: (input: { actionIds: string[]; dueDate: Date | null }) => Promise<unknown> };\n bulkDefer: { mutate: (input: { actionIds: string[] }) => Promise<unknown> };\n };\n project: {\n getAll: { query: (input?: ProjectInput) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n update: { mutate: (input: ProjectUpdateApiInput) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n workspace: {\n list: { query: () => Promise<unknown[]> };\n listMembers: { query: (input: { workspaceId: string }) => Promise<unknown[]> };\n };\n goal: {\n getById: { query: (input: { id: number }) => Promise<unknown> };\n getAllMyGoals: {\n query: (input?: {\n workspaceId?: string;\n period?: string;\n status?: GoalQueryStatusInput;\n }) => Promise<unknown[]>;\n };\n getGoalTree: {\n query: (input?: {\n workspaceId?: string;\n status?: GoalQueryStatusInput;\n }) => Promise<unknown[]>;\n };\n getProjectGoals: { query: (input: { projectId: string }) => Promise<unknown[]> };\n createGoal: { mutate: (input: GoalCreateProcedureInput) => Promise<unknown> };\n /**\n * Partial update — only the keys present are written, and an explicit null\n * clears. Every nullable field is therefore `T | null | undefined`.\n */\n updateGoal: { mutate: (input: GoalUpdateProcedureInput) => Promise<unknown> };\n /** Status-only write; the only path that accepts `on-hold`. */\n updateGoalStatus: {\n mutate: (input: { id: number; status: GoalQueryStatusInput }) => Promise<unknown>;\n };\n /** Single-column re-parent; validates no-self / no-cycle / depth-5. */\n setParent: {\n mutate: (input: { id: number; parentGoalId: number | null }) => Promise<unknown>;\n };\n deleteGoal: { mutate: (input: { id: number }) => Promise<unknown> };\n };\n // Mounted at `okr`, but this is the KEY RESULT router — objectives live on\n // `goal` above. Key results are cuid-keyed; the `goalId` linking them to an\n // objective is an integer.\n okr: {\n getAll: {\n query: (input?: {\n workspaceId?: string;\n goalId?: number;\n period?: string;\n status?: KeyResultStatusInput;\n onlyMine?: boolean;\n }) => Promise<unknown[]>;\n };\n getByObjective: {\n query: (input: {\n workspaceId?: string;\n period?: string;\n includePairedPeriod?: boolean;\n onlyMine?: boolean;\n }) => Promise<unknown[]>;\n };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n getByIds: { query: (input: { ids: string[] }) => Promise<unknown[]> };\n create: { mutate: (input: KeyResultCreateProcedureInput) => Promise<unknown> };\n update: { mutate: (input: KeyResultUpdateProcedureInput) => Promise<unknown> };\n checkIn: {\n mutate: (input: {\n keyResultId: string;\n newValue: number;\n notes?: string;\n }) => Promise<unknown>;\n };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n linkProject: {\n mutate: (input: { keyResultId: string; projectId: string }) => Promise<unknown>;\n };\n unlinkProject: {\n mutate: (input: { keyResultId: string; projectId: string }) => Promise<unknown>;\n };\n linkFeature: {\n mutate: (input: { keyResultId: string; featureId: string }) => Promise<unknown>;\n };\n unlinkFeature: {\n mutate: (input: { keyResultId: string; featureId: string }) => Promise<unknown>;\n };\n getPeriods: { query: () => Promise<unknown[]> };\n getStats: {\n query: (input: { workspaceId?: string; period?: string }) => Promise<unknown>;\n };\n };\n goalComment: {\n getComments: { query: (input: { goalId: number }) => Promise<unknown[]> };\n addComment: { mutate: (input: { goalId: number; content: string; parentUpdateId?: string }) => Promise<unknown> };\n updateComment: { mutate: (input: { commentId: string; content: string }) => Promise<unknown> };\n deleteComment: { mutate: (input: { commentId: string }) => Promise<unknown> };\n };\n pageComment: {\n list: { query: (input: { pageId: string }) => Promise<unknown[]> };\n create: { mutate: (input: { pageId: string; body: string }) => Promise<unknown> };\n update: { mutate: (input: { commentId: string; body: string }) => Promise<unknown> };\n delete: { mutate: (input: { commentId: string }) => Promise<unknown> };\n };\n /** Local-runner side of Agent runs (ADR-0067); agent-key principals only. */\n agentRun: {\n claim: { mutate: (input: { runnerId: string }) => Promise<unknown> };\n heartbeat: { mutate: (input: { runId: string; runnerId?: string }) => Promise<unknown> };\n appendEvents: {\n mutate: (input: {\n runId: string;\n runnerId?: string;\n events: Array<{ seq: number; kind: string; payload: Record<string, unknown> }>;\n }) => Promise<unknown>;\n };\n finish: {\n mutate: (input: {\n runId: string;\n runnerId?: string;\n status: 'SUCCEEDED' | 'FAILED' | 'WAITING_ON_OWNER';\n summary?: string;\n readyToClose?: boolean;\n error?: string;\n usage?: Record<string, unknown>;\n question?: string;\n }) => Promise<unknown>;\n };\n };\n timeEntry: {\n /** Explicit-bounds entry; never touches the running Timer (ADR-0061). */\n create: { mutate: (input: TimeEntryCreateInput) => Promise<unknown> };\n upsertBySourceRef: {\n mutate: (input: TimeEntryCreateInput & { sourceRef: string }) => Promise<unknown>;\n };\n listByDateRange: {\n query: (input: { startDate: Date; endDate: Date; workspaceId?: string | null }) => Promise<unknown[]>;\n };\n /** Human-only; `date` is the start of the day in the caller's timezone. */\n confirmDay: {\n mutate: (input: { date: Date; workspaceId?: string | null }) => Promise<unknown>;\n };\n /** `date` is the start of the day in the caller's timezone; an agent key reads its owner's day. */\n dayReport: {\n query: (input: { date: Date; workspaceId?: string | null }) => Promise<unknown>;\n };\n };\n decision: {\n list: {\n query: (input: {\n workspaceId: string;\n statuses?: DecisionStatusInput[];\n sources?: DecisionSourceInput[];\n /** A product id, or \"workspace\" for decisions with no product. */\n productId?: string;\n includeWorkspaceWide?: boolean;\n projectId?: string;\n search?: string;\n /** One decision by its workspace sequence number — `D-0003` → 3. */\n number?: number;\n limit?: number;\n }) => Promise<unknown[]>;\n };\n get: {\n query: (input: { workspaceId: string; decisionId: string }) => Promise<unknown>;\n };\n /** Workspace comes from the meeting; drafts included for meeting editors. */\n listForMeeting: {\n query: (input: { transcriptionSessionId: string }) => Promise<unknown>;\n };\n listForAdr: {\n query: (input: { workspaceId: string; adrDocumentId: string }) => Promise<unknown[]>;\n };\n /** Extract draft decisions from a meeting's notes and transcript. */\n extractDrafts: {\n mutate: (input: { transcriptionSessionId: string }) => Promise<unknown>;\n };\n create: { mutate: (input: DecisionCreateProcedureInput) => Promise<unknown> };\n update: { mutate: (input: DecisionUpdateProcedureInput) => Promise<unknown> };\n setStatus: {\n mutate: (input: {\n workspaceId: string;\n decisionId: string;\n status: DecisionStatusInput;\n supersededById?: string | null;\n }) => Promise<unknown>;\n };\n linkTicket: {\n mutate: (input: { workspaceId: string; decisionId: string; ticketId: string }) => Promise<unknown>;\n };\n linkFeature: {\n mutate: (input: { workspaceId: string; decisionId: string; featureId: string }) => Promise<unknown>;\n };\n /** `linkId` is the DecisionLink id, not the ticket or feature id. */\n unlink: {\n mutate: (input: { workspaceId: string; linkId: string }) => Promise<unknown>;\n };\n confirmDraft: {\n mutate: (input: { workspaceId: string; decisionId: string }) => Promise<unknown>;\n };\n rejectDraft: {\n mutate: (input: { workspaceId: string; decisionId: string }) => Promise<unknown>;\n };\n deleteDraft: {\n mutate: (input: { workspaceId: string; decisionId: string }) => Promise<unknown>;\n };\n };\n crmApi: {\n contactList: { query: (input: { workspaceId: string; search?: string; tags?: string[]; organizationId?: string; limit?: number; cursor?: string }) => Promise<unknown> };\n contactGet: { query: (input: { id: string; includeInteractions?: boolean }) => Promise<unknown> };\n contactCreate: { mutate: (input: { workspaceId: string; firstName?: string; lastName?: string; email?: string | null; phone?: string; linkedIn?: string; telegram?: string; twitter?: string; github?: string; bluesky?: string; about?: string; profileType?: string; skills?: string[]; tags?: string[]; organizationId?: string; organizationName?: string }) => Promise<unknown> };\n contactUpdate: { mutate: (input: { id: string; firstName?: string; lastName?: string; email?: string | null; phone?: string | null; linkedIn?: string | null; telegram?: string | null; twitter?: string | null; github?: string | null; bluesky?: string | null; about?: string; profileType?: string; skills?: string[]; tags?: string[]; organizationId?: string | null; organizationName?: string }) => Promise<unknown> };\n contactDelete: { mutate: (input: { id: string }) => Promise<unknown> };\n contactAddInteraction: { mutate: (input: { contactId: string; type: string; direction: string; subject?: string; notes?: string; metadata?: unknown }) => Promise<unknown> };\n contactEnrich: { mutate: (input: { contactId: string }) => Promise<unknown> };\n organizationList: { query: (input: { workspaceId: string; search?: string; industry?: string; limit?: number; cursor?: string }) => Promise<unknown> };\n organizationGet: { query: (input: { id: string }) => Promise<unknown> };\n organizationCreate: { mutate: (input: { workspaceId: string; name: string; websiteUrl?: string | null; logoUrl?: string | null; description?: string; industry?: string; size?: string }) => Promise<unknown> };\n pipelineGet: { query: (input: { workspaceId: string }) => Promise<unknown> };\n pipelineGetStages: { query: (input: { workspaceId: string }) => Promise<unknown[]> };\n dealList: { query: (input: { workspaceId: string }) => Promise<unknown[]> };\n dealGet: { query: (input: { id: string }) => Promise<unknown> };\n dealCreate: { mutate: (input: { workspaceId: string; stageId: string; title: string; description?: string; value?: number; currency?: string; probability?: number; expectedCloseDate?: Date; contactId?: string; organizationId?: string; assignedToId?: string }) => Promise<unknown> };\n dealUpdate: { mutate: (input: { id: string; title?: string; description?: string | null; value?: number | null; currency?: string; probability?: number | null; expectedCloseDate?: Date | null; contactId?: string | null; organizationId?: string | null; assignedToId?: string | null }) => Promise<unknown> };\n dealMove: { mutate: (input: { id: string; stageId: string; stageOrder: number }) => Promise<unknown> };\n dealDelete: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n actionComment: {\n getComments: { query: (input: { actionId: string }) => Promise<unknown[]> };\n addComment: { mutate: (input: { actionId: string; content: string }) => Promise<unknown> };\n updateComment: { mutate: (input: { commentId: string; content: string }) => Promise<unknown> };\n deleteComment: { mutate: (input: { commentId: string }) => Promise<unknown> };\n };\n page: {\n list: { query: (input: { workspaceId: string; projectId?: string; search?: string }) => Promise<unknown[]> };\n get: { query: (input: { id: string; format?: 'full' | 'markdown' | 'outline'; section?: string }) => Promise<unknown> };\n search: { query: (input: { workspaceId: string; query: string; projectId?: string; limit?: number }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; projectId?: string | null; title?: string; body?: string; includeInSearch?: boolean; note?: string; source?: string | null; asOf?: Date | null }) => Promise<unknown> };\n update: { mutate: (input: { id: string; title?: string; projectId?: string | null; includeInSearch?: boolean; body?: string; baseVersion?: number; note?: string; source?: string | null; asOf?: Date | null }) => Promise<unknown> };\n history: { query: (input: { id: string; limit?: number; cursor?: string }) => Promise<unknown> };\n revision: { query: (input: { id: string; revisionId: string }) => Promise<unknown> };\n diff: { query: (input: { id: string; revisionId: string; against?: string }) => Promise<unknown> };\n restore: { mutate: (input: { id: string; revisionId: string; note?: string; baseVersion?: number }) => Promise<unknown> };\n };\n resource: {\n list: { query: (input: { workspaceId?: string; projectId?: string; contentType?: string; readStatus?: string; search?: string; tags?: string[]; includeArchived?: boolean; limit?: number; cursor?: string }) => Promise<unknown> };\n create: { mutate: (input: { title: string; url?: string; description?: string; content?: string; contentType?: string; tags?: string[]; workspaceId?: string; projectId?: string; readStatus?: string; generateEmbeddings?: boolean }) => Promise<unknown> };\n setReadStatus: { mutate: (input: { id: string; readStatus: string }) => Promise<unknown> };\n archive: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n epic: {\n list: { query: (input: { workspaceId: string; status?: 'OPEN' | 'IN_PROGRESS' | 'DONE' | 'CANCELLED' }) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; name: string; description?: string; priority?: 'HIGH' | 'MEDIUM' | 'LOW' | 'NONE'; startDate?: Date; targetDate?: Date }) => Promise<unknown> };\n update: { mutate: (input: { id: string; name?: string; description?: string | null; status?: 'OPEN' | 'IN_PROGRESS' | 'DONE' | 'CANCELLED'; priority?: 'HIGH' | 'MEDIUM' | 'LOW' | 'NONE'; startDate?: Date | null; targetDate?: Date | null }) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n tag: {\n list: { query: (input?: { workspaceId?: string; category?: string | null }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; name: string; color: string; description?: string; category?: string | null }) => Promise<unknown> };\n setEntityTags: { mutate: (input: { entityType: 'action' | 'ticket' | 'feature' | 'epic'; entityId: string; tagIds: string[] }) => Promise<unknown> };\n listForEntity: { query: (input: { entityType: 'action' | 'ticket' | 'feature' | 'epic'; entityId: string }) => Promise<unknown[]> };\n };\n product: {\n product: {\n list: { query: (input: { workspaceId: string }) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n getBySlug: { query: (input: { workspaceId: string; slug: string }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; name: string; slug: string; description?: string; icon?: string; color?: string }) => Promise<unknown> };\n update: { mutate: (input: { id: string; name?: string; description?: string; icon?: string; color?: string; funTicketIds?: boolean }) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n featureComment: {\n list: { query: (input: { featureId: string }) => Promise<unknown[]> };\n create: { mutate: (input: { featureId: string; scopeId?: string; threadId?: string; body: string; quotedText?: string }) => Promise<unknown> };\n reply: { mutate: (input: { parentId: string; body: string }) => Promise<unknown> };\n update: { mutate: (input: { commentId: string; body: string }) => Promise<unknown> };\n delete: { mutate: (input: { commentId: string }) => Promise<unknown> };\n resolve: { mutate: (input: { featureId: string; threadId: string }) => Promise<unknown> };\n unresolve: { mutate: (input: { featureId: string; threadId: string }) => Promise<unknown> };\n };\n feature: {\n list: { query: (input: { productId: string; status?: 'IDEA' | 'DEFINED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED' | 'ARCHIVED' }) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n create: { mutate: (input: { productId: string; name: string; description?: string; vision?: string; status?: 'IDEA' | 'DEFINED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED' | 'ARCHIVED'; effort?: number; priority?: number; goalId?: number; areaId?: string }) => Promise<unknown> };\n update: { mutate: (input: { id: string; name?: string; description?: string; vision?: string; status?: 'IDEA' | 'DEFINED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED' | 'ARCHIVED'; effort?: number; priority?: number; goalId?: number | null; areaId?: string | null }) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n addUserStory: { mutate: (input: { featureId: string; scopeId?: string; asA?: string; iWant?: string; soThat?: string; acceptanceCriteria?: string }) => Promise<unknown> };\n updateUserStory: { mutate: (input: { id: string; scopeId?: string | null; asA?: string; iWant?: string; soThat?: string; acceptanceCriteria?: string }) => Promise<unknown> };\n deleteUserStory: { mutate: (input: { id: string }) => Promise<unknown> };\n addScope: { mutate: (input: { featureId: string; version: string; description: string; status?: 'PLANNED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED'; shippedAt?: Date }) => Promise<unknown> };\n updateScope: { mutate: (input: { id: string; version?: string; description?: string; status?: 'PLANNED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED'; shippedAt?: Date | null; displayOrder?: number }) => Promise<unknown> };\n deleteScope: { mutate: (input: { id: string }) => Promise<unknown> };\n addRequirement: { mutate: (input: { featureId: string; scopeId?: string; statement: string; kind?: 'FUNCTIONAL' | 'NON_FUNCTIONAL' | 'CONSTRAINT' }) => Promise<unknown> };\n setRequirementChecked: { mutate: (input: { id: string; checked: boolean }) => Promise<unknown> };\n deleteRequirement: { mutate: (input: { id: string }) => Promise<unknown> };\n linkPage: { mutate: (input: { featureId: string; pageId: string; scopeId?: string }) => Promise<unknown> };\n unlinkPage: { mutate: (input: { featureId: string; pageId: string }) => Promise<unknown> };\n listAreas: { query: (input: { productId: string }) => Promise<unknown[]> };\n createArea: { mutate: (input: { productId: string; name: string; description?: string }) => Promise<unknown> };\n };\n ticket: {\n list: { query: (input: { productId?: string; status?: string; type?: string; featureId?: string; epicId?: string; cycleId?: string; assigneeId?: string; prUrl?: string; branchName?: string }) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n create: { mutate: (input: { productId: string; title: string; body?: string; type?: string; status?: string; priority?: number; points?: number; branchName?: string; prUrl?: string; designUrl?: string; specUrl?: string; links?: Record<string, string>; epicId?: string; featureId?: string; cycleId?: string; scopeId?: string; assigneeId?: string; templateId?: string }) => Promise<unknown> };\n update: { mutate: (input: { id: string; title?: string; body?: string; type?: string; status?: string; priority?: number | null; points?: number | null; branchName?: string | null; prUrl?: string | null; designUrl?: string | null; specUrl?: string | null; links?: Record<string, string> | null; epicId?: string | null; featureId?: string | null; cycleId?: string | null; scopeId?: string | null; assigneeId?: string | null }) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n search: { query: (input: { productId: string; query?: string; excludeTicketId?: string; limit?: number }) => Promise<unknown[]> };\n addDependency: { mutate: (input: { ticketId: string; dependsOnId: string }) => Promise<unknown> };\n removeDependency: { mutate: (input: { ticketId: string; dependsOnId: string }) => Promise<unknown> };\n addComment: { mutate: (input: { ticketId: string; content: string }) => Promise<unknown> };\n updateComment: { mutate: (input: { id: string; content: string }) => Promise<unknown> };\n deleteComment: { mutate: (input: { id: string }) => Promise<unknown> };\n linkAction: { mutate: (input: { ticketId: string; actionId: string }) => Promise<unknown> };\n unlinkAction: { mutate: (input: { actionId: string }) => Promise<unknown> };\n };\n };\n}\n\nexport function createClient(config: { token: string; apiUrl: string }): TrpcClient {\n const apiUrl = config.apiUrl.replace(/\\/+$/, '');\n\n return createTRPCClient<any>({\n links: [\n httpBatchLink({\n url: `${apiUrl}/api/trpc`,\n headers() {\n return {\n Authorization: `Bearer ${config.token}`,\n };\n },\n transformer: superjson,\n }),\n ],\n }) as unknown as TrpcClient;\n}\n\nexport function isTRPCError(error: unknown): error is TRPCClientError<any> {\n return error instanceof TRPCClientError;\n}\n\nexport { TRPCClientError };\n","import type { TrpcClient } from './client.js';\nimport type { Action, KanbanStatus, Priority } from './types/action.js';\n\nexport interface ActionsListOptions {\n projectId?: string;\n status?: KanbanStatus;\n assigneeId?: string;\n}\n\nexport interface ActionsKanbanOptions {\n projectId?: string;\n status?: KanbanStatus;\n assigneeId?: string;\n}\n\nexport type ActionStatus = 'ACTIVE' | 'COMPLETED' | 'CANCELLED' | 'DELETED' | 'DRAFT';\n\nexport interface ActionCreateInput {\n name: string;\n description?: string;\n projectId?: string;\n workspaceId?: string;\n dueDate?: Date;\n scheduledStart?: Date;\n scheduledEnd?: Date;\n duration?: number;\n priority?: Priority;\n status?: ActionStatus;\n epicId?: string;\n effortEstimate?: number;\n blockedByIds?: string[];\n}\n\nexport interface ActionUpdateInput {\n id: string;\n name?: string;\n description?: string;\n projectId?: string;\n workspaceId?: string | null;\n dueDate?: Date | null;\n scheduledStart?: Date | null;\n scheduledEnd?: Date | null;\n duration?: number | null;\n priority?: Priority;\n status?: ActionStatus;\n kanbanStatus?: KanbanStatus;\n epicId?: string | null;\n effortEstimate?: number | null;\n blockedByIds?: string[];\n}\n\nexport interface ActionUpsertBySourceInput {\n /** Convention for the Daily worklog: `claude-session`. */\n sourceType: string;\n /** The conversation id — re-running with the same pair updates, never duplicates. */\n sourceId: string;\n name: string;\n workspaceId: string;\n description?: string;\n /** Must live in `workspaceId`, or the call is NOT_FOUND. */\n projectId?: string | null;\n /** Must belong to a product in `workspaceId`, or the call is NOT_FOUND. */\n ticketId?: string | null;\n}\n\nexport interface ActionUpsertBySourceResult {\n action: Action & {\n ticket?: { id: string; number: number; shortId: string | null; productId: string } | null;\n };\n outcome: 'created' | 'updated';\n}\n\n/** One action as returned inside a {@link TodaysActions} group. */\nexport interface TodaysActionRow {\n id: string;\n name: string;\n status: string;\n scheduledStart: Date | null;\n dueDate: Date | null;\n projectName: string | null;\n workspaceName: string | null;\n}\n\nexport interface TodaysActionsGroup {\n /** Total in this group — may exceed `actions.length`, which is capped at 50. */\n count: number;\n actions: TodaysActionRow[];\n}\n\nexport interface TodaysActions {\n overdue: TodaysActionsGroup;\n today: TodaysActionsGroup;\n inbox: TodaysActionsGroup;\n}\n\nexport interface OverdueTriageRow extends Omit<TodaysActionRow, 'status' | 'workspaceName'> {\n priority: string | null;\n daysOverdue: number;\n}\n\nexport interface OverdueCohort {\n /** The exact instant every member is stamped with. */\n stampedAt: Date;\n daysOverdue: number;\n count: number;\n projectNames: string[];\n actionIds: string[];\n actions: OverdueTriageRow[];\n}\n\nexport interface OverdueTriage {\n totalOverdue: number;\n /** How many of `totalOverdue` sit inside a cohort. */\n cohortCount: number;\n cohorts: OverdueCohort[];\n /** Individually-dated overdue actions — real debt, worth reading one by one. */\n loose: OverdueTriageRow[];\n}\n\nexport class ActionsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ActionsListOptions = {}): Promise<Action[]> {\n const { projectId, status, assigneeId } = options;\n let actions: Action[];\n\n if (projectId) {\n actions = await this.client.action.getProjectActions.query({\n projectId,\n assigneeId,\n }) as Action[];\n } else if (status) {\n actions = await this.client.action.getKanbanActions.query({\n kanbanStatus: status,\n assigneeId,\n }) as Action[];\n } else {\n actions = await this.client.action.getAll.query({\n assigneeId,\n }) as Action[];\n }\n\n // Match CLI behavior: hide completed/cancelled unless status specified\n if (!status) {\n actions = actions.filter(action =>\n action.status !== 'COMPLETED' &&\n action.status !== 'CANCELLED' &&\n action.kanbanStatus !== 'DONE' &&\n action.kanbanStatus !== 'CANCELLED'\n );\n }\n\n return actions;\n }\n\n /**\n * Actions whose `dueDate` falls today.\n *\n * Note this is a **narrow** slice: it excludes overdue actions, and excludes\n * anything scheduled for today that carries no due date. If you want \"what\n * is on my plate\", use {@link getTodaysActions} instead — this method will\n * happily report a quiet day on top of a large overdue pile.\n */\n async getToday(workspaceId?: string): Promise<Action[]> {\n return await this.client.action.getToday.query({\n workspaceId,\n }) as Action[];\n }\n\n /**\n * What is actually on the user's plate: the `/today` page's own partition,\n * pre-split into `overdue` / `today` / `inbox`.\n *\n * Prefer this over {@link getToday} for anything that reasons about the\n * user's day. `getToday` is a due-date-only slice that omits the overdue\n * pile entirely — on a real account that can mean returning 6 actions while\n * 40 sit overdue. This method uses the server-shared partition, so it agrees\n * with what the user is looking at by construction.\n *\n * Cross-workspace by default. Each group is capped at 50 rows; `count` is the\n * true total.\n */\n async getTodaysActions(workspaceId?: string): Promise<TodaysActions> {\n return await this.client.action.getTodaysActions.query({\n workspaceId,\n }) as TodaysActions;\n }\n\n /**\n * Why the overdue pile is the size it is.\n *\n * Splits overdue actions into **cohorts** — groups sharing one exact\n * timestamp, the fingerprint of a bulk write like a generated project plan —\n * and **loose** individually-dated debt. Cohort members were almost certainly\n * never individually due, so the honest disposition is {@link bulkDefer},\n * not another {@link bulkReschedule} that re-inflicts the pile tomorrow.\n */\n async getOverdueTriage(workspaceId?: string): Promise<OverdueTriage> {\n return await this.client.action.getOverdueTriage.query({\n workspaceId,\n }) as OverdueTriage;\n }\n\n /**\n * Move actions to a new do-date (`scheduledStart`), pushing `dueDate` forward\n * only where it would otherwise fall before it. Pass `null` to clear both —\n * though {@link bulkDefer} says that more clearly.\n */\n async bulkReschedule(actionIds: string[], dueDate: Date | null): Promise<{ count: number; actionIds: string[] }> {\n return await this.client.action.bulkReschedule.mutate({\n actionIds,\n dueDate,\n }) as { count: number; actionIds: string[] };\n }\n\n /**\n * Amnesty: clear the dates so actions fall back to their project backlog\n * untimed. For work that was never really due on the date it carries —\n * typically an overdue cohort. Kanban status is untouched.\n */\n async bulkDefer(actionIds: string[]): Promise<{ count: number; actionIds: string[]; message: string }> {\n return await this.client.action.bulkDefer.mutate({\n actionIds,\n }) as { count: number; actionIds: string[]; message: string };\n }\n\n async getByDateRange(start: Date, end: Date, workspaceId?: string): Promise<Action[]> {\n return await this.client.action.getByDateRange.query({\n startDate: start,\n endDate: end,\n workspaceId,\n }) as Action[];\n }\n\n async getKanban(options: ActionsKanbanOptions = {}): Promise<Action[]> {\n const { projectId, status, assigneeId } = options;\n\n return await this.client.action.getKanbanActions.query({\n projectId,\n kanbanStatus: status,\n assigneeId,\n }) as Action[];\n }\n\n async getProjectActions(projectId: string, assigneeId?: string): Promise<Action[]> {\n return await this.client.action.getProjectActions.query({\n projectId,\n assigneeId,\n }) as Action[];\n }\n\n async create(input: ActionCreateInput): Promise<Action> {\n return await this.client.action.create.mutate(input) as Action;\n }\n\n async update(input: ActionUpdateInput): Promise<Action> {\n return await this.client.action.update.mutate(input) as Action;\n }\n\n /**\n * One Action per external source: find by (workspaceId, sourceType,\n * sourceId), refresh its name and links, else create it. `outcome` says\n * which happened. Agents may call this; the created Action records the\n * agent's shadow user as creator with `source: \"agent\"` (ADR-0049).\n */\n async upsertBySource(input: ActionUpsertBySourceInput): Promise<ActionUpsertBySourceResult> {\n return await this.client.action.upsertBySource.mutate(input) as ActionUpsertBySourceResult;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { ActionComment } from './types/comment.js';\n\nexport interface ActionCommentAddInput {\n actionId: string;\n content: string;\n}\n\nexport interface ActionCommentUpdateInput {\n commentId: string;\n content: string;\n}\n\nexport class ActionCommentsApi {\n constructor(private client: TrpcClient) {}\n\n async list(actionId: string): Promise<ActionComment[]> {\n return await this.client.actionComment.getComments.query({\n actionId,\n }) as ActionComment[];\n }\n\n async add(input: ActionCommentAddInput): Promise<ActionComment> {\n return await this.client.actionComment.addComment.mutate(input) as ActionComment;\n }\n\n async update(input: ActionCommentUpdateInput): Promise<ActionComment> {\n return await this.client.actionComment.updateComment.mutate(input) as ActionComment;\n }\n\n async delete(commentId: string): Promise<ActionComment> {\n return await this.client.actionComment.deleteComment.mutate({\n commentId,\n }) as ActionComment;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { FeatureComment } from './types/comment.js';\n\nexport interface FeatureCommentCreateInput {\n featureId: string;\n /** Attach to a scope's activity feed instead of the feature's own feed. */\n scopeId?: string;\n /** Anchor to a span of the PRD body. Omit for a doc-level comment. */\n threadId?: string;\n /** Markdown. Mention members with `@[Name](userId)` — see `workspaces.listMembers()`. */\n body: string;\n quotedText?: string;\n}\n\nexport interface FeatureCommentReplyInput {\n parentId: string;\n body: string;\n}\n\nexport interface FeatureCommentUpdateInput {\n commentId: string;\n body: string;\n}\n\nexport interface FeatureCommentThreadInput {\n featureId: string;\n threadId: string;\n}\n\n/**\n * Discussion on a Feature (PRD). Any workspace member can read and comment;\n * editing and deleting are author-only.\n *\n * Mentions are `@[Display Name](userId)` in the body — that markup is what\n * triggers a notification. `workspaces.listMembers()` returns a ready-made\n * `mentionSyntax` per member so callers never have to build it by hand.\n */\nexport class FeatureCommentsApi {\n constructor(private client: TrpcClient) {}\n\n async list(featureId: string): Promise<FeatureComment[]> {\n return await this.client.product.featureComment.list.query({\n featureId,\n }) as FeatureComment[];\n }\n\n async create(input: FeatureCommentCreateInput): Promise<FeatureComment> {\n return await this.client.product.featureComment.create.mutate(\n input,\n ) as FeatureComment;\n }\n\n /** Reply to an existing comment. Replies to replies still hang off the root. */\n async reply(input: FeatureCommentReplyInput): Promise<FeatureComment> {\n return await this.client.product.featureComment.reply.mutate(\n input,\n ) as FeatureComment;\n }\n\n async update(input: FeatureCommentUpdateInput): Promise<FeatureComment> {\n return await this.client.product.featureComment.update.mutate(\n input,\n ) as FeatureComment;\n }\n\n async delete(commentId: string): Promise<{ success: boolean }> {\n return await this.client.product.featureComment.delete.mutate({\n commentId,\n }) as { success: boolean };\n }\n\n /** Mark an anchored thread resolved. Only anchored threads have a threadId. */\n async resolve(input: FeatureCommentThreadInput): Promise<{ success: boolean }> {\n return await this.client.product.featureComment.resolve.mutate(\n input,\n ) as { success: boolean };\n }\n\n async unresolve(input: FeatureCommentThreadInput): Promise<{ success: boolean }> {\n return await this.client.product.featureComment.unresolve.mutate(\n input,\n ) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { PageComment } from './types/comment.js';\n\nexport interface PageCommentCreateInput {\n pageId: string;\n /** Markdown. Mention members with `@[Name](userId)` — see `workspaces.listMembers()`. */\n body: string;\n}\n\nexport interface PageCommentUpdateInput {\n commentId: string;\n body: string;\n}\n\n/**\n * Discussion on a Knowledge Page — a flat, doc-level feed under the page body.\n * View access is the commenting gate: anyone the page is shared with can join\n * the thread. Editing and deleting are author-only.\n */\nexport class PageCommentsApi {\n constructor(private client: TrpcClient) {}\n\n async list(pageId: string): Promise<PageComment[]> {\n return await this.client.pageComment.list.query({ pageId }) as PageComment[];\n }\n\n async create(input: PageCommentCreateInput): Promise<PageComment> {\n return await this.client.pageComment.create.mutate(input) as PageComment;\n }\n\n async update(input: PageCommentUpdateInput): Promise<PageComment> {\n return await this.client.pageComment.update.mutate(input) as PageComment;\n }\n\n async delete(commentId: string): Promise<{ success: boolean }> {\n return await this.client.pageComment.delete.mutate({\n commentId,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { GoalComment } from './types/comment.js';\n\nexport interface GoalCommentAddInput {\n goalId: number;\n /** Markdown. Mention members with `@[Name](userId)` — see `workspaces.listMembers()`. */\n content: string;\n /** Thread this comment under a specific goal update rather than the goal itself. */\n parentUpdateId?: string;\n}\n\nexport interface GoalCommentUpdateInput {\n commentId: string;\n content: string;\n}\n\n/**\n * Discussion on a Goal/Objective. Note `goalId` is numeric — goals use integer\n * ids, unlike the cuid-keyed product entities.\n */\nexport class GoalCommentsApi {\n constructor(private client: TrpcClient) {}\n\n async list(goalId: number): Promise<GoalComment[]> {\n return await this.client.goalComment.getComments.query({\n goalId,\n }) as GoalComment[];\n }\n\n async add(input: GoalCommentAddInput): Promise<GoalComment> {\n return await this.client.goalComment.addComment.mutate(input) as GoalComment;\n }\n\n async update(input: GoalCommentUpdateInput): Promise<GoalComment> {\n return await this.client.goalComment.updateComment.mutate(\n input,\n ) as GoalComment;\n }\n\n async delete(commentId: string): Promise<{ success: boolean }> {\n return await this.client.goalComment.deleteComment.mutate({\n commentId,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { KeyResultsApi } from './keyResults.js';\nimport type {\n Goal,\n GoalPeriod,\n GoalStats,\n GoalStatus,\n GoalTreeNode,\n GoalWritableStatus,\n} from './types/goal.js';\n\nexport interface GoalListOptions {\n /**\n * Scope to a workspace. With it the list is workspace-**wide** — every\n * member's objectives, not just yours. Without it you get your own.\n */\n workspaceId?: string;\n /** Free-form period string, e.g. `\"Q3-2026\"` or `\"Annual-2026\"`. */\n period?: string;\n status?: GoalStatus;\n}\n\nexport interface GoalTreeOptions {\n workspaceId?: string;\n status?: GoalStatus;\n}\n\nexport interface GoalCreateInput {\n title: string;\n description?: string;\n whyThisGoal?: string;\n notes?: string;\n dueDate?: Date;\n period?: string;\n status?: GoalWritableStatus;\n lifeDomainId?: number;\n /** Link the objective to one project on creation. */\n projectId?: string;\n outcomeIds?: string[];\n driUserId?: string;\n workspaceId?: string;\n /** Nest under a parent objective. Max nesting depth is 5. */\n parentGoalId?: number;\n icon?: string | null;\n iconColor?: string | null;\n}\n\n/**\n * A **partial** update: omit a field and it is left untouched, pass an explicit\n * `null` to clear it. Nothing you don't name is written.\n *\n * Prefer {@link GoalsApi.setStatus} for a status change and\n * {@link GoalsApi.setParent} for a re-parent — both write exactly one column.\n */\nexport interface GoalUpdateInput {\n id: number;\n title?: string;\n description?: string | null;\n whyThisGoal?: string | null;\n notes?: string | null;\n dueDate?: Date | null;\n period?: string | null;\n status?: GoalWritableStatus;\n lifeDomainId?: number | null;\n /** Replace the project links with this one project; `null` clears them. */\n projectId?: string | null;\n /** Replace the project links wholesale; `[]` clears them. */\n projectIds?: string[];\n outcomeIds?: string[];\n driUserId?: string | null;\n workspaceId?: string | null;\n parentGoalId?: number | null;\n displayOrder?: number;\n icon?: string | null;\n iconColor?: string | null;\n}\n\nexport interface GoalSetStatusInput {\n id: number;\n /** `on-hold` is accepted here and only here. */\n status: GoalStatus;\n}\n\nexport interface GoalSetParentInput {\n id: number;\n /** `null` detaches the objective from its parent. */\n parentGoalId: number | null;\n}\n\nexport interface GoalStatsOptions {\n workspaceId?: string;\n period?: string;\n}\n\n/**\n * Objectives (`Goal`) — the qualitative half of an OKR, keyed by **integer** id.\n * Their measurable key results hang off {@link KeyResultsApi}, reachable here as\n * `goals.keyResults`.\n *\n * On writes: `update()` is a partial update, but `setStatus()` and `setParent()`\n * each write a single column and are the right call whenever that is all you\n * mean to change — closing a quarter or re-parenting a cascade should never risk\n * a collateral write.\n */\nexport class GoalsApi {\n constructor(\n private client: TrpcClient,\n /** Key results for these objectives. Same instance as `client.keyResults`. */\n public keyResults: KeyResultsApi,\n ) {}\n\n /**\n * List objectives. Pass `workspaceId` for the workspace-wide list (every\n * member's), omit it for your own. Includes each objective's linked\n * `projects`, which is the join that maps day-to-day work back to an OKR:\n * every action carries a `projectId`.\n *\n * `period` and `status` are sent to the server *and* re-applied here. The\n * server grew those filters recently; against an instance that predates them\n * zod strips the unknown keys and hands back **every** objective — a filter\n * that silently matches everything is worse than one that errors. Re-applying\n * is a no-op once the server has done the work. Same reasoning as the\n * client-side `branchName`/`prUrl` filters in `tickets.ts`.\n */\n async list(options: GoalListOptions = {}): Promise<Goal[]> {\n const goals = await this.client.goal.getAllMyGoals.query(options) as Goal[];\n return goals.filter(\n (g) =>\n (options.period === undefined || g.period === options.period) &&\n (options.status === undefined || g.status === options.status),\n );\n }\n\n /**\n * The same objectives nested parent → child (up to 5 levels), each with its\n * projects and key results. One call for the whole annual → quarterly cascade.\n */\n async tree(options: GoalTreeOptions = {}): Promise<GoalTreeNode[]> {\n return await this.client.goal.getGoalTree.query(\n options,\n ) as GoalTreeNode[];\n }\n\n async get(id: number): Promise<Goal> {\n return await this.client.goal.getById.query({ id }) as Goal;\n }\n\n /** Objectives linked to a given project. */\n async listByProject(projectId: string): Promise<Goal[]> {\n return await this.client.goal.getProjectGoals.query({ projectId }) as Goal[];\n }\n\n async create(input: GoalCreateInput): Promise<Goal> {\n return await this.client.goal.createGoal.mutate(input) as Goal;\n }\n\n /**\n * Partial update — see {@link GoalUpdateInput}. Fields you omit are left\n * alone; pass an explicit `null` to clear one.\n */\n async update(input: GoalUpdateInput): Promise<Goal> {\n return await this.client.goal.updateGoal.mutate(input) as Goal;\n }\n\n /**\n * Status-only write. Never touches another field, and is the only path that\n * accepts `on-hold`. Moving an objective to `completed` also records a\n * workspace milestone.\n */\n async setStatus(input: GoalSetStatusInput): Promise<Goal> {\n return await this.client.goal.updateGoalStatus.mutate(input) as Goal;\n }\n\n /**\n * Re-parent an objective, or detach it with `parentGoalId: null`. Writes only\n * `parentGoalId`, and validates the no-self / no-cycle / depth-5 rules.\n */\n async setParent(input: GoalSetParentInput): Promise<Goal> {\n return await this.client.goal.setParent.mutate(input) as Goal;\n }\n\n async delete(id: number): Promise<Goal> {\n return await this.client.goal.deleteGoal.mutate({ id }) as Goal;\n }\n\n /** The conventional period strings (quarters, halves, annual) for this year and next. */\n async periods(): Promise<GoalPeriod[]> {\n return await this.client.okr.getPeriods.query() as GoalPeriod[];\n }\n\n /** Aggregate objective/key-result counts and average progress. */\n async stats(options: GoalStatsOptions = {}): Promise<GoalStats> {\n return await this.client.okr.getStats.query(options) as GoalStats;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n KeyResult,\n KeyResultCheckIn,\n KeyResultStatus,\n KeyResultUnit,\n ObjectiveWithKeyResults,\n} from './types/keyResult.js';\n\nexport interface KeyResultListOptions {\n /**\n * Scope to a workspace. With it the list is workspace-**wide** — every\n * member's key results, not just yours. Without it you get your own.\n */\n workspaceId?: string;\n /** Objective id — an integer, unlike the key result's own cuid. */\n goalId?: number;\n period?: string;\n status?: KeyResultStatus;\n /** Narrow a workspace-scoped list back to the key results you own. */\n onlyMine?: boolean;\n}\n\nexport interface KeyResultByObjectiveOptions {\n workspaceId?: string;\n period?: string;\n /** Also include the period's parent annual period (Q3-2026 → Annual-2026). */\n includePairedPeriod?: boolean;\n onlyMine?: boolean;\n}\n\nexport interface KeyResultCreateInput {\n /** Objective (integer id) the key result hangs off. */\n goalId: number;\n title: string;\n targetValue: number;\n /** Free-form, e.g. `\"Q3-2026\"`. */\n period: string;\n description?: string;\n startValue?: number;\n currentValue?: number;\n unit?: KeyResultUnit;\n unitLabel?: string;\n driUserId?: string;\n /**\n * Omit to inherit the objective's workspace — {@link KeyResultsApi.create}\n * resolves it before writing. Pass one explicitly only to override.\n */\n workspaceId?: string;\n}\n\nexport interface KeyResultUpdateInput {\n /** cuid. */\n id: string;\n title?: string;\n description?: string;\n targetValue?: number;\n currentValue?: number;\n startValue?: number;\n unit?: KeyResultUnit;\n unitLabel?: string;\n status?: KeyResultStatus;\n /** 0–100. */\n confidence?: number;\n driUserId?: string;\n /** Move the key result to a different objective. */\n goalId?: number;\n}\n\nexport interface KeyResultCheckInInput {\n /** cuid. */\n id: string;\n /** The new current value. */\n value: number;\n note?: string;\n}\n\n/**\n * Key results — the measurable half of an OKR.\n *\n * Reachable both as `client.keyResults` and as `client.goals.keyResults`; they\n * are the same instance. Every id here is a **cuid string**, while the `goalId`\n * that ties a key result to its objective is an **integer**. The tRPC router\n * behind these calls is mounted at `okr`, which is the key-result router — not\n * an objective router. Objectives live on {@link GoalsApi}.\n */\nexport class KeyResultsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * List key results. Pass `workspaceId` for the workspace-wide list (every\n * member's), omit it for your own.\n *\n * ⚠️ Workspace scoping here depends on a server-side fix to `okr.getAll`,\n * which previously accepted a `workspaceId` while still filtering on the\n * caller's `userId` — so against an older instance this returns only your own\n * key results, or `[]`, rather than the workspace's. Unlike the filters in\n * `goals.list()` that cannot be repaired here: the other members' rows never\n * reach the client. {@link KeyResultsApi.byObjective} is workspace-correct on\n * every server version and is the safer read when that matters.\n */\n async list(options: KeyResultListOptions = {}): Promise<KeyResult[]> {\n return await this.client.okr.getAll.query(options) as KeyResult[];\n }\n\n /**\n * Objectives with their key results nested — the richest OKR read, and the\n * one to reach for when rendering \"here is the quarter\".\n */\n async byObjective(\n options: KeyResultByObjectiveOptions = {},\n ): Promise<ObjectiveWithKeyResults[]> {\n return await this.client.okr.getByObjective.query(\n options,\n ) as ObjectiveWithKeyResults[];\n }\n\n async get(id: string): Promise<KeyResult> {\n return await this.client.okr.getById.query({ id }) as KeyResult;\n }\n\n /**\n * Create a key result on an objective.\n *\n * When `workspaceId` is omitted it is resolved from the objective first,\n * rather than left to the server. `okr.create` writes the input through as-is\n * on older instances, so an absent workspace persists as `null` — and a key\n * result with no workspace is invisible to every workspace-scoped read and\n * unwritable by teammates once owner-OR-member authz applies. That is the\n * same orphaning that has already cost a goal; one extra read on a mutation\n * is a cheap way not to repeat it.\n */\n async create(input: KeyResultCreateInput): Promise<KeyResult> {\n let workspaceId = input.workspaceId;\n if (workspaceId === undefined) {\n const goal = await this.client.goal.getById.query({\n id: input.goalId,\n }) as { workspaceId: string | null };\n workspaceId = goal.workspaceId ?? undefined;\n }\n return await this.client.okr.create.mutate({\n ...input,\n workspaceId,\n }) as KeyResult;\n }\n\n async update(input: KeyResultUpdateInput): Promise<KeyResult> {\n return await this.client.okr.update.mutate(input) as KeyResult;\n }\n\n /**\n * Record a progress check-in. The server derives the new status from where\n * `value` lands between `startValue` and `targetValue`, so a check-in both\n * moves the number and re-colours the key result.\n */\n async checkIn(input: KeyResultCheckInInput): Promise<KeyResultCheckIn> {\n return await this.client.okr.checkIn.mutate({\n keyResultId: input.id,\n newValue: input.value,\n notes: input.note,\n }) as KeyResultCheckIn;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.okr.delete.mutate({ id }) as { success: boolean };\n }\n\n /** Link a project to a key result as executing work. Idempotent. */\n async linkProject(input: {\n keyResultId: string;\n projectId: string;\n }): Promise<{ success: boolean }> {\n return await this.client.okr.linkProject.mutate(input) as {\n success: boolean;\n };\n }\n\n async unlinkProject(input: {\n keyResultId: string;\n projectId: string;\n }): Promise<{ success: boolean }> {\n return await this.client.okr.unlinkProject.mutate(input) as {\n success: boolean;\n };\n }\n\n /**\n * Link a feature to a key result as executing work. Idempotent. The feature's\n * product must live in the key result's workspace. A feature with no\n * objective alignment inherits the key result's objective; one that already\n * has an objective is never overwritten.\n */\n async linkFeature(input: {\n keyResultId: string;\n featureId: string;\n }): Promise<{ success: boolean }> {\n return await this.client.okr.linkFeature.mutate(input) as {\n success: boolean;\n };\n }\n\n /** Removes only the link row — never the feature's objective alignment. */\n async unlinkFeature(input: {\n keyResultId: string;\n featureId: string;\n }): Promise<{ success: boolean }> {\n return await this.client.okr.unlinkFeature.mutate(input) as {\n success: boolean;\n };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n Project,\n ProjectDetail,\n ProjectPriority,\n ProjectStatus,\n} from './types/project.js';\n\nexport interface ProjectsListOptions {\n workspaceId?: string;\n includeActions?: boolean;\n}\n\n/**\n * A **partial** update. Omit a field and it is left untouched.\n *\n * `name`, `status` and `priority` are required by the server on every call, so\n * {@link ProjectsApi.update} reads the project first and sends the current\n * values for whichever of the three you leave out — the same read-before-write\n * that keeps `goals.update()` from clobbering. Everything else here is written\n * only when present.\n */\nexport interface ProjectUpdateInput {\n id: string;\n name?: string;\n /** The server has no way to clear a description — pass `''` to blank it. */\n description?: string;\n status?: ProjectStatus;\n priority?: ProjectPriority;\n /** `null` unlinks the product. */\n productId?: string | null;\n /** `null` makes the project personal. */\n workspaceId?: string | null;\n /** Directly responsible individual; `null` clears it. */\n driId?: string | null;\n /**\n * Replace the objective links. Integer goal ids passed as strings — the\n * server parses them. An empty array is a **no-op**, not a clear; the server\n * only writes this when the array is non-empty.\n */\n goalIds?: string[];\n outcomeIds?: string[];\n /** Replace the key-result links wholesale; `[]` clears them. */\n keyResultIds?: string[];\n lifeDomainIds?: number[];\n reviewDate?: Date | null;\n nextActionDate?: Date | null;\n startDate?: Date | null;\n endDate?: Date | null;\n}\n\nexport class ProjectsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ProjectsListOptions = {}): Promise<Project[]> {\n const { workspaceId, includeActions } = options;\n\n return await this.client.project.getAll.query({\n workspaceId,\n include: includeActions ? { actions: true } : undefined,\n }) as Project[];\n }\n\n /**\n * Fetch one project with its relations — actions, linked objectives and key\n * results, DRI, team. Accepts a cuid, a slug, or the compound `slug-cuid`\n * form that appears in app URLs.\n *\n * The list read carries none of the OKR edges, so this is the only way to\n * answer \"what is this project driving?\".\n */\n async get(idOrSlug: string): Promise<ProjectDetail> {\n return await this.client.project.getById.query({\n id: idOrSlug,\n }) as ProjectDetail;\n }\n\n /**\n * Partial update — see {@link ProjectUpdateInput}. Costs one extra read when\n * `name`, `status` or `priority` is omitted, because the server requires all\n * three.\n */\n async update(input: ProjectUpdateInput): Promise<Project> {\n const { id, name, status, priority, ...rest } = input;\n\n let resolvedName = name;\n let resolvedStatus = status;\n let resolvedPriority = priority;\n\n if (\n resolvedName === undefined ||\n resolvedStatus === undefined ||\n resolvedPriority === undefined\n ) {\n const current = await this.get(id);\n resolvedName ??= current.name;\n resolvedStatus ??= (current.status as ProjectStatus | null) ?? 'ACTIVE';\n resolvedPriority ??=\n (current.priority as ProjectPriority | null) ?? 'NONE';\n }\n\n return await this.client.project.update.mutate({\n id,\n name: resolvedName,\n status: resolvedStatus,\n priority: resolvedPriority,\n ...rest,\n }) as Project;\n }\n\n /** Deletes the project and its actions. There is no undo. */\n async delete(id: string): Promise<Project> {\n return await this.client.project.delete.mutate({ id }) as Project;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Workspace, WorkspaceMember } from './types/workspace.js';\n\nexport class WorkspacesApi {\n constructor(private client: TrpcClient) {}\n\n async list(): Promise<Workspace[]> {\n return await this.client.workspace.list.query() as Workspace[];\n }\n\n /**\n * Everyone who belongs to a workspace — direct members plus anyone with\n * access through a linked team. This is the lookup that makes mentions\n * possible from outside the app: match a name or email here, then drop the\n * row's `mentionSyntax` into a comment body.\n */\n async listMembers(workspaceId: string): Promise<WorkspaceMember[]> {\n return await this.client.workspace.listMembers.query({\n workspaceId,\n }) as WorkspaceMember[];\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Contact, ContactInteraction, ContactListOutput, InteractionType, InteractionDirection } from './types/contact.js';\n\nexport interface ContactsListOptions {\n workspaceId: string;\n search?: string;\n tags?: string[];\n organizationId?: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface ContactCreateInput {\n workspaceId: string;\n firstName?: string;\n lastName?: string;\n email?: string | null;\n phone?: string;\n linkedIn?: string;\n telegram?: string;\n twitter?: string;\n github?: string;\n bluesky?: string;\n about?: string;\n profileType?: string;\n skills?: string[];\n tags?: string[];\n organizationId?: string;\n /** Link (or find-or-create) an organization by name. Ignored when organizationId is set. */\n organizationName?: string;\n}\n\nexport interface ContactUpdateInput {\n id: string;\n firstName?: string;\n lastName?: string;\n email?: string | null;\n phone?: string | null;\n linkedIn?: string | null;\n telegram?: string | null;\n twitter?: string | null;\n github?: string | null;\n bluesky?: string | null;\n about?: string;\n profileType?: string;\n skills?: string[];\n tags?: string[];\n organizationId?: string | null;\n /** Link (or find-or-create) an organization by name. Ignored when organizationId is set. */\n organizationName?: string;\n}\n\nexport interface EnrichContactResult {\n enqueued: boolean;\n /** The enrichment job id — the newly created one, or the in-flight one that blocked it. */\n enrichmentId?: string;\n /** Why nothing was enqueued (only set when `enqueued` is false). */\n reason?: 'auto-enrich-disabled' | 'already-in-flight';\n}\n\nexport interface AddInteractionInput {\n contactId: string;\n type: InteractionType;\n direction: InteractionDirection;\n subject?: string;\n notes?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport class ContactsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ContactsListOptions): Promise<ContactListOutput> {\n return await this.client.crmApi.contactList.query(options) as ContactListOutput;\n }\n\n async get(id: string, options?: { includeInteractions?: boolean }): Promise<Contact> {\n return await this.client.crmApi.contactGet.query({\n id,\n includeInteractions: options?.includeInteractions,\n }) as Contact;\n }\n\n async create(input: ContactCreateInput): Promise<Contact> {\n return await this.client.crmApi.contactCreate.mutate(input) as Contact;\n }\n\n async update(input: ContactUpdateInput): Promise<Contact> {\n return await this.client.crmApi.contactUpdate.mutate(input) as Contact;\n }\n\n async delete(id: string): Promise<void> {\n await this.client.crmApi.contactDelete.mutate({ id });\n }\n\n async addInteraction(input: AddInteractionInput): Promise<ContactInteraction> {\n return await this.client.crmApi.contactAddInteraction.mutate(input) as ContactInteraction;\n }\n\n /**\n * Enqueue a web-search enrichment job for an existing contact. This is an\n * explicit action, so it runs regardless of the workspace's auto-enrich\n * setting; the enrich-pending-contacts cron drains the job into the\n * enrichment agent. Idempotent — a contact with a job already in flight is\n * not re-queued.\n */\n async enrich(id: string): Promise<EnrichContactResult> {\n return await this.client.crmApi.contactEnrich.mutate({ contactId: id }) as EnrichContactResult;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n Decision,\n DecisionEvidenceTurn,\n DraftDecisionsResult,\n DecisionLink,\n DecisionListRow,\n DecisionReviewState,\n DecisionSource,\n DecisionStatus,\n MeetingDecisions,\n} from './types/decision.js';\n\n/** A person who made the decision; `name` is the only required half. */\nexport interface DecisionDeciderInput {\n userId?: string | null;\n name: string;\n email?: string | null;\n}\n\nexport interface DecisionListOptions {\n workspaceId: string;\n statuses?: DecisionStatus[];\n sources?: DecisionSource[];\n /** A product id, or the literal `\"workspace\"` for decisions with no product. */\n productId?: string;\n /** With a real `productId`: ALSO include decisions that have no product. */\n includeWorkspaceWide?: boolean;\n projectId?: string;\n /** Free-text over statement and body (max 200 characters). */\n search?: string;\n /** One decision by its workspace sequence number — `D-0003` is number 3. */\n number?: number;\n /** Cap the rows returned (1-500). Unset returns everything visible. */\n limit?: number;\n}\n\nexport interface DecisionCreateInput {\n workspaceId: string;\n /** The decision itself, or the open question. Max 500 characters. */\n statement: string;\n /** Markdown detail — context, alternatives, consequences. Max 20,000. */\n body?: string | null;\n /**\n * Defaults to `PROPOSED` server-side. Pass `OPEN` to log an OPEN QUESTION —\n * that is the only representation of one. `SUPERSEDED` and `DEPRECATED` are\n * rejected here; they are `setStatus` transitions.\n */\n status?: DecisionStatus;\n source?: DecisionSource;\n decidedAt?: Date | null;\n ownerId?: string | null;\n /** Meeting provenance. Requires EDIT access to that meeting. */\n transcriptionSessionId?: string | null;\n occurrenceId?: string | null;\n productId?: string | null;\n projectId?: string | null;\n goalId?: number | null;\n keyResultId?: string | null;\n /** Max 50. */\n deciders?: DecisionDeciderInput[];\n /**\n * Quoted transcript turns backing the decision (max 50). The server checks\n * every turn against the meeting's actual transcript: the index must\n * resolve and the words must be that turn's, compared loosely for case,\n * punctuation and whitespace. Turns that don't match are DROPPED, silently\n * from the caller's side, and `speaker`/`startTime` are overwritten with\n * the transcript's own values. Evidence therefore requires\n * `transcriptionSessionId` — sending it without one is a BAD_REQUEST.\n */\n evidence?: DecisionEvidenceTurn[];\n}\n\n/** Content and scope only — status changes go through {@link DecisionsApi.setStatus}. */\nexport interface DecisionUpdateInput {\n workspaceId: string;\n decisionId: string;\n statement?: string;\n body?: string | null;\n decidedAt?: Date | null;\n ownerId?: string | null;\n productId?: string | null;\n projectId?: string | null;\n goalId?: number | null;\n keyResultId?: string | null;\n adrDocumentId?: string | null;\n}\n\nexport interface DecisionSetStatusInput {\n workspaceId: string;\n decisionId: string;\n status: DecisionStatus;\n /** Required by convention when moving to `SUPERSEDED`. */\n supersededById?: string | null;\n}\n\n/**\n * Decisions — the writable half of the Decision Log (ADR-0060).\n *\n * The one thing worth knowing before using this: **an open question is a\n * decision with status `OPEN`**. There is no separate model, and it is what\n * the \"Open questions\" panel on a meeting page reads.\n *\n * Reads need workspace `view`; writes need workspace `edit`, and a decision\n * carrying `transcriptionSessionId` additionally needs edit access to that\n * meeting.\n */\nexport class DecisionsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * Confirmed decisions in a workspace, newest decided first. Drafts are\n * never included — see {@link listForMeeting} for those.\n */\n async list(options: DecisionListOptions): Promise<DecisionListRow[]> {\n return await this.client.decision.list.query(options) as DecisionListRow[];\n }\n\n async get(workspaceId: string, decisionId: string): Promise<Decision> {\n return await this.client.decision.get.query({\n workspaceId,\n decisionId,\n }) as Decision;\n }\n\n /**\n * Decisions logged from one meeting — both panels' contents. Drafts are\n * included for callers who can edit the meeting. No workspace id needed:\n * the meeting resolves it.\n */\n async listForMeeting(\n transcriptionSessionId: string,\n ): Promise<MeetingDecisions> {\n return await this.client.decision.listForMeeting.query({\n transcriptionSessionId,\n }) as MeetingDecisions;\n }\n\n /** Decisions formalised as one ADR (\"Decided in\"). */\n async listForAdr(\n workspaceId: string,\n adrDocumentId: string,\n ): Promise<DecisionListRow[]> {\n return await this.client.decision.listForAdr.query({\n workspaceId,\n adrDocumentId,\n }) as DecisionListRow[];\n }\n\n /**\n * Extract draft decisions from a meeting's notes and transcript. Drafts\n * only — someone confirms or rejects each one. Idempotent per meeting:\n * existing drafts come back untouched, and a meeting that already has\n * confirmed decisions reports `alreadyPublished` without calling the model.\n */\n async extractDrafts(\n transcriptionSessionId: string,\n ): Promise<DraftDecisionsResult> {\n return await this.client.decision.extractDrafts.mutate({\n transcriptionSessionId,\n }) as DraftDecisionsResult;\n }\n\n /**\n * Log a decision. Pass `status: 'OPEN'` for an open question, and\n * `transcriptionSessionId` to attach it to the meeting it came out of.\n */\n async create(input: DecisionCreateInput): Promise<Decision> {\n return await this.client.decision.create.mutate(input) as Decision;\n }\n\n async update(input: DecisionUpdateInput): Promise<Decision> {\n return await this.client.decision.update.mutate(input) as Decision;\n }\n\n /**\n * Lifecycle transition — including answering an open question by moving it\n * from `OPEN` to `ACCEPTED`.\n */\n async setStatus(input: DecisionSetStatusInput): Promise<Decision> {\n return await this.client.decision.setStatus.mutate(input) as Decision;\n }\n\n /** \"Implemented by\" a ticket. Idempotent: an existing link is returned. */\n async linkTicket(\n workspaceId: string,\n decisionId: string,\n ticketId: string,\n ): Promise<DecisionLink> {\n return await this.client.decision.linkTicket.mutate({\n workspaceId,\n decisionId,\n ticketId,\n }) as DecisionLink;\n }\n\n /** \"Implemented by\" a feature. Idempotent: an existing link is returned. */\n async linkFeature(\n workspaceId: string,\n decisionId: string,\n featureId: string,\n ): Promise<DecisionLink> {\n return await this.client.decision.linkFeature.mutate({\n workspaceId,\n decisionId,\n featureId,\n }) as DecisionLink;\n }\n\n /** Remove one link, by the `DecisionLink` id (not the ticket/feature id). */\n async unlink(workspaceId: string, linkId: string): Promise<{ deleted: boolean }> {\n return await this.client.decision.unlink.mutate({\n workspaceId,\n linkId,\n }) as { deleted: boolean };\n }\n\n /**\n * Publish a draft into the log. Needs a person's login: agent keys are\n * refused. Idempotent on a decision that is already confirmed.\n *\n * `status` moves it in the same write — `{ status: 'ACCEPTED' }` is\n * \"confirm as accepted\", and works on an already-confirmed decision too.\n * `SUPERSEDED` is refused (it needs a successor; use {@link setStatus}).\n * A person confirming or accepting a decision that no person stands behind\n * becomes its decider. `decisionId` may also be a `D-0006` label.\n */\n async confirmDraft(\n workspaceId: string,\n decisionId: string,\n options: { status?: DecisionStatus } = {},\n ): Promise<Decision> {\n return await this.client.decision.confirmDraft.mutate({\n workspaceId,\n decisionId,\n ...(options.status ? { status: options.status } : {}),\n }) as Decision;\n }\n\n /**\n * Reject a draft. Confirmed decisions are never rejected — deprecate or\n * supersede them through {@link setStatus}.\n */\n async rejectDraft(\n workspaceId: string,\n decisionId: string,\n ): Promise<{ id: string; reviewState: DecisionReviewState }> {\n return await this.client.decision.rejectDraft.mutate({\n workspaceId,\n decisionId,\n }) as { id: string; reviewState: DecisionReviewState };\n }\n\n /**\n * Hard-delete a draft or rejected row. The server refuses for a confirmed\n * decision — the log keeps its history.\n */\n async deleteDraft(\n workspaceId: string,\n decisionId: string,\n ): Promise<{ id: string }> {\n return await this.client.decision.deleteDraft.mutate({\n workspaceId,\n decisionId,\n }) as { id: string };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Organization, OrganizationListOutput, OrganizationSize } from './types/organization.js';\n\nexport interface OrganizationsListOptions {\n workspaceId: string;\n search?: string;\n industry?: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface OrganizationCreateInput {\n workspaceId: string;\n name: string;\n websiteUrl?: string | null;\n logoUrl?: string | null;\n description?: string;\n industry?: string;\n size?: OrganizationSize;\n}\n\nexport class OrganizationsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: OrganizationsListOptions): Promise<OrganizationListOutput> {\n return await this.client.crmApi.organizationList.query(options) as OrganizationListOutput;\n }\n\n async get(id: string): Promise<Organization> {\n return await this.client.crmApi.organizationGet.query({ id }) as Organization;\n }\n\n async create(input: OrganizationCreateInput): Promise<Organization> {\n return await this.client.crmApi.organizationCreate.mutate(input) as Organization;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Pipeline, PipelineStage, Deal } from './types/pipeline.js';\n\nexport interface DealCreateInput {\n workspaceId: string;\n stageId: string;\n title: string;\n description?: string;\n value?: number;\n currency?: string;\n probability?: number;\n expectedCloseDate?: Date;\n contactId?: string;\n organizationId?: string;\n assignedToId?: string;\n}\n\nexport interface DealUpdateInput {\n id: string;\n title?: string;\n description?: string | null;\n value?: number | null;\n currency?: string;\n probability?: number | null;\n expectedCloseDate?: Date | null;\n contactId?: string | null;\n organizationId?: string | null;\n assignedToId?: string | null;\n}\n\nexport interface DealMoveInput {\n id: string;\n stageId: string;\n stageOrder: number;\n}\n\nexport class PipelinesApi {\n constructor(private client: TrpcClient) {}\n\n async get(workspaceId: string): Promise<Pipeline | null> {\n return await this.client.crmApi.pipelineGet.query({ workspaceId }) as Pipeline | null;\n }\n\n async getStages(workspaceId: string): Promise<PipelineStage[]> {\n return await this.client.crmApi.pipelineGetStages.query({ workspaceId }) as PipelineStage[];\n }\n\n async listDeals(workspaceId: string): Promise<Deal[]> {\n return await this.client.crmApi.dealList.query({ workspaceId }) as Deal[];\n }\n\n async getDeal(id: string): Promise<Deal> {\n return await this.client.crmApi.dealGet.query({ id }) as Deal;\n }\n\n async createDeal(input: DealCreateInput): Promise<Deal> {\n return await this.client.crmApi.dealCreate.mutate(input) as Deal;\n }\n\n async updateDeal(input: DealUpdateInput): Promise<Deal> {\n return await this.client.crmApi.dealUpdate.mutate(input) as Deal;\n }\n\n async moveDeal(input: DealMoveInput): Promise<Deal> {\n return await this.client.crmApi.dealMove.mutate(input) as Deal;\n }\n\n async deleteDeal(id: string): Promise<void> {\n await this.client.crmApi.dealDelete.mutate({ id });\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { TicketComment } from './types/comment.js';\nimport type {\n Ticket,\n TicketDetail,\n TicketDependencyEdge,\n TicketStatus,\n TicketType,\n} from './types/ticket.js';\nimport type { Action } from './types/action.js';\n\nexport interface TicketListOptions {\n /**\n * Always required. `product.ticket.list` is product-scoped on the server —\n * there is no workspace-wide ticket query. To search several products, call\n * `list` once per product and merge the results.\n */\n productId: string;\n status?: TicketStatus;\n type?: TicketType;\n featureId?: string;\n epicId?: string;\n cycleId?: string;\n assigneeId?: string;\n /**\n * Filter by `Ticket.prUrl` (exact match).\n *\n * Applied **client-side**, after the product-scoped fetch — the server's\n * `list` input schema has no `prUrl` field. See the note on {@link\n * TicketsApi.list}.\n */\n prUrl?: string;\n /**\n * Filter by `Ticket.branchName` (exact match).\n *\n * Applied **client-side**, after the product-scoped fetch — the server's\n * `list` input schema has no `branchName` field. See the note on {@link\n * TicketsApi.list}.\n */\n branchName?: string;\n}\n\nexport interface TicketCreateInput {\n productId: string;\n title: string;\n body?: string;\n type?: TicketType;\n status?: TicketStatus;\n /** 0–4; lower is higher priority. */\n priority?: number;\n points?: number;\n branchName?: string;\n prUrl?: string;\n designUrl?: string;\n specUrl?: string;\n links?: Record<string, string>;\n epicId?: string;\n featureId?: string;\n cycleId?: string;\n scopeId?: string;\n assigneeId?: string;\n templateId?: string;\n}\n\nexport interface TicketUpdateInput {\n id: string;\n title?: string;\n body?: string;\n type?: TicketType;\n status?: TicketStatus;\n priority?: number | null;\n points?: number | null;\n branchName?: string | null;\n prUrl?: string | null;\n designUrl?: string | null;\n specUrl?: string | null;\n links?: Record<string, string> | null;\n epicId?: string | null;\n featureId?: string | null;\n cycleId?: string | null;\n scopeId?: string | null;\n assigneeId?: string | null;\n}\n\nexport interface TicketCommentAddInput {\n ticketId: string;\n content: string;\n}\n\nexport interface TicketCommentUpdateInput {\n id: string;\n content: string;\n}\n\nexport interface TicketSearchOptions {\n productId: string;\n query?: string;\n excludeTicketId?: string;\n limit?: number;\n}\n\nexport class TicketsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * List tickets in one product.\n *\n * `prUrl` and `branchName` are filtered here rather than on the server. The\n * `product.ticket.list` tRPC input schema accepts neither, and zod strips\n * unknown keys, so forwarding them was silently a no-op: a lookup by a branch\n * that matched nothing came back as *every ticket in the product*. Filtering\n * locally makes them mean what they say. Move them server-side once\n * `product.ticket.list` grows the matching input fields.\n */\n async list(options: TicketListOptions): Promise<Ticket[]> {\n const { prUrl, branchName, ...serverQuery } = options;\n const tickets = await this.client.product.ticket.list.query(\n serverQuery,\n ) as Ticket[];\n\n return tickets.filter((t) =>\n (prUrl === undefined || t.prUrl === prUrl) &&\n (branchName === undefined || t.branchName === branchName)\n );\n }\n\n async get(id: string): Promise<TicketDetail> {\n return await this.client.product.ticket.getById.query({\n id,\n }) as TicketDetail;\n }\n\n async create(input: TicketCreateInput): Promise<Ticket> {\n return await this.client.product.ticket.create.mutate(input) as Ticket;\n }\n\n async update(input: TicketUpdateInput): Promise<Ticket> {\n return await this.client.product.ticket.update.mutate(input) as Ticket;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.ticket.delete.mutate({ id }) as {\n success: boolean;\n };\n }\n\n async search(options: TicketSearchOptions): Promise<TicketDependencyEdge[]> {\n return await this.client.product.ticket.search.query(\n options,\n ) as TicketDependencyEdge[];\n }\n\n /** Mark `ticketId` as blocked by `dependsOnId`. */\n async addDependency(\n ticketId: string,\n dependsOnId: string,\n ): Promise<{ id: string; dependsOn: TicketDependencyEdge }> {\n return await this.client.product.ticket.addDependency.mutate({\n ticketId,\n dependsOnId,\n }) as { id: string; dependsOn: TicketDependencyEdge };\n }\n\n async removeDependency(\n ticketId: string,\n dependsOnId: string,\n ): Promise<{ success: boolean }> {\n return await this.client.product.ticket.removeDependency.mutate({\n ticketId,\n dependsOnId,\n }) as { success: boolean };\n }\n\n async addComment(input: TicketCommentAddInput): Promise<TicketComment> {\n return await this.client.product.ticket.addComment.mutate(\n input,\n ) as TicketComment;\n }\n\n async updateComment(input: TicketCommentUpdateInput): Promise<TicketComment> {\n return await this.client.product.ticket.updateComment.mutate(\n input,\n ) as TicketComment;\n }\n\n async deleteComment(id: string): Promise<{ success: boolean }> {\n return await this.client.product.ticket.deleteComment.mutate({\n id,\n }) as { success: boolean };\n }\n\n /** Attach an existing action to a ticket. */\n async linkAction(ticketId: string, actionId: string): Promise<Action> {\n return await this.client.product.ticket.linkAction.mutate({\n ticketId,\n actionId,\n }) as Action;\n }\n\n /** Detach an action from whatever ticket it's linked to. */\n async unlinkAction(actionId: string): Promise<Action> {\n return await this.client.product.ticket.unlinkAction.mutate({\n actionId,\n }) as Action;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Product } from './types/product.js';\n\nexport interface ProductCreateInput {\n workspaceId: string;\n name: string;\n /** Kebab-case slug; must match `/^[a-z0-9-]+$/`. */\n slug: string;\n description?: string;\n icon?: string;\n color?: string;\n}\n\nexport interface ProductUpdateInput {\n id: string;\n name?: string;\n description?: string;\n icon?: string;\n color?: string;\n funTicketIds?: boolean;\n}\n\nexport class ProductsApi {\n constructor(private client: TrpcClient) {}\n\n async list(workspaceId: string): Promise<Product[]> {\n return await this.client.product.product.list.query({\n workspaceId,\n }) as Product[];\n }\n\n async get(id: string): Promise<Product> {\n return await this.client.product.product.getById.query({ id }) as Product;\n }\n\n async getBySlug(workspaceId: string, slug: string): Promise<Product> {\n return await this.client.product.product.getBySlug.query({\n workspaceId,\n slug,\n }) as Product;\n }\n\n /**\n * Resolve a product reference (slug or CUID) to a full Product. Falls back\n * to slug lookup if the bare CUID lookup fails — callers can pass either.\n */\n async resolve(workspaceId: string, slugOrId: string): Promise<Product> {\n // Heuristic: CUIDs from Prisma start with 'c' and are 25 chars; otherwise\n // try slug first. We try both to stay forgiving.\n const looksLikeId = /^c[a-z0-9]{20,}$/.test(slugOrId);\n if (looksLikeId) {\n try {\n return await this.get(slugOrId);\n } catch {\n // fall through to slug\n }\n }\n return await this.getBySlug(workspaceId, slugOrId);\n }\n\n async create(input: ProductCreateInput): Promise<Product> {\n return await this.client.product.product.create.mutate(input) as Product;\n }\n\n async update(input: ProductUpdateInput): Promise<Product> {\n return await this.client.product.product.update.mutate(input) as Product;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.product.delete.mutate({ id }) as {\n success: boolean;\n };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Feature, FeatureStatus } from './types/feature.js';\n\nexport interface FeatureListOptions {\n productId: string;\n status?: FeatureStatus;\n}\n\nexport interface FeatureCreateInput {\n productId: string;\n name: string;\n description?: string;\n vision?: string;\n status?: FeatureStatus;\n effort?: number;\n /** 0–4; lower is higher priority. */\n priority?: number;\n goalId?: number;\n /** Area (per-product bucket) to file the feature under. */\n areaId?: string;\n}\n\nexport interface FeatureUpdateInput {\n id: string;\n name?: string;\n description?: string;\n vision?: string;\n status?: FeatureStatus;\n effort?: number;\n priority?: number;\n goalId?: number | null;\n areaId?: string | null;\n}\n\nexport interface FeatureLinkPageInput {\n featureId: string;\n pageId: string;\n /** Pin the linked page to one of the feature's scopes. */\n scopeId?: string;\n}\n\nexport class FeaturesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: FeatureListOptions): Promise<Feature[]> {\n return await this.client.product.feature.list.query({\n productId: options.productId,\n status: options.status,\n }) as Feature[];\n }\n\n async get(id: string): Promise<Feature> {\n return await this.client.product.feature.getById.query({ id }) as Feature;\n }\n\n async create(input: FeatureCreateInput): Promise<Feature> {\n return await this.client.product.feature.create.mutate(input) as Feature;\n }\n\n async update(input: FeatureUpdateInput): Promise<Feature> {\n return await this.client.product.feature.update.mutate(input) as Feature;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.delete.mutate({ id }) as {\n success: boolean;\n };\n }\n\n /** Link a Knowledge page (PRD, spec, research) to a feature. */\n async linkPage(input: FeatureLinkPageInput): Promise<unknown> {\n return await this.client.product.feature.linkPage.mutate(input);\n }\n\n async unlinkPage(featureId: string, pageId: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.unlinkPage.mutate({\n featureId,\n pageId,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Feature } from './types/feature.js';\nimport type { UserStory } from './types/userStory.js';\n\nexport interface UserStoryListOptions {\n featureId: string;\n}\n\nexport interface UserStoryCreateInput {\n featureId: string;\n asA?: string;\n iWant?: string;\n soThat?: string;\n acceptanceCriteria?: string;\n scopeId?: string;\n}\n\nexport interface UserStoryUpdateInput {\n id: string;\n asA?: string;\n iWant?: string;\n soThat?: string;\n acceptanceCriteria?: string;\n scopeId?: string | null;\n}\n\n/**\n * Native, structured user stories on a feature (As a / I want / So that).\n *\n * Mirrors the existing `FeaturesApi` shape and the `client.product.feature.*`\n * call style. `list` derives from the feature's `getById` payload, which\n * already includes `userStories` ordered by `displayOrder` — there is no\n * dedicated list procedure.\n */\nexport class UserStoriesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: UserStoryListOptions): Promise<UserStory[]> {\n const feature = await this.client.product.feature.getById.query({\n id: options.featureId,\n }) as Feature & { userStories?: UserStory[] };\n return feature.userStories ?? [];\n }\n\n async create(input: UserStoryCreateInput): Promise<UserStory> {\n return await this.client.product.feature.addUserStory.mutate(\n input,\n ) as UserStory;\n }\n\n async update(input: UserStoryUpdateInput): Promise<UserStory> {\n return await this.client.product.feature.updateUserStory.mutate(\n input,\n ) as UserStory;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.deleteUserStory.mutate({\n id,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Epic, EpicPriority, EpicStatus } from './types/epic.js';\n\nexport interface EpicListOptions {\n workspaceId: string;\n status?: EpicStatus;\n}\n\nexport interface EpicCreateInput {\n workspaceId: string;\n name: string;\n description?: string;\n priority?: EpicPriority;\n startDate?: Date;\n targetDate?: Date;\n}\n\nexport interface EpicUpdateInput {\n id: string;\n name?: string;\n description?: string | null;\n status?: EpicStatus;\n priority?: EpicPriority;\n startDate?: Date | null;\n targetDate?: Date | null;\n}\n\nexport class EpicsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: EpicListOptions): Promise<Epic[]> {\n return await this.client.epic.list.query({\n workspaceId: options.workspaceId,\n status: options.status,\n }) as Epic[];\n }\n\n async get(id: string): Promise<Epic> {\n return await this.client.epic.getById.query({ id }) as Epic;\n }\n\n async create(input: EpicCreateInput): Promise<Epic> {\n return await this.client.epic.create.mutate(input) as Epic;\n }\n\n async update(input: EpicUpdateInput): Promise<Epic> {\n return await this.client.epic.update.mutate(input) as Epic;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.epic.delete.mutate({ id }) as {\n success: boolean;\n };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Tag, TagEntityType, TagListResult } from './types/tag.js';\n\nexport interface LabelListOptions {\n workspaceId?: string;\n category?: string | null;\n}\n\nexport interface LabelCreateInput {\n workspaceId: string;\n name: string;\n color: string;\n description?: string;\n category?: string | null;\n}\n\nexport interface SetEntityTagsInput {\n entityType: TagEntityType;\n entityId: string;\n tagIds: string[];\n}\n\nexport interface ListForEntityInput {\n entityType: TagEntityType;\n entityId: string;\n}\n\nexport interface SetEntityTagsResult {\n entityType: TagEntityType;\n entityId: string;\n tags: Tag[];\n}\n\n/**\n * Labels API. Backed by the server's `tag.*` tRPC procedures. \"Label\" is the\n * user-facing word for a Tag (specifically when `category` is null).\n */\nexport class LabelsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: LabelListOptions = {}): Promise<TagListResult> {\n return (await this.client.tag.list.query({\n workspaceId: options.workspaceId,\n category: options.category,\n })) as TagListResult;\n }\n\n async create(input: LabelCreateInput): Promise<Tag> {\n return (await this.client.tag.create.mutate({\n workspaceId: input.workspaceId,\n name: input.name,\n color: input.color,\n description: input.description,\n category: input.category,\n })) as Tag;\n }\n\n async setEntityTags(input: SetEntityTagsInput): Promise<SetEntityTagsResult> {\n return (await this.client.tag.setEntityTags.mutate(input)) as SetEntityTagsResult;\n }\n\n async listForEntity(input: ListForEntityInput): Promise<Tag[]> {\n return (await this.client.tag.listForEntity.query(input)) as Tag[];\n }\n}\n","import type { TrpcClient } from './client.js';\n\nexport interface Area {\n id: string;\n productId: string;\n name: string;\n description: string | null;\n displayOrder: number;\n createdAt: Date;\n updatedAt: Date;\n _count?: {\n features?: number;\n };\n}\n\nexport interface AreaListOptions {\n productId: string;\n}\n\nexport interface AreaCreateInput {\n productId: string;\n name: string;\n description?: string;\n}\n\n/**\n * Areas: per-product buckets a feature is filed under (exactly one or none).\n */\nexport class AreasApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: AreaListOptions): Promise<Area[]> {\n return await this.client.product.feature.listAreas.query(options) as Area[];\n }\n\n async create(input: AreaCreateInput): Promise<Area> {\n return await this.client.product.feature.createArea.mutate(input) as Area;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Meeting } from './types/meeting.js';\n\nexport type MeetingTypeFilter =\n | 'all'\n | 'mine'\n | 'one_on_one'\n | 'customer'\n | 'internal';\n\nexport interface MeetingListOptions {\n workspaceId?: string;\n includeArchived?: boolean;\n /**\n * - `mine`: caller owns the meeting or is a participant\n * - `one_on_one`: exactly two participants\n * - `customer` / `internal`: always empty until meeting tagging ships\n */\n meetingType?: MeetingTypeFilter;\n}\n\n/** A member (userId), an existing CRM contact (contactId), or a name/email. */\nexport interface MeetingParticipantInput {\n userId?: string;\n contactId?: string;\n email?: string;\n name?: string;\n}\n\nexport interface MeetingCreateInput {\n title: string;\n /** Raw transcript text — required by the server, min 1 character. */\n transcription: string;\n description?: string;\n notes?: string;\n meetingDate?: Date;\n /** A project-linked meeting inherits its project's workspace. */\n projectId?: string;\n workspaceId?: string;\n participants?: MeetingParticipantInput[];\n}\n\nexport interface MeetingUpdateInput {\n id: string;\n title?: string;\n description?: string;\n notes?: string;\n summary?: string;\n transcription?: string;\n meetingDate?: Date | null;\n workspaceId?: string | null;\n}\n\n/**\n * Meetings (transcription sessions): recorded/imported meetings and manually\n * created ones, each carrying `notes`, an AI `summary`, and the raw\n * `transcription`.\n */\nexport class MeetingsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * List meetings visible to the caller (owner, participant, project access,\n * or workspace membership). Rows include full `notes`/`summary`/\n * `transcription` bodies, so expect large payloads.\n */\n async list(options: MeetingListOptions = {}): Promise<Meeting[]> {\n return await this.client.transcription.getAllTranscriptions.query(\n options,\n ) as Meeting[];\n }\n\n async get(id: string): Promise<Meeting> {\n return await this.client.transcription.getById.query({ id }) as Meeting;\n }\n\n async create(input: MeetingCreateInput): Promise<Meeting> {\n return await this.client.transcription.createManualTranscription.mutate(\n input,\n ) as Meeting;\n }\n\n /**\n * Partial update — only the keys present are written. The server splits\n * title from the other fields, so a title change is a second mutation.\n */\n async update(input: MeetingUpdateInput): Promise<Meeting> {\n const { id, title, ...details } = input;\n const hasDetails = Object.values(details).some((v) => v !== undefined);\n if (title === undefined && !hasDetails) {\n throw new Error('MeetingsApi.update: nothing to update');\n }\n\n let result: Meeting | undefined;\n if (title !== undefined) {\n result = await this.client.transcription.updateTitle.mutate({\n id,\n title,\n }) as Meeting;\n }\n if (hasDetails) {\n result = await this.client.transcription.updateDetails.mutate({\n id,\n ...details,\n }) as Meeting;\n }\n return result!;\n }\n\n /** The meeting-notes body alone (null when none have been written). */\n async getNotes(id: string): Promise<string | null> {\n const meeting = await this.get(id);\n return meeting.notes ?? null;\n }\n\n /** Replace the meeting's notes. */\n async setNotes(id: string, notes: string): Promise<Meeting> {\n return await this.update({ id, notes });\n }\n\n /**\n * Permanently delete one meeting. Owner-only: the server answers\n * NOT_FOUND for a missing id and FORBIDDEN for a meeting you don't own.\n * Linked actions survive (their meeting link is nulled).\n */\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.transcription.deleteTranscription.mutate({\n id,\n }) as { success: boolean };\n }\n\n /**\n * Permanently delete meetings in bulk. Scoped to meetings the caller\n * owns — ids that are missing or owned by someone else are silently\n * skipped, so compare `count` against the ids you sent.\n */\n async deleteMany(ids: string[]): Promise<{ count: number }> {\n return await this.client.transcription.bulkDeleteTranscriptions.mutate({\n ids,\n }) as { count: number };\n }\n\n /**\n * Append a block to the meeting's notes (separated by a blank line),\n * creating them if none exist. Read-modify-write, not atomic.\n */\n async appendNotes(id: string, text: string): Promise<Meeting> {\n const existing = await this.getNotes(id);\n const notes = existing?.trim()\n ? `${existing.replace(/\\s+$/, '')}\\n\\n${text}`\n : text;\n return await this.update({ id, notes });\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n KnowledgePage,\n PageDiff,\n PageGetFormat,\n PageHistory,\n PageRevisionDetail,\n PageSearchOutput,\n} from './types/page.js';\n\nexport interface PageListOptions {\n workspaceId: string;\n projectId?: string;\n /** Case-insensitive title match. To find pages by content or meaning use `search`. */\n search?: string;\n}\n\nexport interface PageGetOptions {\n /**\n * How much of the body to fetch. Defaults to `markdown` — the Markdown body\n * without the editor's ProseMirror doc, which is several times larger and\n * carries nothing an agent needs. `outline` returns headings only; `full`\n * is the editor payload.\n */\n format?: PageGetFormat;\n /**\n * Narrow the body to one section: the heading's text (case-insensitive;\n * `## ` prefix tolerated) through to the next heading of the same or a\n * higher level. Unknown headings fail with the list of headings that exist.\n */\n section?: string;\n}\n\nexport interface PageSearchOptions {\n workspaceId: string;\n /** What the page should be about (2–200 chars). */\n query: string;\n projectId?: string;\n /** Max pages returned (1–25, server default 10). */\n limit?: number;\n}\n\nexport interface PageHistoryOptions {\n /** Max revisions (1–200, server default 50). */\n limit?: number;\n /** `nextCursor` from a previous page of history. */\n cursor?: string;\n}\n\nexport interface PageDiffOptions {\n /**\n * What to compare the revision with: `previous` (default — what this\n * revision changed), `current` (the page as it is now), or another\n * revision's id.\n */\n against?: 'previous' | 'current' | string;\n}\n\nexport interface PageCreateInput {\n workspaceId: string;\n projectId?: string | null;\n title?: string;\n /** Markdown body. Indexed for search when non-empty. */\n body?: string;\n includeInSearch?: boolean;\n /** Why the page was created — recorded on its first revision. */\n note?: string;\n /** Provenance: where the facts come from (URL, document, person). */\n source?: string | null;\n /** Provenance: the date the facts were true. */\n asOf?: Date | null;\n}\n\nexport interface PageUpdateInput {\n id: string;\n title?: string;\n projectId?: string | null;\n includeInSearch?: boolean;\n /**\n * Markdown body. Sending `body` without a rich-text doc is a\n * Markdown-source write: the server treats the Markdown as canonical and\n * the editor re-derives its rich document on next open.\n */\n body?: string;\n /**\n * The `docVersion` you read before editing. With it, a body write is a\n * compare-and-set: if someone saved in between, the call fails with\n * CONFLICT instead of overwriting their work. Always send it when you can.\n */\n baseVersion?: number;\n /**\n * Why this change — recorded on the revision and shown in the page's\n * history. Always send one from an agent: a body write without a note\n * reads \"No reason given\" to everyone who looks at the history.\n */\n note?: string;\n /** Provenance: where the facts come from. Empty string / null clears it. */\n source?: string | null;\n /** Provenance: the date the facts were true. Null clears it. */\n asOf?: Date | null;\n}\n\nexport interface PageRestoreOptions {\n /** Why you are restoring; defaults to \"Restored the version from <date>\". */\n note?: string;\n /**\n * The page's `docVersion` when you decided to restore (the newest\n * revision's `docVersion` from `history`). With it, a page saved since then\n * fails with CONFLICT instead of being replaced. Always send it.\n */\n baseVersion?: number;\n}\n\n/**\n * Knowledge pages (PRDs, research, technical specs). Workspace-scoped\n * documents; link one to a feature via `FeaturesApi.linkPage`.\n *\n * Reads are lean by default: `get` returns Markdown only. Use `outline` to see\n * a long page's shape, then `get(id, { section })` for the part you need.\n * Every write is recorded in the page's history (`history`, `diff`,\n * `restore`); pass a `note` so the record says why.\n */\nexport class PagesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: PageListOptions): Promise<KnowledgePage[]> {\n return await this.client.page.list.query(options) as KnowledgePage[];\n }\n\n /** One page. Markdown body only unless `format` says otherwise. */\n async get(id: string, options: PageGetOptions = {}): Promise<KnowledgePage> {\n return await this.client.page.get.query({\n id,\n format: options.format ?? 'markdown',\n ...(options.section ? { section: options.section } : {}),\n }) as KnowledgePage;\n }\n\n /** The page's headings (level, text, line) and `bodyBytes`, no body. */\n async outline(id: string): Promise<KnowledgePage> {\n return await this.get(id, { format: 'outline' });\n }\n\n /**\n * Pages about something: semantic hits from the Knowledge index first\n * (nearest first, with the matching passage as `snippet`), then pages whose\n * title or body contain the query. Only pages the caller can view.\n */\n async search(options: PageSearchOptions): Promise<PageSearchOutput> {\n return await this.client.page.search.query(options) as PageSearchOutput;\n }\n\n async create(input: PageCreateInput): Promise<KnowledgePage> {\n return await this.client.page.create.mutate(input) as KnowledgePage;\n }\n\n async update(input: PageUpdateInput): Promise<KnowledgePage> {\n return await this.client.page.update.mutate(input) as KnowledgePage;\n }\n\n /** The page's revisions, newest first — who, when, why, size. Never the bodies. */\n async history(id: string, options: PageHistoryOptions = {}): Promise<PageHistory> {\n return await this.client.page.history.query({ id, ...options }) as PageHistory;\n }\n\n /** One revision with its Markdown body. */\n async revision(pageId: string, revisionId: string): Promise<PageRevisionDetail> {\n return await this.client.page.revision.query({ id: pageId, revisionId }) as PageRevisionDetail;\n }\n\n /** What a revision changed, as a unified diff of the Markdown. */\n async diff(pageId: string, revisionId: string, options: PageDiffOptions = {}): Promise<PageDiff> {\n return await this.client.page.diff.query({\n id: pageId,\n revisionId,\n against: options.against ?? 'previous',\n }) as PageDiff;\n }\n\n /**\n * Put a revision's content back as the page's current content. A forward\n * write: `docVersion` bumps and a \"restore\" revision is recorded.\n */\n async restore(\n pageId: string,\n revisionId: string,\n options: PageRestoreOptions = {},\n ): Promise<{ id: string; docVersion: number; revisionId: string }> {\n return await this.client.page.restore.mutate({ id: pageId, revisionId, ...options }) as {\n id: string;\n docVersion: number;\n revisionId: string;\n };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { ReadStatus, Resource, ResourceContentType } from './types/resource.js';\n\nexport interface ResourceListOptions {\n workspaceId?: string;\n projectId?: string;\n contentType?: ResourceContentType;\n /**\n * Reading-list filter. `'unread'` is the queue (`to_read` + `reading`);\n * a single status narrows to that status; omitted applies no read filter.\n */\n readStatus?: ReadStatus | 'unread';\n search?: string;\n tags?: string[];\n includeArchived?: boolean;\n limit?: number;\n cursor?: string;\n}\n\nexport interface ResourceListResult {\n resources: Resource[];\n nextCursor?: string;\n}\n\nexport interface ResourceCreateInput {\n title: string;\n url?: string;\n description?: string;\n /** Pasted body. Only a Resource with content is embedded for search. */\n content?: string;\n contentType?: ResourceContentType;\n tags?: string[];\n workspaceId?: string;\n projectId?: string;\n /** Defaults to `to_read` server-side, so a saved link lands in the Reading list. */\n readStatus?: ReadStatus;\n /** Defaults to true server-side; a no-op when there is no content to embed. */\n generateEmbeddings?: boolean;\n}\n\nexport interface ResourceReadState {\n id: string;\n readStatus: ReadStatus | string;\n readAt: Date | null;\n}\n\n/**\n * Resources: ingested external content (saved links, PDFs, pasted notes).\n * The Reading list is `list({ readStatus: 'unread' })`; `save` is the\n * quick-add that files a URL as a `bookmark` to read.\n *\n * Indexing follows content, never read state: a bare URL has nothing to\n * embed and is findable by title and URL only.\n */\nexport class ResourcesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ResourceListOptions = {}): Promise<ResourceListResult> {\n return await this.client.resource.list.query(options) as ResourceListResult;\n }\n\n async create(input: ResourceCreateInput): Promise<Resource> {\n const result = await this.client.resource.create.mutate(input) as { resource: Resource };\n return result.resource;\n }\n\n /** Save a link to the Reading list: a `bookmark` in `to_read`, not embedded. */\n async save(input: {\n url: string;\n title?: string;\n note?: string;\n workspaceId?: string;\n readStatus?: ReadStatus;\n }): Promise<Resource> {\n return await this.create({\n title: input.title?.trim() || hostnameOf(input.url) || input.url,\n url: input.url,\n description: input.note,\n contentType: 'bookmark',\n readStatus: input.readStatus ?? 'to_read',\n generateEmbeddings: false,\n workspaceId: input.workspaceId,\n });\n }\n\n async setReadStatus(id: string, readStatus: ReadStatus): Promise<ResourceReadState> {\n return await this.client.resource.setReadStatus.mutate({ id, readStatus }) as ResourceReadState;\n }\n\n async archive(id: string): Promise<{ success: boolean }> {\n return await this.client.resource.archive.mutate({ id }) as { success: boolean };\n }\n}\n\nfunction hostnameOf(url: string): string | null {\n try {\n return new URL(url).hostname.replace(/^www\\./, '');\n } catch {\n return null;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Feature } from './types/feature.js';\nimport type { Requirement, RequirementKind } from './types/requirement.js';\n\nexport interface RequirementListOptions {\n featureId: string;\n /** Only requirements pinned to this scope. */\n scopeId?: string;\n}\n\nexport interface RequirementCreateInput {\n featureId: string;\n /** Pin the requirement to one of the feature's scopes. */\n scopeId?: string;\n /** One EARS-style \"shall\" statement. */\n statement: string;\n kind?: RequirementKind;\n}\n\n/**\n * Requirements on a feature (EARS-style \"shall\" statements, checkable\n * met/unmet). Replaces user stories as the requirements mechanism.\n *\n * Mirrors the `UserStoriesApi` shape: `list` derives from the feature's\n * `getById` payload, which includes `requirements` ordered by\n * `displayOrder` - there is no dedicated list procedure.\n */\nexport class RequirementsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: RequirementListOptions): Promise<Requirement[]> {\n const feature = await this.client.product.feature.getById.query({\n id: options.featureId,\n }) as Feature & { requirements?: Requirement[] };\n const requirements = feature.requirements ?? [];\n return options.scopeId\n ? requirements.filter((r) => r.scopeId === options.scopeId)\n : requirements;\n }\n\n async create(input: RequirementCreateInput): Promise<Requirement> {\n return await this.client.product.feature.addRequirement.mutate(\n input,\n ) as Requirement;\n }\n\n /** Mark a requirement met (true) or unmet (false). */\n async setChecked(id: string, checked: boolean): Promise<Requirement> {\n return await this.client.product.feature.setRequirementChecked.mutate({\n id,\n checked,\n }) as Requirement;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.deleteRequirement.mutate({\n id,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Feature, FeatureScope, FeatureScopeStatus } from './types/feature.js';\n\nexport interface ScopeListOptions {\n featureId: string;\n}\n\nexport interface ScopeCreateInput {\n featureId: string;\n /** Short label for the increment, e.g. \"V1\" or \"V2: auto-sync\". */\n version: string;\n description: string;\n status?: FeatureScopeStatus;\n shippedAt?: Date;\n}\n\nexport interface ScopeUpdateInput {\n id: string;\n version?: string;\n description?: string;\n status?: FeatureScopeStatus;\n shippedAt?: Date | null;\n displayOrder?: number;\n}\n\n/**\n * Feature scopes: shippable increments of a feature (\"V1\", \"V2\"), each with\n * its own lifecycle. Setting a scope SHIPPED stamps `shippedAt` server-side\n * and rolls the feature's status up (any live scope makes the feature Live).\n *\n * Mirrors the `UserStoriesApi` shape: `list` derives from the feature's\n * `getById` payload, which includes `scopes` ordered by `displayOrder` -\n * there is no dedicated list procedure.\n */\nexport class ScopesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ScopeListOptions): Promise<FeatureScope[]> {\n const feature = await this.client.product.feature.getById.query({\n id: options.featureId,\n }) as Feature & { scopes?: FeatureScope[] };\n return feature.scopes ?? [];\n }\n\n async create(input: ScopeCreateInput): Promise<FeatureScope> {\n return await this.client.product.feature.addScope.mutate(\n input,\n ) as FeatureScope;\n }\n\n async update(input: ScopeUpdateInput): Promise<FeatureScope> {\n return await this.client.product.feature.updateScope.mutate(\n input,\n ) as FeatureScope;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.deleteScope.mutate({\n id,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n GlobalSearchOptions,\n GlobalSearchOutput,\n KnowledgeSearchOptions,\n KnowledgeSearchOutput,\n} from './types/search.js';\n\nexport class SearchApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * Global text search across the entities the caller can access — the same\n * coverage as the app's Cmd+K palette (projects, actions, goals,\n * workspaces, and other entity types as the API grows). Matches titles;\n * for pages by meaning use `knowledge` or `PagesApi.search`.\n */\n async global(options: GlobalSearchOptions): Promise<GlobalSearchOutput> {\n return (await this.client.search.global.query(options)) as GlobalSearchOutput;\n }\n\n /**\n * Semantic search over one workspace's Knowledge index — the caller's own\n * indexed meetings, resources, documents and pages, scored by meaning. Each\n * source contributes its best-matching passage. Costs an embedding call;\n * never throws for an index failure (returns no results instead).\n */\n async knowledge(options: KnowledgeSearchOptions): Promise<KnowledgeSearchOutput> {\n return (await this.client.search.knowledge.query(options)) as KnowledgeSearchOutput;\n }\n}\n","import type { TrpcClient } from './client.js';\n\nexport type TimeEntryStatus = 'PROPOSED' | 'CONFIRMED';\n\n/**\n * Where an entry came from. `plugin` is the legacy stamp of the in-app Timer\n * and calendar grids; new writes use the other three. `claude-desktop` is\n * Proposed time from the Daily worklog, `agent-run` is Agent-run time (an\n * agent working with no human turns, kept off the owner's attention totals).\n */\nexport type TimeEntrySource = 'plugin' | 'manual' | 'claude-desktop' | 'agent-run';\n\nexport interface TimeEntry {\n id: string;\n /** Whose time it is. Under an agent key this is the agent's OWNER (ADR-0061). */\n userId: string;\n actionId: string;\n workspaceId: string | null;\n startedAt: Date;\n endedAt: Date | null;\n source: string;\n status: TimeEntryStatus;\n /** Idempotency key, e.g. `claude-session:<sessionId>#<segmentIndex>`. */\n sourceRef: string | null;\n note: string | null;\n /** The external agent that wrote the row; null for human-made entries. */\n createdByAgentId: string | null;\n action: {\n id: string;\n name: string;\n projectId: string | null;\n workspaceId: string | null;\n };\n}\n\nexport interface TimeLogInput {\n actionId: string;\n startedAt: Date;\n endedAt: Date;\n /** Defaults to `manual` server-side. */\n source?: Exclude<TimeEntrySource, 'plugin'>;\n /**\n * Ignored under an agent key: agent-written entries are always PROPOSED.\n * A human's entry defaults to CONFIRMED.\n */\n status?: TimeEntryStatus;\n /**\n * With a `sourceRef` the write is idempotent per owner: a re-run updates a\n * PROPOSED entry in place and leaves a CONFIRMED one alone.\n */\n sourceRef?: string;\n /** One line shown in the day view and list row (max 1000 chars). */\n note?: string;\n}\n\n/**\n * `created` / `updated` — proposed pieces were written; `left` — a CONFIRMED\n * row already carries this ref and was not touched; `merged` — manual time\n * on the same Action covers it, so the manual entries were annotated instead\n * (V2, manual wins); `dropped` — manual time on other Actions covered every\n * minute, nothing written.\n */\nexport type TimeLogOutcome = 'created' | 'updated' | 'left' | 'merged' | 'dropped';\n\nexport interface TimeLogResult {\n /** The first written piece, or the untouched CONFIRMED row; null for merged/dropped. */\n entry: TimeEntry | null;\n outcome: TimeLogOutcome;\n /** Every piece written — several when manual time on another Action split the proposal. */\n pieces?: TimeEntry[];\n /** Manual entry ids whose note now carries the conversation reference. */\n mergedInto?: string[];\n}\n\nexport interface DayReportEntry extends TimeEntry {\n /** Whole minutes inside the day window (a running entry ends \"now\"). */\n minutes: number;\n /** `ticket.productId ?? project.productId ?? null`. */\n productId: string | null;\n productName: string | null;\n isAgentRun: boolean;\n flags: Array<'forgotten-timer'>;\n action: TimeEntry['action'] & {\n ticketId: string | null;\n project: { id: string; name: string; productId: string | null } | null;\n ticket: { id: string; number: number; shortId: string | null; title: string; productId: string } | null;\n };\n}\n\nexport interface DayReportProductRow {\n /** Null is Unassigned time. */\n productId: string | null;\n name: string;\n /** Overlap-split minutes; the rows sum to `attentionMinutes`. */\n minutes: number;\n}\n\nexport interface DayReportActionRow {\n actionId: string;\n name: string;\n /** Overlap-split minutes; the rows sum to `attentionMinutes`. */\n minutes: number;\n /** Plain sum of the Action's non-agent-run entries. */\n sessionMinutes: number;\n agentRunMinutes: number;\n productId: string | null;\n productName: string | null;\n projectId: string | null;\n projectName: string | null;\n ticket: { id: string; number: number; shortId: string | null; title: string } | null;\n proposedCount: number;\n}\n\n/**\n * One day of a person's time — the same numbers the `/time` Day tab shows.\n * Attention minutes count each covered minute once; session minutes are the\n * plain sum; Agent-run time is kept off both and reported on its own.\n */\nexport interface DayReport {\n dayStart: Date;\n dayEnd: Date;\n entries: DayReportEntry[];\n attentionMinutes: number;\n sessionMinutes: number;\n agentRunMinutes: number;\n byProduct: DayReportProductRow[];\n byAction: DayReportActionRow[];\n /** Non-agent-run entries whose Action has neither Ticket nor Project. */\n unassignedCount: number;\n proposedCount: number;\n flags: Array<{ entryId: string; flag: 'forgotten-timer' }>;\n}\n\nexport interface TimeConfirmDayResult {\n /** Proposed entries flipped to CONFIRMED. */\n confirmed: number;\n}\n\nexport interface TimeLogBatchResult {\n index: number;\n success: boolean;\n sourceRef?: string;\n /** Null when the outcome is `merged` or `dropped`. */\n entry?: TimeEntry | null;\n outcome?: TimeLogOutcome;\n pieces?: TimeEntry[];\n mergedInto?: string[];\n error?: string;\n}\n\nfunction startOfLocalDay(date: Date | string): Date {\n const d =\n typeof date === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(date)\n ? new Date(`${date}T00:00:00`)\n : new Date(date);\n if (Number.isNaN(d.getTime())) {\n throw new Error(`Invalid date: \"${String(date)}\". Use YYYY-MM-DD or an ISO timestamp.`);\n }\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\n/**\n * Time entries — the Daily worklog's write path (ADR-0061).\n *\n * The thing to know: an entry always belongs to the person whose time it\n * was. Called with an external-agent key, {@link log} writes an entry OWNED\n * by the agent's owner, records the agent as author and forces it to\n * `PROPOSED`; it shows on the owner's `/time` with a \"proposed\" chip and\n * stays out of `Action.timeSpentMins` until the owner confirms the day.\n * Manual time is never altered by these calls.\n */\nexport class TimeApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * Log one completed entry with explicit bounds. Never starts, stops or\n * alters the running Timer. With `sourceRef` the call is an upsert keyed\n * on (owner, sourceRef); without it every call creates a row.\n */\n async log(input: TimeLogInput): Promise<TimeLogResult> {\n if (input.sourceRef) {\n return (await this.client.timeEntry.upsertBySourceRef.mutate({\n ...input,\n sourceRef: input.sourceRef,\n })) as TimeLogResult;\n }\n const entry = (await this.client.timeEntry.create.mutate(input)) as TimeEntry;\n return { entry, outcome: 'created', pieces: [entry], mergedInto: [] };\n }\n\n /**\n * Log many entries, one call each and in order, so a failure names the\n * entry it belonged to instead of rejecting the whole batch. `defaults`\n * fill any field an entry leaves out.\n */\n async logBatch(\n entries: Partial<TimeLogInput>[],\n defaults: Partial<TimeLogInput> = {},\n ): Promise<TimeLogBatchResult[]> {\n const results: TimeLogBatchResult[] = [];\n for (const [index, item] of entries.entries()) {\n const merged = { ...defaults, ...item };\n const sourceRef = merged.sourceRef;\n try {\n if (!merged.actionId) throw new Error('actionId is required');\n if (!merged.startedAt || !merged.endedAt) {\n throw new Error('startedAt and endedAt are required');\n }\n const result = await this.log(merged as TimeLogInput);\n results.push({ index, success: true, sourceRef, ...result });\n } catch (error) {\n results.push({\n index,\n success: false,\n sourceRef,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n return results;\n }\n\n /**\n * Confirm a day: every PROPOSED entry of yours that starts on that local\n * calendar day becomes CONFIRMED and the Actions' spent time moves. Human\n * only — the server refuses agent keys, so run this with personal\n * credentials. A day with nothing proposed returns `{ confirmed: 0 }`.\n */\n async confirmDay(date: Date | string, workspaceId?: string): Promise<TimeConfirmDayResult> {\n return (await this.client.timeEntry.confirmDay.mutate({\n date: startOfLocalDay(date),\n workspaceId,\n })) as TimeConfirmDayResult;\n }\n\n /**\n * The day report for one local calendar day: entries joined to Action,\n * Ticket, Project and Product, attention / session / agent-run minutes,\n * the overlap-split roll-ups and the counts — exactly what the `/time` Day\n * tab and the Daily summary's Yesterday line read. Under an agent key the\n * report is the OWNER's day.\n */\n async dayReport(date: Date | string, workspaceId?: string): Promise<DayReport> {\n return (await this.client.timeEntry.dayReport.query({\n date: startOfLocalDay(date),\n workspaceId,\n })) as DayReport;\n }\n\n /**\n * The caller's entries that touch one calendar day (local time), oldest\n * first, each with its `status`. Pass `YYYY-MM-DD` or a Date.\n */\n async list(date: Date | string, workspaceId?: string): Promise<TimeEntry[]> {\n const startDate = startOfLocalDay(date);\n const endDate = new Date(startDate.getTime() + 24 * 60 * 60 * 1000);\n return (await this.client.timeEntry.listByDateRange.query({\n startDate,\n endDate,\n workspaceId,\n })) as TimeEntry[];\n }\n}\n","import type { TrpcClient } from './client.js';\n\n/**\n * Agent runs — the local runner's side of an Assistant run (Exponential\n * ADR-0067, \"Local runner (V2) procedures\" in dev-docs/AGENT_RUNS.md).\n *\n * An Assistant whose executor is LOCAL_CLI is never run by the hosted\n * dispatcher: a process on its owner's machine claims the run with the\n * Assistant's `exp_agent_` key, does the work with the owner's own tools,\n * streams what it did as events, and finishes. Every method needs an\n * **agent-key** client (a personal token or a run token is FORBIDDEN), and\n * every run is resolved through the key's own agent — a run id alone never\n * reaches another agent's work.\n */\n\nexport type AgentRunStatus =\n | 'QUEUED'\n | 'RUNNING'\n | 'WAITING_ON_OWNER'\n | 'SUCCEEDED'\n | 'FAILED'\n | 'CANCELLED'\n | 'TIMED_OUT';\n\nexport type RunnerEventKind = 'status' | 'tool_call' | 'tool_result' | 'text' | 'log' | 'error';\n\n/** One line of a run's transcript. The runner numbers `seq` itself, from 1, monotonically. */\nexport interface RunnerEvent {\n seq: number;\n kind: RunnerEventKind;\n payload: Record<string, unknown>;\n}\n\n/** A chat-shaped message the runner feeds to its CLI: the persona, then the brief. */\nexport interface RunMessage {\n role: 'system' | 'user';\n content: string;\n}\n\n/** What `claim` hands the runner: the run, the action, the owner, and the exact persona + brief the hosted executor would use. */\nexport interface ClaimedRun {\n id: string;\n actionId: string;\n predecessorId: string | null;\n claimedBy: string | null;\n startedAt: Date | string | null;\n action: {\n id: string;\n name: string;\n description: string | null;\n workspaceId: string | null;\n project: { id: string; name: string } | null;\n };\n owner: { id: string; name: string | null };\n messages: RunMessage[];\n}\n\nexport interface HeartbeatResult {\n /** false — the run left RUNNING (a cancel): stop now. */\n ok: boolean;\n lastEventAt: Date | string | null;\n}\n\nexport interface AppendEventsResult {\n /** Rows actually inserted; a retried batch inserts only the seqs not yet stored. */\n inserted: number;\n newToolCalls: number;\n toolCallCount: number;\n}\n\nexport type FinishInput =\n | {\n status: 'SUCCEEDED';\n /** Public: the requester, the owner and their teammates read it. */\n summary?: string;\n readyToClose?: boolean;\n usage?: Record<string, unknown>;\n }\n | { status: 'FAILED'; error?: string; summary?: string; usage?: Record<string, unknown> }\n | {\n status: 'WAITING_ON_OWNER';\n /** Required: the app posts it as a comment mentioning the owner and parks the run. */\n question: string;\n summary?: string;\n usage?: Record<string, unknown>;\n };\n\nexport interface FinishResult {\n /** false — a cancel landed first; nothing was posted. */\n finished: boolean;\n status: AgentRunStatus;\n /** The ask-owner comment, for WAITING_ON_OWNER. */\n commentId?: string | null;\n}\n\nexport class AgentRunsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * Claim the oldest queued LOCAL_CLI run of this key's Assistant, or null when\n * nothing is queued. `runnerId` names this machine/process; it is recorded on\n * the run and checked by the other calls.\n */\n async claim(runnerId: string): Promise<ClaimedRun | null> {\n return (await this.client.agentRun.claim.mutate({ runnerId })) as ClaimedRun | null;\n }\n\n /** Keep the run alive while a step is slow (the app times out a silent run after 5 minutes). */\n async heartbeat(runId: string, runnerId?: string): Promise<HeartbeatResult> {\n return (await this.client.agentRun.heartbeat.mutate({ runId, runnerId })) as HeartbeatResult;\n }\n\n /**\n * Append transcript events (1–200 per call). Idempotent on `seq`, so a batch\n * may be retried after a network error without duplicating lines.\n */\n async appendEvents(runId: string, events: RunnerEvent[], runnerId?: string): Promise<AppendEventsResult> {\n return (await this.client.agentRun.appendEvents.mutate({ runId, runnerId, events })) as AppendEventsResult;\n }\n\n /** End the run: succeeded, failed, or waiting on the owner's answer to `question`. */\n async finish(runId: string, input: FinishInput, runnerId?: string): Promise<FinishResult> {\n return (await this.client.agentRun.finish.mutate({ runId, runnerId, ...input })) as FinishResult;\n }\n}\n","import Conf from 'conf';\n\nexport interface ExponentialConfig {\n apiUrl: string;\n token: string;\n tokenExpiry?: string;\n defaultWorkspaceId?: string;\n defaultWorkspaceSlug?: string;\n}\n\nconst schema = {\n apiUrl: {\n type: 'string' as const,\n default: '',\n },\n token: {\n type: 'string' as const,\n default: '',\n },\n tokenExpiry: {\n type: 'string' as const,\n default: '',\n },\n defaultWorkspaceId: {\n type: 'string' as const,\n default: '',\n },\n defaultWorkspaceSlug: {\n type: 'string' as const,\n default: '',\n },\n};\n\nfunction createStore(projectName: string) {\n return new Conf<ExponentialConfig>({\n projectName,\n schema,\n });\n}\n\nfunction readConfig(store: Conf<ExponentialConfig>): ExponentialConfig {\n return {\n apiUrl: store.get('apiUrl'),\n token: store.get('token'),\n tokenExpiry: store.get('tokenExpiry'),\n defaultWorkspaceId: store.get('defaultWorkspaceId'),\n defaultWorkspaceSlug: store.get('defaultWorkspaceSlug'),\n };\n}\n\nfunction writeConfig(store: Conf<ExponentialConfig>, values: Partial<ExponentialConfig>): void {\n if (values.apiUrl !== undefined) store.set('apiUrl', values.apiUrl);\n if (values.token !== undefined) store.set('token', values.token);\n if (values.tokenExpiry !== undefined) store.set('tokenExpiry', values.tokenExpiry);\n if (values.defaultWorkspaceId !== undefined) store.set('defaultWorkspaceId', values.defaultWorkspaceId);\n if (values.defaultWorkspaceSlug !== undefined) store.set('defaultWorkspaceSlug', values.defaultWorkspaceSlug);\n}\n\nconst defaultStore = createStore('exponential-sdk');\n\nexport function createConfigStore(options?: { projectName?: string }) {\n const store = createStore(options?.projectName ?? 'exponential-sdk');\n\n return {\n loadConfig: () => readConfig(store),\n saveConfig: (values: Partial<ExponentialConfig>) => writeConfig(store, values),\n clearConfig: () => store.clear(),\n isAuthenticated: () => {\n const cfg = readConfig(store);\n return Boolean(cfg.token && cfg.apiUrl);\n },\n getConfigPath: () => store.path,\n };\n}\n\nexport function loadConfig(): ExponentialConfig {\n return readConfig(defaultStore);\n}\n\nexport function saveConfig(values: Partial<ExponentialConfig>): void {\n writeConfig(defaultStore, values);\n}\n\nexport function clearConfig(): void {\n defaultStore.clear();\n}\n\nexport function isAuthenticated(): boolean {\n const cfg = readConfig(defaultStore);\n return Boolean(cfg.token && cfg.apiUrl);\n}\n\nexport function getConfigPath(): string {\n return defaultStore.path;\n}\n","/**\n * Worklog segments (CONTEXT.md \"Worklog segment\"): cut a conversation into\n * the stretches of a person's attention it actually held. Pure — it lives in\n * the SDK because the Daily worklog that needs it runs outside the app\n * (decision 2026-09-12).\n */\n\nexport interface ConversationMessage {\n at: Date | string;\n role: 'user' | 'assistant';\n}\n\nexport interface WorklogSegment {\n start: Date;\n end: Date;\n /** Number of the person's messages inside. `0` marks an Agent-run stretch. */\n humanTurns: number;\n}\n\n/** Silence between the person's messages that ends a segment. */\nexport const DEFAULT_GAP_MINUTES = 30;\n/** Segment bounds are rounded outward to this grain. */\nexport const ROUND_MINUTES = 5;\n\nfunction roundDown(ms: number): Date {\n const grain = ROUND_MINUTES * 60_000;\n return new Date(Math.floor(ms / grain) * grain);\n}\n\nfunction roundUp(ms: number): Date {\n const grain = ROUND_MINUTES * 60_000;\n return new Date(Math.ceil(ms / grain) * grain);\n}\n\n/**\n * Rules:\n * - a segment opens at a user message and, as long as the person keeps\n * replying within `gapMinutes` of their previous message, runs to the\n * last reply before the next gap (CONTEXT.md: \"starts at the person's\n * first message and ends at the last reply\");\n * - the exception is unattended work: once the assistant has been talking\n * alone for longer than `gapMinutes` since the person's last message, the\n * rest of that run — when it lasts longer than `gapMinutes` itself — is\n * a separate segment with `humanTurns: 0`, and the person's segment ends\n * at the last message inside the window. A shorter tail is just the reply\n * and stays in the person's segment — but only when it starts within\n * `gapMinutes` of the window closing (two gaps after the person's last\n * message). A short burst that comes later, e.g. the assistant speaking\n * just before the person resumes days afterwards, belongs to no segment;\n * - an agent-run ends at a silence longer than two gaps: whatever the\n * assistant says after it starts a new candidate run, so a Monitor ticking\n * every few hours is not one unbroken stretch. A shorter silence is a long\n * tool call inside the run;\n * - every segment is rounded outward to 5 minutes.\n */\nexport function segmentConversation(\n messages: ConversationMessage[],\n gapMinutes = DEFAULT_GAP_MINUTES,\n): WorklogSegment[] {\n const gapMs = gapMinutes * 60_000;\n const sorted = messages\n .map((m) => ({ at: new Date(m.at).getTime(), role: m.role }))\n .filter((m) => !Number.isNaN(m.at))\n .sort((a, b) => a.at - b.at);\n\n const out: WorklogSegment[] = [];\n let seg: { start: number; end: number; humanTurns: number; lastUserAt: number } | null = null;\n // Assistant messages beyond the person's window: a candidate agent-run.\n let run: { start: number; end: number } | null = null;\n\n const closeSegment = () => {\n if (seg) out.push({ start: roundDown(seg.start), end: roundUp(seg.end), humanTurns: seg.humanTurns });\n seg = null;\n };\n const resolveRun = () => {\n if (!run) return;\n if (run.end - run.start > gapMs) {\n closeSegment();\n out.push({ start: roundDown(run.start), end: roundUp(run.end), humanTurns: 0 });\n } else if (seg && run.start - seg.lastUserAt <= 2 * gapMs) {\n seg.end = Math.max(seg.end, run.end);\n }\n run = null;\n };\n\n for (const m of sorted) {\n if (m.role === 'user') {\n resolveRun();\n if (seg && m.at - seg.lastUserAt > gapMs) closeSegment();\n if (!seg) seg = { start: m.at, end: m.at, humanTurns: 0, lastUserAt: m.at };\n seg.end = Math.max(seg.end, m.at);\n seg.lastUserAt = m.at;\n seg.humanTurns += 1;\n continue;\n }\n if (run) {\n if (m.at - run.end > 2 * gapMs) {\n resolveRun();\n run = { start: m.at, end: m.at };\n } else {\n run.end = m.at;\n }\n } else if (!seg || m.at - seg.lastUserAt > gapMs) {\n run = { start: m.at, end: m.at };\n } else {\n seg.end = Math.max(seg.end, m.at);\n }\n }\n resolveRun();\n closeSegment();\n return out;\n}\n","import { createClient, isTRPCError, TRPCClientError, type TrpcClient } from './client.js';\nimport { ActionsApi } from './actions.js';\nimport { ActionCommentsApi } from './actionComments.js';\nimport { FeatureCommentsApi } from './featureComments.js';\nimport { PageCommentsApi } from './pageComments.js';\nimport { GoalCommentsApi } from './goalComments.js';\nimport { GoalsApi } from './goals.js';\nimport { KeyResultsApi } from './keyResults.js';\nimport { ProjectsApi } from './projects.js';\nimport { WorkspacesApi } from './workspaces.js';\nimport { ContactsApi } from './contacts.js';\nimport { DecisionsApi } from './decisions.js';\nimport { OrganizationsApi } from './organizations.js';\nimport { PipelinesApi } from './pipelines.js';\nimport { TicketsApi } from './tickets.js';\nimport { ProductsApi } from './products.js';\nimport { FeaturesApi } from './features.js';\nimport { UserStoriesApi } from './userStories.js';\nimport { EpicsApi } from './epics.js';\nimport { LabelsApi } from './labels.js';\nimport { AreasApi } from './areas.js';\nimport { MeetingsApi } from './meetings.js';\nimport { PagesApi } from './pages.js';\nimport { ResourcesApi } from './resources.js';\nimport { RequirementsApi } from './requirements.js';\nimport { ScopesApi } from './scopes.js';\nimport { SearchApi } from './search.js';\nimport { TimeApi } from './time.js';\nimport { AgentRunsApi } from './agentRuns.js';\n\nexport class ExponentialClient {\n private client: TrpcClient;\n actions: ActionsApi;\n actionComments: ActionCommentsApi;\n featureComments: FeatureCommentsApi;\n pageComments: PageCommentsApi;\n goalComments: GoalCommentsApi;\n goals: GoalsApi;\n /** Same instance as `goals.keyResults`. */\n keyResults: KeyResultsApi;\n projects: ProjectsApi;\n workspaces: WorkspacesApi;\n contacts: ContactsApi;\n decisions: DecisionsApi;\n organizations: OrganizationsApi;\n pipelines: PipelinesApi;\n tickets: TicketsApi;\n products: ProductsApi;\n features: FeaturesApi;\n userStories: UserStoriesApi;\n epics: EpicsApi;\n labels: LabelsApi;\n areas: AreasApi;\n meetings: MeetingsApi;\n pages: PagesApi;\n resources: ResourcesApi;\n requirements: RequirementsApi;\n scopes: ScopesApi;\n search: SearchApi;\n /** Time entries — the Daily worklog's write path (ADR-0061). */\n time: TimeApi;\n /** Agent runs — the local runner's claim/heartbeat/append/finish (ADR-0067); agent-key only. */\n agentRuns: AgentRunsApi;\n\n constructor(private config: { token: string; apiUrl: string }) {\n this.client = createClient(this.config);\n this.actions = new ActionsApi(this.client);\n this.actionComments = new ActionCommentsApi(this.client);\n this.featureComments = new FeatureCommentsApi(this.client);\n this.pageComments = new PageCommentsApi(this.client);\n this.goalComments = new GoalCommentsApi(this.client);\n this.keyResults = new KeyResultsApi(this.client);\n this.goals = new GoalsApi(this.client, this.keyResults);\n this.projects = new ProjectsApi(this.client);\n this.workspaces = new WorkspacesApi(this.client);\n this.contacts = new ContactsApi(this.client);\n this.decisions = new DecisionsApi(this.client);\n this.organizations = new OrganizationsApi(this.client);\n this.pipelines = new PipelinesApi(this.client);\n this.tickets = new TicketsApi(this.client);\n this.products = new ProductsApi(this.client);\n this.features = new FeaturesApi(this.client);\n this.userStories = new UserStoriesApi(this.client);\n this.epics = new EpicsApi(this.client);\n this.labels = new LabelsApi(this.client);\n this.areas = new AreasApi(this.client);\n this.meetings = new MeetingsApi(this.client);\n this.pages = new PagesApi(this.client);\n this.resources = new ResourcesApi(this.client);\n this.requirements = new RequirementsApi(this.client);\n this.scopes = new ScopesApi(this.client);\n this.search = new SearchApi(this.client);\n this.time = new TimeApi(this.client);\n this.agentRuns = new AgentRunsApi(this.client);\n }\n}\n\nexport {\n createConfigStore,\n loadConfig,\n saveConfig,\n clearConfig,\n isAuthenticated,\n getConfigPath,\n} from './config.js';\n\nexport type { ExponentialConfig } from './config.js';\nexport type {\n Action,\n ActionOutput,\n ActionsListOutput,\n KanbanStatus,\n Priority,\n} from './types/action.js';\nexport type {\n ActionCreateInput,\n ActionUpdateInput,\n ActionUpsertBySourceInput,\n ActionUpsertBySourceResult,\n ActionStatus,\n TodaysActions,\n TodaysActionsGroup,\n TodaysActionRow,\n OverdueTriage,\n OverdueCohort,\n OverdueTriageRow,\n} from './actions.js';\nexport type {\n Project,\n ProjectDetail,\n ProjectKeyResultLink,\n ProjectOutput,\n ProjectPriority,\n ProjectStatus,\n ProjectsListOutput,\n} from './types/project.js';\nexport type { ProjectUpdateInput, ProjectsListOptions } from './projects.js';\nexport type {\n Workspace,\n WorkspaceMember,\n WorkspaceOutput,\n WorkspacesListOutput,\n} from './types/workspace.js';\nexport type {\n Contact,\n ContactInteraction,\n ContactListOutput,\n InteractionType,\n InteractionDirection,\n} from './types/contact.js';\nexport type {\n ContactCreateInput,\n ContactUpdateInput,\n AddInteractionInput,\n ContactsListOptions,\n EnrichContactResult,\n} from './contacts.js';\nexport type {\n Organization,\n OrganizationListOutput,\n OrganizationSize,\n} from './types/organization.js';\nexport type {\n OrganizationCreateInput,\n OrganizationsListOptions,\n} from './organizations.js';\nexport type {\n Pipeline,\n PipelineStage,\n Deal,\n DealActivity,\n} from './types/pipeline.js';\nexport type {\n DealCreateInput,\n DealUpdateInput,\n DealMoveInput,\n} from './pipelines.js';\nexport type {\n ActionComment,\n TicketComment,\n FeatureComment,\n PageComment,\n GoalComment,\n CommentAuthor,\n} from './types/comment.js';\nexport type {\n ActionCommentAddInput,\n ActionCommentUpdateInput,\n} from './actionComments.js';\nexport type {\n FeatureCommentCreateInput,\n FeatureCommentReplyInput,\n FeatureCommentUpdateInput,\n FeatureCommentThreadInput,\n} from './featureComments.js';\nexport type {\n PageCommentCreateInput,\n PageCommentUpdateInput,\n} from './pageComments.js';\nexport type {\n GoalCommentAddInput,\n GoalCommentUpdateInput,\n} from './goalComments.js';\nexport type {\n Goal,\n GoalChildSummary,\n GoalHealth,\n GoalKeyResultSummary,\n GoalLifeDomain,\n GoalPeriod,\n GoalProjectSummary,\n GoalStats,\n GoalStatus,\n GoalTreeNode,\n GoalUserSummary,\n GoalWritableStatus,\n} from './types/goal.js';\nexport type {\n GoalListOptions,\n GoalTreeOptions,\n GoalCreateInput,\n GoalUpdateInput,\n GoalSetStatusInput,\n GoalSetParentInput,\n GoalStatsOptions,\n} from './goals.js';\nexport type {\n KeyResult,\n KeyResultCheckIn,\n KeyResultFeatureLink,\n KeyResultProjectLink,\n KeyResultStatus,\n KeyResultUnit,\n ObjectiveWithKeyResults,\n} from './types/keyResult.js';\nexport type {\n KeyResultListOptions,\n KeyResultByObjectiveOptions,\n KeyResultCreateInput,\n KeyResultUpdateInput,\n KeyResultCheckInInput,\n} from './keyResults.js';\nexport type { Product } from './types/product.js';\nexport type { ProductCreateInput, ProductUpdateInput } from './products.js';\nexport type {\n Feature,\n FeatureKeyResultLink,\n FeatureScope,\n FeatureScopeStatus,\n FeatureStatus,\n} from './types/feature.js';\nexport type {\n FeatureCreateInput,\n FeatureUpdateInput,\n FeatureListOptions,\n FeatureLinkPageInput,\n} from './features.js';\nexport type { Area, AreaListOptions, AreaCreateInput } from './areas.js';\nexport type {\n Decision,\n DecisionAdrRef,\n DecisionChainRef,\n DecisionDecider,\n DecisionEvidenceTurn,\n DecisionFeatureRef,\n DecisionLink,\n DecisionListRow,\n DecisionMeetingRef,\n DecisionOccurrenceRef,\n DecisionProductRef,\n DecisionProjectRef,\n DecisionReviewState,\n DecisionSource,\n DecisionStatus,\n DecisionTicketRef,\n DecisionUserRef,\n DraftDecisionsResult,\n MeetingDecisions,\n} from './types/decision.js';\nexport type {\n DecisionCreateInput,\n DecisionDeciderInput,\n DecisionListOptions,\n DecisionSetStatusInput,\n DecisionUpdateInput,\n} from './decisions.js';\nexport type {\n Meeting,\n MeetingActionSummary,\n MeetingParticipant,\n MeetingProjectRef,\n MeetingSourceIntegration,\n MeetingWorkspaceRef,\n} from './types/meeting.js';\nexport type {\n MeetingListOptions,\n MeetingTypeFilter,\n MeetingParticipantInput,\n MeetingCreateInput,\n MeetingUpdateInput,\n} from './meetings.js';\nexport type {\n KnowledgePage,\n PageGetFormat,\n PageOutlineEntry,\n PageRevision,\n PageRevisionKind,\n PageRevisionAuthor,\n PageRevisionDetail,\n PageHistory,\n PageDiff,\n PageDiffSide,\n PageSearchResult,\n PageSearchOutput,\n} from './types/page.js';\nexport type { Resource, ResourceContentType, ReadStatus } from './types/resource.js';\nexport type {\n ResourceListOptions,\n ResourceListResult,\n ResourceCreateInput,\n ResourceReadState,\n} from './resources.js';\nexport type {\n PageListOptions,\n PageGetOptions,\n PageSearchOptions,\n PageHistoryOptions,\n PageDiffOptions,\n PageRestoreOptions,\n PageCreateInput,\n PageUpdateInput,\n} from './pages.js';\nexport type { Requirement, RequirementKind } from './types/requirement.js';\nexport type {\n RequirementListOptions,\n RequirementCreateInput,\n} from './requirements.js';\nexport type {\n ScopeListOptions,\n ScopeCreateInput,\n ScopeUpdateInput,\n} from './scopes.js';\nexport type { UserStory } from './types/userStory.js';\nexport type {\n UserStoryCreateInput,\n UserStoryUpdateInput,\n UserStoryListOptions,\n} from './userStories.js';\nexport type {\n Ticket,\n TicketDetail,\n TicketAssignee,\n TicketDependencyEdge,\n TicketStatus,\n TicketType,\n} from './types/ticket.js';\nexport type {\n TicketListOptions,\n TicketCreateInput,\n TicketUpdateInput,\n TicketCommentAddInput,\n TicketCommentUpdateInput,\n TicketSearchOptions,\n} from './tickets.js';\nexport type { Epic, EpicStatus, EpicPriority } from './types/epic.js';\nexport type {\n EpicCreateInput,\n EpicUpdateInput,\n EpicListOptions,\n} from './epics.js';\nexport type {\n SearchResult,\n SearchResultType,\n SearchResultWorkspace,\n GlobalSearchOptions,\n GlobalSearchOutput,\n KnowledgeSourceType,\n KnowledgeSearchOptions,\n KnowledgeSearchResult,\n KnowledgeSearchOutput,\n} from './types/search.js';\nexport type { Tag, TagEntityType, TagListResult } from './types/tag.js';\nexport type {\n LabelListOptions,\n LabelCreateInput,\n SetEntityTagsInput,\n ListForEntityInput,\n SetEntityTagsResult,\n} from './labels.js';\nexport { isTRPCError, TRPCClientError };\nexport { TimeApi } from './time.js';\nexport type {\n TimeEntry,\n TimeEntryStatus,\n TimeEntrySource,\n TimeLogInput,\n TimeLogOutcome,\n TimeLogResult,\n TimeLogBatchResult,\n TimeConfirmDayResult,\n DayReport,\n DayReportEntry,\n DayReportProductRow,\n DayReportActionRow,\n} from './time.js';\nexport { segmentConversation, DEFAULT_GAP_MINUTES, ROUND_MINUTES } from './segment.js';\nexport type { ConversationMessage, WorklogSegment } from './segment.js';\nexport { AgentRunsApi } from './agentRuns.js';\nexport type {\n AgentRunStatus,\n RunnerEventKind,\n RunnerEvent,\n RunMessage,\n ClaimedRun,\n HeartbeatResult,\n AppendEventsResult,\n FinishInput,\n FinishResult,\n} from './agentRuns.js';\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts","../src/actions.ts","../src/actionComments.ts","../src/featureComments.ts","../src/pageComments.ts","../src/goalComments.ts","../src/goals.ts","../src/keyResults.ts","../src/projects.ts","../src/workspaces.ts","../src/contacts.ts","../src/decisions.ts","../src/organizations.ts","../src/pipelines.ts","../src/tickets.ts","../src/products.ts","../src/features.ts","../src/userStories.ts","../src/epics.ts","../src/labels.ts","../src/areas.ts","../src/meetings.ts","../src/pages.ts","../src/resources.ts","../src/requirements.ts","../src/scopes.ts","../src/search.ts","../src/time.ts","../src/agentRuns.ts","../src/config.ts","../src/segment.ts","../src/index.ts"],"sourcesContent":["import { createTRPCClient, httpBatchLink, TRPCClientError } from '@trpc/client';\nimport superjson from 'superjson';\n\ntype ActionInput = {\n assigneeId?: string;\n};\n\ntype KanbanInput = {\n projectId?: string;\n assigneeId?: string;\n kanbanStatus?: 'BACKLOG' | 'TODO' | 'IN_PROGRESS' | 'IN_REVIEW' | 'DONE' | 'CANCELLED';\n};\n\ntype TodayInput = {\n workspaceId?: string;\n};\n\ntype DateRangeInput = {\n startDate: Date;\n endDate: Date;\n workspaceId?: string;\n};\n\ntype ProjectInput = {\n include?: {\n actions?: boolean;\n };\n workspaceId?: string;\n};\n\n/**\n * `project.update` as the server declares it: `name`, `status` and `priority`\n * are REQUIRED on every call, the rest are optional and only written when\n * present. `ProjectsApi.update` fills the required three from the current\n * project so callers can still pass a partial.\n */\ntype ProjectUpdateApiInput = {\n id: string;\n name: string;\n status: 'ACTIVE' | 'ON_HOLD' | 'COMPLETED' | 'CANCELLED';\n priority: 'HIGH' | 'MEDIUM' | 'LOW' | 'NONE';\n description?: string;\n productId?: string | null;\n workspaceId?: string | null;\n driId?: string | null;\n goalIds?: string[];\n outcomeIds?: string[];\n keyResultIds?: string[];\n lifeDomainIds?: number[];\n reviewDate?: Date | null;\n nextActionDate?: Date | null;\n startDate?: Date | null;\n endDate?: Date | null;\n};\n\ntype ActionStatus = 'ACTIVE' | 'COMPLETED' | 'CANCELLED' | 'DELETED' | 'DRAFT';\ntype ActionKanbanStatus = 'BACKLOG' | 'TODO' | 'IN_PROGRESS' | 'IN_REVIEW' | 'DONE' | 'CANCELLED';\ntype ActionPriority = 'Quick' | 'Scheduled' | '1st Priority' | '2nd Priority' | '3rd Priority' | '4th Priority' | '5th Priority' | 'Errand' | 'Remember' | 'Watch' | 'Someday Maybe';\n\ntype ActionCreateInput = {\n name: string;\n description?: string;\n projectId?: string;\n workspaceId?: string;\n dueDate?: Date;\n scheduledStart?: Date;\n scheduledEnd?: Date;\n duration?: number;\n priority?: ActionPriority;\n status?: ActionStatus;\n epicId?: string;\n effortEstimate?: number;\n blockedByIds?: string[];\n};\n\n// ── Goals (objectives) and key results ──────────────────────────────────────\n// Objectives are `Goal` rows with INTEGER ids; key results are `KeyResult` rows\n// with cuid ids. `period` is a free-form string (\"Q3-2026\", \"Annual-2026\").\n\ntype GoalStatusInput = 'planned' | 'active' | 'completed' | 'archived';\n/** Reads and `updateGoalStatus` also accept `on-hold`; `updateGoal` does not. */\ntype GoalQueryStatusInput = GoalStatusInput | 'on-hold';\n\ntype GoalCreateProcedureInput = {\n title: string;\n description?: string;\n whyThisGoal?: string;\n notes?: string;\n dueDate?: Date;\n period?: string;\n status?: GoalStatusInput;\n lifeDomainId?: number;\n projectId?: string;\n outcomeIds?: string[];\n driUserId?: string;\n workspaceId?: string;\n parentGoalId?: number;\n icon?: string | null;\n iconColor?: string | null;\n};\n\ntype GoalUpdateProcedureInput = {\n id: number;\n title?: string;\n description?: string | null;\n whyThisGoal?: string | null;\n notes?: string | null;\n dueDate?: Date | null;\n period?: string | null;\n status?: GoalStatusInput;\n lifeDomainId?: number | null;\n projectId?: string | null;\n projectIds?: string[];\n outcomeIds?: string[];\n driUserId?: string | null;\n workspaceId?: string | null;\n parentGoalId?: number | null;\n displayOrder?: number;\n icon?: string | null;\n iconColor?: string | null;\n};\n\ntype KeyResultStatusInput =\n | 'not-started'\n | 'on-track'\n | 'at-risk'\n | 'off-track'\n | 'achieved';\n\ntype KeyResultUnitInput = 'percent' | 'count' | 'currency' | 'hours' | 'custom';\n\ntype KeyResultCreateProcedureInput = {\n goalId: number;\n title: string;\n description?: string;\n targetValue: number;\n startValue?: number;\n currentValue?: number;\n unit?: KeyResultUnitInput;\n unitLabel?: string;\n period: string;\n periodStart?: Date;\n periodEnd?: Date;\n driUserId?: string;\n workspaceId?: string;\n};\n\ntype KeyResultUpdateProcedureInput = {\n id: string;\n title?: string;\n description?: string;\n targetValue?: number;\n currentValue?: number;\n startValue?: number;\n unit?: KeyResultUnitInput;\n unitLabel?: string;\n status?: KeyResultStatusInput;\n confidence?: number;\n driUserId?: string;\n goalId?: number;\n};\n\ntype ActionUpdateInput = {\n id: string;\n name?: string;\n description?: string;\n projectId?: string;\n workspaceId?: string | null;\n dueDate?: Date | null;\n scheduledStart?: Date | null;\n scheduledEnd?: Date | null;\n duration?: number | null;\n priority?: ActionPriority;\n status?: ActionStatus;\n kanbanStatus?: ActionKanbanStatus;\n epicId?: string | null;\n effortEstimate?: number | null;\n blockedByIds?: string[];\n};\n\ntype MeetingParticipantPersonInput = {\n userId?: string;\n contactId?: string;\n email?: string;\n name?: string;\n};\n\ntype MeetingCreateProcedureInput = {\n title: string;\n transcription: string;\n description?: string;\n notes?: string;\n meetingDate?: Date;\n projectId?: string;\n workspaceId?: string;\n participants?: MeetingParticipantPersonInput[];\n};\n\ntype MeetingUpdateDetailsProcedureInput = {\n id: string;\n description?: string;\n notes?: string;\n summary?: string;\n transcription?: string;\n workspaceId?: string | null;\n meetingDate?: Date | null;\n};\n\n// ── Decisions (ADR-0060) ────────────────────────────────────────────────────\n// One model behind both meeting panels: an OPEN QUESTION is a decision whose\n// status is `OPEN`. Every procedure is workspace-scoped except\n// `listForMeeting`, which resolves the workspace from the meeting.\n\ntype DecisionStatusInput =\n | 'OPEN'\n | 'PROPOSED'\n | 'ACCEPTED'\n | 'SUPERSEDED'\n | 'DEPRECATED';\n\ntype DecisionSourceInput = 'MEETING' | 'MANUAL' | 'AGENT';\n\ntype DecisionEvidenceInput = {\n turnIndex: number;\n speaker?: string | null;\n startTime?: number | null;\n text: string;\n};\n\ntype DecisionDeciderProcedureInput = {\n userId?: string | null;\n name: string;\n email?: string | null;\n};\n\ntype DecisionCreateProcedureInput = {\n workspaceId: string;\n statement: string;\n body?: string | null;\n status?: DecisionStatusInput;\n source?: DecisionSourceInput;\n decidedAt?: Date | null;\n ownerId?: string | null;\n transcriptionSessionId?: string | null;\n occurrenceId?: string | null;\n productId?: string | null;\n projectId?: string | null;\n goalId?: number | null;\n keyResultId?: string | null;\n deciders?: DecisionDeciderProcedureInput[];\n evidence?: DecisionEvidenceInput[];\n};\n\ntype DecisionUpdateProcedureInput = {\n workspaceId: string;\n decisionId: string;\n statement?: string;\n body?: string | null;\n decidedAt?: Date | null;\n ownerId?: string | null;\n productId?: string | null;\n projectId?: string | null;\n goalId?: number | null;\n keyResultId?: string | null;\n adrDocumentId?: string | null;\n};\n\ntype ActionUpsertBySourceInput = {\n sourceType: string;\n sourceId: string;\n name: string;\n workspaceId: string;\n description?: string;\n projectId?: string | null;\n ticketId?: string | null;\n};\n\ntype TimeEntryCreateInput = {\n actionId: string;\n startedAt: Date;\n endedAt: Date;\n source?: 'manual' | 'claude-desktop' | 'agent-run';\n status?: 'PROPOSED' | 'CONFIRMED';\n sourceRef?: string;\n note?: string;\n};\n\nexport interface TrpcClient {\n transcription: {\n getAllTranscriptions: {\n query: (input?: {\n includeArchived?: boolean;\n workspaceId?: string;\n meetingType?: 'all' | 'mine' | 'one_on_one' | 'customer' | 'internal';\n }) => Promise<unknown[]>;\n };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n createManualTranscription: {\n mutate: (input: MeetingCreateProcedureInput) => Promise<unknown>;\n };\n updateDetails: {\n mutate: (input: MeetingUpdateDetailsProcedureInput) => Promise<unknown>;\n };\n updateTitle: {\n mutate: (input: { id: string; title: string }) => Promise<unknown>;\n };\n deleteTranscription: {\n mutate: (input: { id: string }) => Promise<unknown>;\n };\n bulkDeleteTranscriptions: {\n mutate: (input: { ids: string[] }) => Promise<unknown>;\n };\n };\n search: {\n global: {\n query: (input: { query: string; workspaceId?: string; limit?: number }) => Promise<unknown>;\n };\n knowledge: {\n query: (input: {\n query: string;\n workspaceId: string;\n limit?: number;\n sourceTypes?: ('transcription' | 'resource' | 'document' | 'page')[];\n }) => Promise<unknown>;\n };\n };\n action: {\n getAll: { query: (input?: ActionInput) => Promise<unknown[]> };\n getKanbanActions: { query: (input?: KanbanInput) => Promise<unknown[]> };\n getToday: { query: (input?: TodayInput) => Promise<unknown[]> };\n getTodaysActions: { query: (input?: TodayInput) => Promise<unknown> };\n getOverdueTriage: { query: (input?: TodayInput) => Promise<unknown> };\n getByDateRange: { query: (input: DateRangeInput) => Promise<unknown[]> };\n getProjectActions: { query: (input: { projectId: string; assigneeId?: string }) => Promise<unknown[]> };\n create: { mutate: (input: ActionCreateInput) => Promise<unknown> };\n update: { mutate: (input: ActionUpdateInput) => Promise<unknown> };\n /** Idempotent create keyed on (workspaceId, sourceType, sourceId). */\n upsertBySource: { mutate: (input: ActionUpsertBySourceInput) => Promise<unknown> };\n bulkReschedule: { mutate: (input: { actionIds: string[]; dueDate: Date | null }) => Promise<unknown> };\n bulkDefer: { mutate: (input: { actionIds: string[] }) => Promise<unknown> };\n };\n project: {\n getAll: { query: (input?: ProjectInput) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n update: { mutate: (input: ProjectUpdateApiInput) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n workspace: {\n list: { query: () => Promise<unknown[]> };\n listMembers: { query: (input: { workspaceId: string }) => Promise<unknown[]> };\n };\n goal: {\n getById: { query: (input: { id: number }) => Promise<unknown> };\n getAllMyGoals: {\n query: (input?: {\n workspaceId?: string;\n period?: string;\n status?: GoalQueryStatusInput;\n }) => Promise<unknown[]>;\n };\n getGoalTree: {\n query: (input?: {\n workspaceId?: string;\n status?: GoalQueryStatusInput;\n }) => Promise<unknown[]>;\n };\n getProjectGoals: { query: (input: { projectId: string }) => Promise<unknown[]> };\n createGoal: { mutate: (input: GoalCreateProcedureInput) => Promise<unknown> };\n /**\n * Partial update — only the keys present are written, and an explicit null\n * clears. Every nullable field is therefore `T | null | undefined`.\n */\n updateGoal: { mutate: (input: GoalUpdateProcedureInput) => Promise<unknown> };\n /** Status-only write; the only path that accepts `on-hold`. */\n updateGoalStatus: {\n mutate: (input: { id: number; status: GoalQueryStatusInput }) => Promise<unknown>;\n };\n /** Single-column re-parent; validates no-self / no-cycle / depth-5. */\n setParent: {\n mutate: (input: { id: number; parentGoalId: number | null }) => Promise<unknown>;\n };\n deleteGoal: { mutate: (input: { id: number }) => Promise<unknown> };\n };\n // Mounted at `okr`, but this is the KEY RESULT router — objectives live on\n // `goal` above. Key results are cuid-keyed; the `goalId` linking them to an\n // objective is an integer.\n okr: {\n getAll: {\n query: (input?: {\n workspaceId?: string;\n goalId?: number;\n period?: string;\n status?: KeyResultStatusInput;\n onlyMine?: boolean;\n }) => Promise<unknown[]>;\n };\n getByObjective: {\n query: (input: {\n workspaceId?: string;\n period?: string;\n includePairedPeriod?: boolean;\n onlyMine?: boolean;\n }) => Promise<unknown[]>;\n };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n getByIds: { query: (input: { ids: string[] }) => Promise<unknown[]> };\n create: { mutate: (input: KeyResultCreateProcedureInput) => Promise<unknown> };\n update: { mutate: (input: KeyResultUpdateProcedureInput) => Promise<unknown> };\n checkIn: {\n mutate: (input: {\n keyResultId: string;\n newValue: number;\n notes?: string;\n }) => Promise<unknown>;\n };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n linkProject: {\n mutate: (input: { keyResultId: string; projectId: string }) => Promise<unknown>;\n };\n unlinkProject: {\n mutate: (input: { keyResultId: string; projectId: string }) => Promise<unknown>;\n };\n linkFeature: {\n mutate: (input: { keyResultId: string; featureId: string }) => Promise<unknown>;\n };\n unlinkFeature: {\n mutate: (input: { keyResultId: string; featureId: string }) => Promise<unknown>;\n };\n getPeriods: { query: () => Promise<unknown[]> };\n getStats: {\n query: (input: { workspaceId?: string; period?: string }) => Promise<unknown>;\n };\n };\n goalComment: {\n getComments: { query: (input: { goalId: number }) => Promise<unknown[]> };\n addComment: { mutate: (input: { goalId: number; content: string; parentUpdateId?: string }) => Promise<unknown> };\n updateComment: { mutate: (input: { commentId: string; content: string }) => Promise<unknown> };\n deleteComment: { mutate: (input: { commentId: string }) => Promise<unknown> };\n };\n pageComment: {\n list: { query: (input: { pageId: string }) => Promise<unknown[]> };\n create: { mutate: (input: { pageId: string; body: string }) => Promise<unknown> };\n update: { mutate: (input: { commentId: string; body: string }) => Promise<unknown> };\n delete: { mutate: (input: { commentId: string }) => Promise<unknown> };\n };\n /** Local-runner side of Agent runs (ADR-0067); agent-key principals only. */\n agentRun: {\n claim: { mutate: (input: { runnerId: string }) => Promise<unknown> };\n heartbeat: { mutate: (input: { runId: string; runnerId?: string }) => Promise<unknown> };\n appendEvents: {\n mutate: (input: {\n runId: string;\n runnerId?: string;\n events: Array<{ seq: number; kind: string; payload: Record<string, unknown> }>;\n }) => Promise<unknown>;\n };\n finish: {\n mutate: (input: {\n runId: string;\n runnerId?: string;\n status: 'SUCCEEDED' | 'FAILED' | 'WAITING_ON_OWNER';\n summary?: string;\n readyToClose?: boolean;\n error?: string;\n usage?: Record<string, unknown>;\n question?: string;\n }) => Promise<unknown>;\n };\n };\n timeEntry: {\n /** Explicit-bounds entry; never touches the running Timer (ADR-0061). */\n create: { mutate: (input: TimeEntryCreateInput) => Promise<unknown> };\n upsertBySourceRef: {\n mutate: (input: TimeEntryCreateInput & { sourceRef: string }) => Promise<unknown>;\n };\n listByDateRange: {\n query: (input: { startDate: Date; endDate: Date; workspaceId?: string | null }) => Promise<unknown[]>;\n };\n /** Human-only; `date` is the start of the day in the caller's timezone. */\n confirmDay: {\n mutate: (input: { date: Date; workspaceId?: string | null }) => Promise<unknown>;\n };\n /** `date` is the start of the day in the caller's timezone; an agent key reads its owner's day. */\n dayReport: {\n query: (input: { date: Date; workspaceId?: string | null }) => Promise<unknown>;\n };\n };\n decision: {\n list: {\n query: (input: {\n workspaceId: string;\n statuses?: DecisionStatusInput[];\n sources?: DecisionSourceInput[];\n /** A product id, or \"workspace\" for decisions with no product. */\n productId?: string;\n includeWorkspaceWide?: boolean;\n projectId?: string;\n search?: string;\n /** One decision by its workspace sequence number — `D-0003` → 3. */\n number?: number;\n limit?: number;\n }) => Promise<unknown[]>;\n };\n get: {\n query: (input: { workspaceId: string; decisionId: string }) => Promise<unknown>;\n };\n /** Workspace comes from the meeting; drafts included for meeting editors. */\n listForMeeting: {\n query: (input: { transcriptionSessionId: string }) => Promise<unknown>;\n };\n listForAdr: {\n query: (input: { workspaceId: string; adrDocumentId: string }) => Promise<unknown[]>;\n };\n /** Extract draft decisions from a meeting's notes and transcript. */\n extractDrafts: {\n mutate: (input: { transcriptionSessionId: string }) => Promise<unknown>;\n };\n create: { mutate: (input: DecisionCreateProcedureInput) => Promise<unknown> };\n update: { mutate: (input: DecisionUpdateProcedureInput) => Promise<unknown> };\n setStatus: {\n mutate: (input: {\n workspaceId: string;\n decisionId: string;\n status: DecisionStatusInput;\n supersededById?: string | null;\n }) => Promise<unknown>;\n };\n linkTicket: {\n mutate: (input: { workspaceId: string; decisionId: string; ticketId: string }) => Promise<unknown>;\n };\n linkFeature: {\n mutate: (input: { workspaceId: string; decisionId: string; featureId: string }) => Promise<unknown>;\n };\n /** `linkId` is the DecisionLink id, not the ticket or feature id. */\n unlink: {\n mutate: (input: { workspaceId: string; linkId: string }) => Promise<unknown>;\n };\n confirmDraft: {\n mutate: (input: { workspaceId: string; decisionId: string }) => Promise<unknown>;\n };\n rejectDraft: {\n mutate: (input: { workspaceId: string; decisionId: string }) => Promise<unknown>;\n };\n deleteDraft: {\n mutate: (input: { workspaceId: string; decisionId: string }) => Promise<unknown>;\n };\n };\n crmApi: {\n contactList: { query: (input: { workspaceId: string; search?: string; tags?: string[]; organizationId?: string; limit?: number; cursor?: string }) => Promise<unknown> };\n contactGet: { query: (input: { id: string; includeInteractions?: boolean }) => Promise<unknown> };\n contactCreate: { mutate: (input: { workspaceId: string; firstName?: string; lastName?: string; email?: string | null; phone?: string; linkedIn?: string; telegram?: string; twitter?: string; github?: string; bluesky?: string; about?: string; profileType?: string; skills?: string[]; tags?: string[]; organizationId?: string; organizationName?: string }) => Promise<unknown> };\n contactUpdate: { mutate: (input: { id: string; firstName?: string; lastName?: string; email?: string | null; phone?: string | null; linkedIn?: string | null; telegram?: string | null; twitter?: string | null; github?: string | null; bluesky?: string | null; about?: string; profileType?: string; skills?: string[]; tags?: string[]; organizationId?: string | null; organizationName?: string }) => Promise<unknown> };\n contactDelete: { mutate: (input: { id: string }) => Promise<unknown> };\n contactAddInteraction: { mutate: (input: { contactId: string; type: string; direction: string; subject?: string; notes?: string; metadata?: unknown }) => Promise<unknown> };\n contactEnrich: { mutate: (input: { contactId: string }) => Promise<unknown> };\n organizationList: { query: (input: { workspaceId: string; search?: string; industry?: string; limit?: number; cursor?: string }) => Promise<unknown> };\n organizationGet: { query: (input: { id: string }) => Promise<unknown> };\n organizationCreate: { mutate: (input: { workspaceId: string; name: string; websiteUrl?: string | null; logoUrl?: string | null; description?: string; industry?: string; size?: string }) => Promise<unknown> };\n pipelineGet: { query: (input: { workspaceId: string }) => Promise<unknown> };\n pipelineGetStages: { query: (input: { workspaceId: string }) => Promise<unknown[]> };\n dealList: { query: (input: { workspaceId: string }) => Promise<unknown[]> };\n dealGet: { query: (input: { id: string }) => Promise<unknown> };\n dealCreate: { mutate: (input: { workspaceId: string; stageId: string; title: string; description?: string; value?: number; currency?: string; probability?: number; expectedCloseDate?: Date; contactId?: string; organizationId?: string; assignedToId?: string }) => Promise<unknown> };\n dealUpdate: { mutate: (input: { id: string; title?: string; description?: string | null; value?: number | null; currency?: string; probability?: number | null; expectedCloseDate?: Date | null; contactId?: string | null; organizationId?: string | null; assignedToId?: string | null }) => Promise<unknown> };\n dealMove: { mutate: (input: { id: string; stageId: string; stageOrder: number }) => Promise<unknown> };\n dealDelete: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n actionComment: {\n getComments: { query: (input: { actionId: string }) => Promise<unknown[]> };\n addComment: { mutate: (input: { actionId: string; content: string }) => Promise<unknown> };\n updateComment: { mutate: (input: { commentId: string; content: string }) => Promise<unknown> };\n deleteComment: { mutate: (input: { commentId: string }) => Promise<unknown> };\n };\n page: {\n list: { query: (input: { workspaceId: string; projectId?: string; search?: string }) => Promise<unknown[]> };\n get: { query: (input: { id: string; format?: 'full' | 'markdown' | 'outline'; section?: string }) => Promise<unknown> };\n search: { query: (input: { workspaceId: string; query: string; projectId?: string; limit?: number }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; projectId?: string | null; title?: string; body?: string; includeInSearch?: boolean; note?: string; source?: string | null; asOf?: Date | null }) => Promise<unknown> };\n update: { mutate: (input: { id: string; title?: string; projectId?: string | null; includeInSearch?: boolean; body?: string; baseVersion?: number; note?: string; source?: string | null; asOf?: Date | null }) => Promise<unknown> };\n history: { query: (input: { id: string; limit?: number; cursor?: string }) => Promise<unknown> };\n revision: { query: (input: { id: string; revisionId: string }) => Promise<unknown> };\n diff: { query: (input: { id: string; revisionId: string; against?: string }) => Promise<unknown> };\n restore: { mutate: (input: { id: string; revisionId: string; note?: string; baseVersion?: number }) => Promise<unknown> };\n };\n resource: {\n list: { query: (input: { workspaceId?: string; projectId?: string; contentType?: string; readStatus?: string; search?: string; tags?: string[]; includeArchived?: boolean; limit?: number; cursor?: string }) => Promise<unknown> };\n create: { mutate: (input: { title: string; url?: string; description?: string; content?: string; contentType?: string; tags?: string[]; workspaceId?: string; projectId?: string; readStatus?: string; generateEmbeddings?: boolean }) => Promise<unknown> };\n get: { query: (input: { id: string }) => Promise<unknown> };\n update: { mutate: (input: { id: string; title?: string; description?: string; tags?: string[]; readStatus?: string }) => Promise<unknown> };\n setReadStatus: { mutate: (input: { id: string; readStatus: string }) => Promise<unknown> };\n archive: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n epic: {\n list: { query: (input: { workspaceId: string; status?: 'OPEN' | 'IN_PROGRESS' | 'DONE' | 'CANCELLED' }) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; name: string; description?: string; priority?: 'HIGH' | 'MEDIUM' | 'LOW' | 'NONE'; startDate?: Date; targetDate?: Date }) => Promise<unknown> };\n update: { mutate: (input: { id: string; name?: string; description?: string | null; status?: 'OPEN' | 'IN_PROGRESS' | 'DONE' | 'CANCELLED'; priority?: 'HIGH' | 'MEDIUM' | 'LOW' | 'NONE'; startDate?: Date | null; targetDate?: Date | null }) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n tag: {\n list: { query: (input?: { workspaceId?: string; category?: string | null }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; name: string; color: string; description?: string; category?: string | null }) => Promise<unknown> };\n setEntityTags: { mutate: (input: { entityType: 'action' | 'ticket' | 'feature' | 'epic'; entityId: string; tagIds: string[] }) => Promise<unknown> };\n listForEntity: { query: (input: { entityType: 'action' | 'ticket' | 'feature' | 'epic'; entityId: string }) => Promise<unknown[]> };\n };\n product: {\n product: {\n list: { query: (input: { workspaceId: string }) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n getBySlug: { query: (input: { workspaceId: string; slug: string }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; name: string; slug: string; description?: string; icon?: string; color?: string }) => Promise<unknown> };\n update: { mutate: (input: { id: string; name?: string; description?: string; icon?: string; color?: string; funTicketIds?: boolean }) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n };\n featureComment: {\n list: { query: (input: { featureId: string }) => Promise<unknown[]> };\n create: { mutate: (input: { featureId: string; scopeId?: string; threadId?: string; body: string; quotedText?: string }) => Promise<unknown> };\n reply: { mutate: (input: { parentId: string; body: string }) => Promise<unknown> };\n update: { mutate: (input: { commentId: string; body: string }) => Promise<unknown> };\n delete: { mutate: (input: { commentId: string }) => Promise<unknown> };\n resolve: { mutate: (input: { featureId: string; threadId: string }) => Promise<unknown> };\n unresolve: { mutate: (input: { featureId: string; threadId: string }) => Promise<unknown> };\n };\n feature: {\n list: { query: (input: { productId: string; status?: 'IDEA' | 'DEFINED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED' | 'ARCHIVED' }) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n create: { mutate: (input: { productId: string; name: string; description?: string; vision?: string; status?: 'IDEA' | 'DEFINED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED' | 'ARCHIVED'; effort?: number; priority?: number; goalId?: number; areaId?: string }) => Promise<unknown> };\n update: { mutate: (input: { id: string; name?: string; description?: string; vision?: string; status?: 'IDEA' | 'DEFINED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED' | 'ARCHIVED'; effort?: number; priority?: number; goalId?: number | null; areaId?: string | null }) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n addUserStory: { mutate: (input: { featureId: string; scopeId?: string; asA?: string; iWant?: string; soThat?: string; acceptanceCriteria?: string }) => Promise<unknown> };\n updateUserStory: { mutate: (input: { id: string; scopeId?: string | null; asA?: string; iWant?: string; soThat?: string; acceptanceCriteria?: string }) => Promise<unknown> };\n deleteUserStory: { mutate: (input: { id: string }) => Promise<unknown> };\n addScope: { mutate: (input: { featureId: string; version: string; description: string; status?: 'PLANNED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED'; shippedAt?: Date }) => Promise<unknown> };\n updateScope: { mutate: (input: { id: string; version?: string; description?: string; status?: 'PLANNED' | 'IN_PROGRESS' | 'SHIPPED' | 'DEPRECATED'; shippedAt?: Date | null; displayOrder?: number }) => Promise<unknown> };\n deleteScope: { mutate: (input: { id: string }) => Promise<unknown> };\n addRequirement: { mutate: (input: { featureId: string; scopeId?: string; statement: string; kind?: 'FUNCTIONAL' | 'NON_FUNCTIONAL' | 'CONSTRAINT' }) => Promise<unknown> };\n setRequirementChecked: { mutate: (input: { id: string; checked: boolean }) => Promise<unknown> };\n deleteRequirement: { mutate: (input: { id: string }) => Promise<unknown> };\n linkPage: { mutate: (input: { featureId: string; pageId: string; scopeId?: string }) => Promise<unknown> };\n unlinkPage: { mutate: (input: { featureId: string; pageId: string }) => Promise<unknown> };\n listAreas: { query: (input: { productId: string }) => Promise<unknown[]> };\n createArea: { mutate: (input: { productId: string; name: string; description?: string }) => Promise<unknown> };\n };\n ticket: {\n list: { query: (input: { productId?: string; status?: string; type?: string; featureId?: string; epicId?: string; cycleId?: string; assigneeId?: string; prUrl?: string; branchName?: string }) => Promise<unknown[]> };\n getById: { query: (input: { id: string }) => Promise<unknown> };\n create: { mutate: (input: { productId: string; title: string; body?: string; type?: string; status?: string; priority?: number; points?: number; branchName?: string; prUrl?: string; designUrl?: string; specUrl?: string; links?: Record<string, string>; epicId?: string; featureId?: string; cycleId?: string; scopeId?: string; assigneeId?: string; templateId?: string }) => Promise<unknown> };\n update: { mutate: (input: { id: string; title?: string; body?: string; type?: string; status?: string; priority?: number | null; points?: number | null; branchName?: string | null; prUrl?: string | null; designUrl?: string | null; specUrl?: string | null; links?: Record<string, string> | null; epicId?: string | null; featureId?: string | null; cycleId?: string | null; scopeId?: string | null; assigneeId?: string | null }) => Promise<unknown> };\n delete: { mutate: (input: { id: string }) => Promise<unknown> };\n search: { query: (input: { productId: string; query?: string; excludeTicketId?: string; limit?: number }) => Promise<unknown[]> };\n addDependency: { mutate: (input: { ticketId: string; dependsOnId: string }) => Promise<unknown> };\n removeDependency: { mutate: (input: { ticketId: string; dependsOnId: string }) => Promise<unknown> };\n addComment: { mutate: (input: { ticketId: string; content: string }) => Promise<unknown> };\n updateComment: { mutate: (input: { id: string; content: string }) => Promise<unknown> };\n deleteComment: { mutate: (input: { id: string }) => Promise<unknown> };\n linkAction: { mutate: (input: { ticketId: string; actionId: string }) => Promise<unknown> };\n unlinkAction: { mutate: (input: { actionId: string }) => Promise<unknown> };\n };\n };\n}\n\nexport function createClient(config: { token: string; apiUrl: string }): TrpcClient {\n const apiUrl = config.apiUrl.replace(/\\/+$/, '');\n\n return createTRPCClient<any>({\n links: [\n httpBatchLink({\n url: `${apiUrl}/api/trpc`,\n headers() {\n return {\n Authorization: `Bearer ${config.token}`,\n };\n },\n transformer: superjson,\n }),\n ],\n }) as unknown as TrpcClient;\n}\n\nexport function isTRPCError(error: unknown): error is TRPCClientError<any> {\n return error instanceof TRPCClientError;\n}\n\nexport { TRPCClientError };\n","import type { TrpcClient } from './client.js';\nimport type { Action, KanbanStatus, Priority } from './types/action.js';\n\nexport interface ActionsListOptions {\n projectId?: string;\n status?: KanbanStatus;\n assigneeId?: string;\n}\n\nexport interface ActionsKanbanOptions {\n projectId?: string;\n status?: KanbanStatus;\n assigneeId?: string;\n}\n\nexport type ActionStatus = 'ACTIVE' | 'COMPLETED' | 'CANCELLED' | 'DELETED' | 'DRAFT';\n\nexport interface ActionCreateInput {\n name: string;\n description?: string;\n projectId?: string;\n workspaceId?: string;\n dueDate?: Date;\n scheduledStart?: Date;\n scheduledEnd?: Date;\n duration?: number;\n priority?: Priority;\n status?: ActionStatus;\n epicId?: string;\n effortEstimate?: number;\n blockedByIds?: string[];\n}\n\nexport interface ActionUpdateInput {\n id: string;\n name?: string;\n description?: string;\n projectId?: string;\n workspaceId?: string | null;\n dueDate?: Date | null;\n scheduledStart?: Date | null;\n scheduledEnd?: Date | null;\n duration?: number | null;\n priority?: Priority;\n status?: ActionStatus;\n kanbanStatus?: KanbanStatus;\n epicId?: string | null;\n effortEstimate?: number | null;\n blockedByIds?: string[];\n}\n\nexport interface ActionUpsertBySourceInput {\n /** Convention for the Daily worklog: `claude-session`. */\n sourceType: string;\n /** The conversation id — re-running with the same pair updates, never duplicates. */\n sourceId: string;\n name: string;\n workspaceId: string;\n description?: string;\n /** Must live in `workspaceId`, or the call is NOT_FOUND. */\n projectId?: string | null;\n /** Must belong to a product in `workspaceId`, or the call is NOT_FOUND. */\n ticketId?: string | null;\n}\n\nexport interface ActionUpsertBySourceResult {\n action: Action & {\n ticket?: { id: string; number: number; shortId: string | null; productId: string } | null;\n };\n outcome: 'created' | 'updated';\n}\n\n/** One action as returned inside a {@link TodaysActions} group. */\nexport interface TodaysActionRow {\n id: string;\n name: string;\n status: string;\n scheduledStart: Date | null;\n dueDate: Date | null;\n projectName: string | null;\n workspaceName: string | null;\n}\n\nexport interface TodaysActionsGroup {\n /** Total in this group — may exceed `actions.length`, which is capped at 50. */\n count: number;\n actions: TodaysActionRow[];\n}\n\nexport interface TodaysActions {\n overdue: TodaysActionsGroup;\n today: TodaysActionsGroup;\n inbox: TodaysActionsGroup;\n}\n\nexport interface OverdueTriageRow extends Omit<TodaysActionRow, 'status' | 'workspaceName'> {\n priority: string | null;\n daysOverdue: number;\n}\n\nexport interface OverdueCohort {\n /** The exact instant every member is stamped with. */\n stampedAt: Date;\n daysOverdue: number;\n count: number;\n projectNames: string[];\n actionIds: string[];\n actions: OverdueTriageRow[];\n}\n\nexport interface OverdueTriage {\n totalOverdue: number;\n /** How many of `totalOverdue` sit inside a cohort. */\n cohortCount: number;\n cohorts: OverdueCohort[];\n /** Individually-dated overdue actions — real debt, worth reading one by one. */\n loose: OverdueTriageRow[];\n}\n\nexport class ActionsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ActionsListOptions = {}): Promise<Action[]> {\n const { projectId, status, assigneeId } = options;\n let actions: Action[];\n\n if (projectId) {\n actions = await this.client.action.getProjectActions.query({\n projectId,\n assigneeId,\n }) as Action[];\n } else if (status) {\n actions = await this.client.action.getKanbanActions.query({\n kanbanStatus: status,\n assigneeId,\n }) as Action[];\n } else {\n actions = await this.client.action.getAll.query({\n assigneeId,\n }) as Action[];\n }\n\n // Match CLI behavior: hide completed/cancelled unless status specified\n if (!status) {\n actions = actions.filter(action =>\n action.status !== 'COMPLETED' &&\n action.status !== 'CANCELLED' &&\n action.kanbanStatus !== 'DONE' &&\n action.kanbanStatus !== 'CANCELLED'\n );\n }\n\n return actions;\n }\n\n /**\n * Actions whose `dueDate` falls today.\n *\n * Note this is a **narrow** slice: it excludes overdue actions, and excludes\n * anything scheduled for today that carries no due date. If you want \"what\n * is on my plate\", use {@link getTodaysActions} instead — this method will\n * happily report a quiet day on top of a large overdue pile.\n */\n async getToday(workspaceId?: string): Promise<Action[]> {\n return await this.client.action.getToday.query({\n workspaceId,\n }) as Action[];\n }\n\n /**\n * What is actually on the user's plate: the `/today` page's own partition,\n * pre-split into `overdue` / `today` / `inbox`.\n *\n * Prefer this over {@link getToday} for anything that reasons about the\n * user's day. `getToday` is a due-date-only slice that omits the overdue\n * pile entirely — on a real account that can mean returning 6 actions while\n * 40 sit overdue. This method uses the server-shared partition, so it agrees\n * with what the user is looking at by construction.\n *\n * Cross-workspace by default. Each group is capped at 50 rows; `count` is the\n * true total.\n */\n async getTodaysActions(workspaceId?: string): Promise<TodaysActions> {\n return await this.client.action.getTodaysActions.query({\n workspaceId,\n }) as TodaysActions;\n }\n\n /**\n * Why the overdue pile is the size it is.\n *\n * Splits overdue actions into **cohorts** — groups sharing one exact\n * timestamp, the fingerprint of a bulk write like a generated project plan —\n * and **loose** individually-dated debt. Cohort members were almost certainly\n * never individually due, so the honest disposition is {@link bulkDefer},\n * not another {@link bulkReschedule} that re-inflicts the pile tomorrow.\n */\n async getOverdueTriage(workspaceId?: string): Promise<OverdueTriage> {\n return await this.client.action.getOverdueTriage.query({\n workspaceId,\n }) as OverdueTriage;\n }\n\n /**\n * Move actions to a new do-date (`scheduledStart`), pushing `dueDate` forward\n * only where it would otherwise fall before it. Pass `null` to clear both —\n * though {@link bulkDefer} says that more clearly.\n */\n async bulkReschedule(actionIds: string[], dueDate: Date | null): Promise<{ count: number; actionIds: string[] }> {\n return await this.client.action.bulkReschedule.mutate({\n actionIds,\n dueDate,\n }) as { count: number; actionIds: string[] };\n }\n\n /**\n * Amnesty: clear the dates so actions fall back to their project backlog\n * untimed. For work that was never really due on the date it carries —\n * typically an overdue cohort. Kanban status is untouched.\n */\n async bulkDefer(actionIds: string[]): Promise<{ count: number; actionIds: string[]; message: string }> {\n return await this.client.action.bulkDefer.mutate({\n actionIds,\n }) as { count: number; actionIds: string[]; message: string };\n }\n\n async getByDateRange(start: Date, end: Date, workspaceId?: string): Promise<Action[]> {\n return await this.client.action.getByDateRange.query({\n startDate: start,\n endDate: end,\n workspaceId,\n }) as Action[];\n }\n\n async getKanban(options: ActionsKanbanOptions = {}): Promise<Action[]> {\n const { projectId, status, assigneeId } = options;\n\n return await this.client.action.getKanbanActions.query({\n projectId,\n kanbanStatus: status,\n assigneeId,\n }) as Action[];\n }\n\n async getProjectActions(projectId: string, assigneeId?: string): Promise<Action[]> {\n return await this.client.action.getProjectActions.query({\n projectId,\n assigneeId,\n }) as Action[];\n }\n\n async create(input: ActionCreateInput): Promise<Action> {\n return await this.client.action.create.mutate(input) as Action;\n }\n\n async update(input: ActionUpdateInput): Promise<Action> {\n return await this.client.action.update.mutate(input) as Action;\n }\n\n /**\n * One Action per external source: find by (workspaceId, sourceType,\n * sourceId), refresh its name and links, else create it. `outcome` says\n * which happened. Agents may call this; the created Action records the\n * agent's shadow user as creator with `source: \"agent\"` (ADR-0049).\n */\n async upsertBySource(input: ActionUpsertBySourceInput): Promise<ActionUpsertBySourceResult> {\n return await this.client.action.upsertBySource.mutate(input) as ActionUpsertBySourceResult;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { ActionComment } from './types/comment.js';\n\nexport interface ActionCommentAddInput {\n actionId: string;\n content: string;\n}\n\nexport interface ActionCommentUpdateInput {\n commentId: string;\n content: string;\n}\n\nexport class ActionCommentsApi {\n constructor(private client: TrpcClient) {}\n\n async list(actionId: string): Promise<ActionComment[]> {\n return await this.client.actionComment.getComments.query({\n actionId,\n }) as ActionComment[];\n }\n\n async add(input: ActionCommentAddInput): Promise<ActionComment> {\n return await this.client.actionComment.addComment.mutate(input) as ActionComment;\n }\n\n async update(input: ActionCommentUpdateInput): Promise<ActionComment> {\n return await this.client.actionComment.updateComment.mutate(input) as ActionComment;\n }\n\n async delete(commentId: string): Promise<ActionComment> {\n return await this.client.actionComment.deleteComment.mutate({\n commentId,\n }) as ActionComment;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { FeatureComment } from './types/comment.js';\n\nexport interface FeatureCommentCreateInput {\n featureId: string;\n /** Attach to a scope's activity feed instead of the feature's own feed. */\n scopeId?: string;\n /** Anchor to a span of the PRD body. Omit for a doc-level comment. */\n threadId?: string;\n /** Markdown. Mention members with `@[Name](userId)` — see `workspaces.listMembers()`. */\n body: string;\n quotedText?: string;\n}\n\nexport interface FeatureCommentReplyInput {\n parentId: string;\n body: string;\n}\n\nexport interface FeatureCommentUpdateInput {\n commentId: string;\n body: string;\n}\n\nexport interface FeatureCommentThreadInput {\n featureId: string;\n threadId: string;\n}\n\n/**\n * Discussion on a Feature (PRD). Any workspace member can read and comment;\n * editing and deleting are author-only.\n *\n * Mentions are `@[Display Name](userId)` in the body — that markup is what\n * triggers a notification. `workspaces.listMembers()` returns a ready-made\n * `mentionSyntax` per member so callers never have to build it by hand.\n */\nexport class FeatureCommentsApi {\n constructor(private client: TrpcClient) {}\n\n async list(featureId: string): Promise<FeatureComment[]> {\n return await this.client.product.featureComment.list.query({\n featureId,\n }) as FeatureComment[];\n }\n\n async create(input: FeatureCommentCreateInput): Promise<FeatureComment> {\n return await this.client.product.featureComment.create.mutate(\n input,\n ) as FeatureComment;\n }\n\n /** Reply to an existing comment. Replies to replies still hang off the root. */\n async reply(input: FeatureCommentReplyInput): Promise<FeatureComment> {\n return await this.client.product.featureComment.reply.mutate(\n input,\n ) as FeatureComment;\n }\n\n async update(input: FeatureCommentUpdateInput): Promise<FeatureComment> {\n return await this.client.product.featureComment.update.mutate(\n input,\n ) as FeatureComment;\n }\n\n async delete(commentId: string): Promise<{ success: boolean }> {\n return await this.client.product.featureComment.delete.mutate({\n commentId,\n }) as { success: boolean };\n }\n\n /** Mark an anchored thread resolved. Only anchored threads have a threadId. */\n async resolve(input: FeatureCommentThreadInput): Promise<{ success: boolean }> {\n return await this.client.product.featureComment.resolve.mutate(\n input,\n ) as { success: boolean };\n }\n\n async unresolve(input: FeatureCommentThreadInput): Promise<{ success: boolean }> {\n return await this.client.product.featureComment.unresolve.mutate(\n input,\n ) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { PageComment } from './types/comment.js';\n\nexport interface PageCommentCreateInput {\n pageId: string;\n /** Markdown. Mention members with `@[Name](userId)` — see `workspaces.listMembers()`. */\n body: string;\n}\n\nexport interface PageCommentUpdateInput {\n commentId: string;\n body: string;\n}\n\n/**\n * Discussion on a Knowledge Page — a flat, doc-level feed under the page body.\n * View access is the commenting gate: anyone the page is shared with can join\n * the thread. Editing and deleting are author-only.\n */\nexport class PageCommentsApi {\n constructor(private client: TrpcClient) {}\n\n async list(pageId: string): Promise<PageComment[]> {\n return await this.client.pageComment.list.query({ pageId }) as PageComment[];\n }\n\n async create(input: PageCommentCreateInput): Promise<PageComment> {\n return await this.client.pageComment.create.mutate(input) as PageComment;\n }\n\n async update(input: PageCommentUpdateInput): Promise<PageComment> {\n return await this.client.pageComment.update.mutate(input) as PageComment;\n }\n\n async delete(commentId: string): Promise<{ success: boolean }> {\n return await this.client.pageComment.delete.mutate({\n commentId,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { GoalComment } from './types/comment.js';\n\nexport interface GoalCommentAddInput {\n goalId: number;\n /** Markdown. Mention members with `@[Name](userId)` — see `workspaces.listMembers()`. */\n content: string;\n /** Thread this comment under a specific goal update rather than the goal itself. */\n parentUpdateId?: string;\n}\n\nexport interface GoalCommentUpdateInput {\n commentId: string;\n content: string;\n}\n\n/**\n * Discussion on a Goal/Objective. Note `goalId` is numeric — goals use integer\n * ids, unlike the cuid-keyed product entities.\n */\nexport class GoalCommentsApi {\n constructor(private client: TrpcClient) {}\n\n async list(goalId: number): Promise<GoalComment[]> {\n return await this.client.goalComment.getComments.query({\n goalId,\n }) as GoalComment[];\n }\n\n async add(input: GoalCommentAddInput): Promise<GoalComment> {\n return await this.client.goalComment.addComment.mutate(input) as GoalComment;\n }\n\n async update(input: GoalCommentUpdateInput): Promise<GoalComment> {\n return await this.client.goalComment.updateComment.mutate(\n input,\n ) as GoalComment;\n }\n\n async delete(commentId: string): Promise<{ success: boolean }> {\n return await this.client.goalComment.deleteComment.mutate({\n commentId,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { KeyResultsApi } from './keyResults.js';\nimport type {\n Goal,\n GoalPeriod,\n GoalStats,\n GoalStatus,\n GoalTreeNode,\n GoalWritableStatus,\n} from './types/goal.js';\n\nexport interface GoalListOptions {\n /**\n * Scope to a workspace. With it the list is workspace-**wide** — every\n * member's objectives, not just yours. Without it you get your own.\n */\n workspaceId?: string;\n /** Free-form period string, e.g. `\"Q3-2026\"` or `\"Annual-2026\"`. */\n period?: string;\n status?: GoalStatus;\n}\n\nexport interface GoalTreeOptions {\n workspaceId?: string;\n status?: GoalStatus;\n}\n\nexport interface GoalCreateInput {\n title: string;\n description?: string;\n whyThisGoal?: string;\n notes?: string;\n dueDate?: Date;\n period?: string;\n status?: GoalWritableStatus;\n lifeDomainId?: number;\n /** Link the objective to one project on creation. */\n projectId?: string;\n outcomeIds?: string[];\n driUserId?: string;\n workspaceId?: string;\n /** Nest under a parent objective. Max nesting depth is 5. */\n parentGoalId?: number;\n icon?: string | null;\n iconColor?: string | null;\n}\n\n/**\n * A **partial** update: omit a field and it is left untouched, pass an explicit\n * `null` to clear it. Nothing you don't name is written.\n *\n * Prefer {@link GoalsApi.setStatus} for a status change and\n * {@link GoalsApi.setParent} for a re-parent — both write exactly one column.\n */\nexport interface GoalUpdateInput {\n id: number;\n title?: string;\n description?: string | null;\n whyThisGoal?: string | null;\n notes?: string | null;\n dueDate?: Date | null;\n period?: string | null;\n status?: GoalWritableStatus;\n lifeDomainId?: number | null;\n /** Replace the project links with this one project; `null` clears them. */\n projectId?: string | null;\n /** Replace the project links wholesale; `[]` clears them. */\n projectIds?: string[];\n outcomeIds?: string[];\n driUserId?: string | null;\n workspaceId?: string | null;\n parentGoalId?: number | null;\n displayOrder?: number;\n icon?: string | null;\n iconColor?: string | null;\n}\n\nexport interface GoalSetStatusInput {\n id: number;\n /** `on-hold` is accepted here and only here. */\n status: GoalStatus;\n}\n\nexport interface GoalSetParentInput {\n id: number;\n /** `null` detaches the objective from its parent. */\n parentGoalId: number | null;\n}\n\nexport interface GoalStatsOptions {\n workspaceId?: string;\n period?: string;\n}\n\n/**\n * Objectives (`Goal`) — the qualitative half of an OKR, keyed by **integer** id.\n * Their measurable key results hang off {@link KeyResultsApi}, reachable here as\n * `goals.keyResults`.\n *\n * On writes: `update()` is a partial update, but `setStatus()` and `setParent()`\n * each write a single column and are the right call whenever that is all you\n * mean to change — closing a quarter or re-parenting a cascade should never risk\n * a collateral write.\n */\nexport class GoalsApi {\n constructor(\n private client: TrpcClient,\n /** Key results for these objectives. Same instance as `client.keyResults`. */\n public keyResults: KeyResultsApi,\n ) {}\n\n /**\n * List objectives. Pass `workspaceId` for the workspace-wide list (every\n * member's), omit it for your own. Includes each objective's linked\n * `projects`, which is the join that maps day-to-day work back to an OKR:\n * every action carries a `projectId`.\n *\n * `period` and `status` are sent to the server *and* re-applied here. The\n * server grew those filters recently; against an instance that predates them\n * zod strips the unknown keys and hands back **every** objective — a filter\n * that silently matches everything is worse than one that errors. Re-applying\n * is a no-op once the server has done the work. Same reasoning as the\n * client-side `branchName`/`prUrl` filters in `tickets.ts`.\n */\n async list(options: GoalListOptions = {}): Promise<Goal[]> {\n const goals = await this.client.goal.getAllMyGoals.query(options) as Goal[];\n return goals.filter(\n (g) =>\n (options.period === undefined || g.period === options.period) &&\n (options.status === undefined || g.status === options.status),\n );\n }\n\n /**\n * The same objectives nested parent → child (up to 5 levels), each with its\n * projects and key results. One call for the whole annual → quarterly cascade.\n */\n async tree(options: GoalTreeOptions = {}): Promise<GoalTreeNode[]> {\n return await this.client.goal.getGoalTree.query(\n options,\n ) as GoalTreeNode[];\n }\n\n async get(id: number): Promise<Goal> {\n return await this.client.goal.getById.query({ id }) as Goal;\n }\n\n /** Objectives linked to a given project. */\n async listByProject(projectId: string): Promise<Goal[]> {\n return await this.client.goal.getProjectGoals.query({ projectId }) as Goal[];\n }\n\n async create(input: GoalCreateInput): Promise<Goal> {\n return await this.client.goal.createGoal.mutate(input) as Goal;\n }\n\n /**\n * Partial update — see {@link GoalUpdateInput}. Fields you omit are left\n * alone; pass an explicit `null` to clear one.\n */\n async update(input: GoalUpdateInput): Promise<Goal> {\n return await this.client.goal.updateGoal.mutate(input) as Goal;\n }\n\n /**\n * Status-only write. Never touches another field, and is the only path that\n * accepts `on-hold`. Moving an objective to `completed` also records a\n * workspace milestone.\n */\n async setStatus(input: GoalSetStatusInput): Promise<Goal> {\n return await this.client.goal.updateGoalStatus.mutate(input) as Goal;\n }\n\n /**\n * Re-parent an objective, or detach it with `parentGoalId: null`. Writes only\n * `parentGoalId`, and validates the no-self / no-cycle / depth-5 rules.\n */\n async setParent(input: GoalSetParentInput): Promise<Goal> {\n return await this.client.goal.setParent.mutate(input) as Goal;\n }\n\n async delete(id: number): Promise<Goal> {\n return await this.client.goal.deleteGoal.mutate({ id }) as Goal;\n }\n\n /** The conventional period strings (quarters, halves, annual) for this year and next. */\n async periods(): Promise<GoalPeriod[]> {\n return await this.client.okr.getPeriods.query() as GoalPeriod[];\n }\n\n /** Aggregate objective/key-result counts and average progress. */\n async stats(options: GoalStatsOptions = {}): Promise<GoalStats> {\n return await this.client.okr.getStats.query(options) as GoalStats;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n KeyResult,\n KeyResultCheckIn,\n KeyResultStatus,\n KeyResultUnit,\n ObjectiveWithKeyResults,\n} from './types/keyResult.js';\n\nexport interface KeyResultListOptions {\n /**\n * Scope to a workspace. With it the list is workspace-**wide** — every\n * member's key results, not just yours. Without it you get your own.\n */\n workspaceId?: string;\n /** Objective id — an integer, unlike the key result's own cuid. */\n goalId?: number;\n period?: string;\n status?: KeyResultStatus;\n /** Narrow a workspace-scoped list back to the key results you own. */\n onlyMine?: boolean;\n}\n\nexport interface KeyResultByObjectiveOptions {\n workspaceId?: string;\n period?: string;\n /** Also include the period's parent annual period (Q3-2026 → Annual-2026). */\n includePairedPeriod?: boolean;\n onlyMine?: boolean;\n}\n\nexport interface KeyResultCreateInput {\n /** Objective (integer id) the key result hangs off. */\n goalId: number;\n title: string;\n targetValue: number;\n /** Free-form, e.g. `\"Q3-2026\"`. */\n period: string;\n description?: string;\n startValue?: number;\n currentValue?: number;\n unit?: KeyResultUnit;\n unitLabel?: string;\n driUserId?: string;\n /**\n * Omit to inherit the objective's workspace — {@link KeyResultsApi.create}\n * resolves it before writing. Pass one explicitly only to override.\n */\n workspaceId?: string;\n}\n\nexport interface KeyResultUpdateInput {\n /** cuid. */\n id: string;\n title?: string;\n description?: string;\n targetValue?: number;\n currentValue?: number;\n startValue?: number;\n unit?: KeyResultUnit;\n unitLabel?: string;\n status?: KeyResultStatus;\n /** 0–100. */\n confidence?: number;\n driUserId?: string;\n /** Move the key result to a different objective. */\n goalId?: number;\n}\n\nexport interface KeyResultCheckInInput {\n /** cuid. */\n id: string;\n /** The new current value. */\n value: number;\n note?: string;\n}\n\n/**\n * Key results — the measurable half of an OKR.\n *\n * Reachable both as `client.keyResults` and as `client.goals.keyResults`; they\n * are the same instance. Every id here is a **cuid string**, while the `goalId`\n * that ties a key result to its objective is an **integer**. The tRPC router\n * behind these calls is mounted at `okr`, which is the key-result router — not\n * an objective router. Objectives live on {@link GoalsApi}.\n */\nexport class KeyResultsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * List key results. Pass `workspaceId` for the workspace-wide list (every\n * member's), omit it for your own.\n *\n * ⚠️ Workspace scoping here depends on a server-side fix to `okr.getAll`,\n * which previously accepted a `workspaceId` while still filtering on the\n * caller's `userId` — so against an older instance this returns only your own\n * key results, or `[]`, rather than the workspace's. Unlike the filters in\n * `goals.list()` that cannot be repaired here: the other members' rows never\n * reach the client. {@link KeyResultsApi.byObjective} is workspace-correct on\n * every server version and is the safer read when that matters.\n */\n async list(options: KeyResultListOptions = {}): Promise<KeyResult[]> {\n return await this.client.okr.getAll.query(options) as KeyResult[];\n }\n\n /**\n * Objectives with their key results nested — the richest OKR read, and the\n * one to reach for when rendering \"here is the quarter\".\n */\n async byObjective(\n options: KeyResultByObjectiveOptions = {},\n ): Promise<ObjectiveWithKeyResults[]> {\n return await this.client.okr.getByObjective.query(\n options,\n ) as ObjectiveWithKeyResults[];\n }\n\n async get(id: string): Promise<KeyResult> {\n return await this.client.okr.getById.query({ id }) as KeyResult;\n }\n\n /**\n * Create a key result on an objective.\n *\n * When `workspaceId` is omitted it is resolved from the objective first,\n * rather than left to the server. `okr.create` writes the input through as-is\n * on older instances, so an absent workspace persists as `null` — and a key\n * result with no workspace is invisible to every workspace-scoped read and\n * unwritable by teammates once owner-OR-member authz applies. That is the\n * same orphaning that has already cost a goal; one extra read on a mutation\n * is a cheap way not to repeat it.\n */\n async create(input: KeyResultCreateInput): Promise<KeyResult> {\n let workspaceId = input.workspaceId;\n if (workspaceId === undefined) {\n const goal = await this.client.goal.getById.query({\n id: input.goalId,\n }) as { workspaceId: string | null };\n workspaceId = goal.workspaceId ?? undefined;\n }\n return await this.client.okr.create.mutate({\n ...input,\n workspaceId,\n }) as KeyResult;\n }\n\n async update(input: KeyResultUpdateInput): Promise<KeyResult> {\n return await this.client.okr.update.mutate(input) as KeyResult;\n }\n\n /**\n * Record a progress check-in. The server derives the new status from where\n * `value` lands between `startValue` and `targetValue`, so a check-in both\n * moves the number and re-colours the key result.\n */\n async checkIn(input: KeyResultCheckInInput): Promise<KeyResultCheckIn> {\n return await this.client.okr.checkIn.mutate({\n keyResultId: input.id,\n newValue: input.value,\n notes: input.note,\n }) as KeyResultCheckIn;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.okr.delete.mutate({ id }) as { success: boolean };\n }\n\n /** Link a project to a key result as executing work. Idempotent. */\n async linkProject(input: {\n keyResultId: string;\n projectId: string;\n }): Promise<{ success: boolean }> {\n return await this.client.okr.linkProject.mutate(input) as {\n success: boolean;\n };\n }\n\n async unlinkProject(input: {\n keyResultId: string;\n projectId: string;\n }): Promise<{ success: boolean }> {\n return await this.client.okr.unlinkProject.mutate(input) as {\n success: boolean;\n };\n }\n\n /**\n * Link a feature to a key result as executing work. Idempotent. The feature's\n * product must live in the key result's workspace. A feature with no\n * objective alignment inherits the key result's objective; one that already\n * has an objective is never overwritten.\n */\n async linkFeature(input: {\n keyResultId: string;\n featureId: string;\n }): Promise<{ success: boolean }> {\n return await this.client.okr.linkFeature.mutate(input) as {\n success: boolean;\n };\n }\n\n /** Removes only the link row — never the feature's objective alignment. */\n async unlinkFeature(input: {\n keyResultId: string;\n featureId: string;\n }): Promise<{ success: boolean }> {\n return await this.client.okr.unlinkFeature.mutate(input) as {\n success: boolean;\n };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n Project,\n ProjectDetail,\n ProjectPriority,\n ProjectStatus,\n} from './types/project.js';\n\nexport interface ProjectsListOptions {\n workspaceId?: string;\n includeActions?: boolean;\n}\n\n/**\n * A **partial** update. Omit a field and it is left untouched.\n *\n * `name`, `status` and `priority` are required by the server on every call, so\n * {@link ProjectsApi.update} reads the project first and sends the current\n * values for whichever of the three you leave out — the same read-before-write\n * that keeps `goals.update()` from clobbering. Everything else here is written\n * only when present.\n */\nexport interface ProjectUpdateInput {\n id: string;\n name?: string;\n /** The server has no way to clear a description — pass `''` to blank it. */\n description?: string;\n status?: ProjectStatus;\n priority?: ProjectPriority;\n /** `null` unlinks the product. */\n productId?: string | null;\n /** `null` makes the project personal. */\n workspaceId?: string | null;\n /** Directly responsible individual; `null` clears it. */\n driId?: string | null;\n /**\n * Replace the objective links. Integer goal ids passed as strings — the\n * server parses them. An empty array is a **no-op**, not a clear; the server\n * only writes this when the array is non-empty.\n */\n goalIds?: string[];\n outcomeIds?: string[];\n /** Replace the key-result links wholesale; `[]` clears them. */\n keyResultIds?: string[];\n lifeDomainIds?: number[];\n reviewDate?: Date | null;\n nextActionDate?: Date | null;\n startDate?: Date | null;\n endDate?: Date | null;\n}\n\nexport class ProjectsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ProjectsListOptions = {}): Promise<Project[]> {\n const { workspaceId, includeActions } = options;\n\n return await this.client.project.getAll.query({\n workspaceId,\n include: includeActions ? { actions: true } : undefined,\n }) as Project[];\n }\n\n /**\n * Fetch one project with its relations — actions, linked objectives and key\n * results, DRI, team. Accepts a cuid, a slug, or the compound `slug-cuid`\n * form that appears in app URLs.\n *\n * The list read carries none of the OKR edges, so this is the only way to\n * answer \"what is this project driving?\".\n */\n async get(idOrSlug: string): Promise<ProjectDetail> {\n return await this.client.project.getById.query({\n id: idOrSlug,\n }) as ProjectDetail;\n }\n\n /**\n * Partial update — see {@link ProjectUpdateInput}. Costs one extra read when\n * `name`, `status` or `priority` is omitted, because the server requires all\n * three.\n */\n async update(input: ProjectUpdateInput): Promise<Project> {\n const { id, name, status, priority, ...rest } = input;\n\n let resolvedName = name;\n let resolvedStatus = status;\n let resolvedPriority = priority;\n\n if (\n resolvedName === undefined ||\n resolvedStatus === undefined ||\n resolvedPriority === undefined\n ) {\n const current = await this.get(id);\n resolvedName ??= current.name;\n resolvedStatus ??= (current.status as ProjectStatus | null) ?? 'ACTIVE';\n resolvedPriority ??=\n (current.priority as ProjectPriority | null) ?? 'NONE';\n }\n\n return await this.client.project.update.mutate({\n id,\n name: resolvedName,\n status: resolvedStatus,\n priority: resolvedPriority,\n ...rest,\n }) as Project;\n }\n\n /** Deletes the project and its actions. There is no undo. */\n async delete(id: string): Promise<Project> {\n return await this.client.project.delete.mutate({ id }) as Project;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Workspace, WorkspaceMember } from './types/workspace.js';\n\nexport class WorkspacesApi {\n constructor(private client: TrpcClient) {}\n\n async list(): Promise<Workspace[]> {\n return await this.client.workspace.list.query() as Workspace[];\n }\n\n /**\n * Everyone who belongs to a workspace — direct members plus anyone with\n * access through a linked team. This is the lookup that makes mentions\n * possible from outside the app: match a name or email here, then drop the\n * row's `mentionSyntax` into a comment body.\n */\n async listMembers(workspaceId: string): Promise<WorkspaceMember[]> {\n return await this.client.workspace.listMembers.query({\n workspaceId,\n }) as WorkspaceMember[];\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Contact, ContactInteraction, ContactListOutput, InteractionType, InteractionDirection } from './types/contact.js';\n\nexport interface ContactsListOptions {\n workspaceId: string;\n search?: string;\n tags?: string[];\n organizationId?: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface ContactCreateInput {\n workspaceId: string;\n firstName?: string;\n lastName?: string;\n email?: string | null;\n phone?: string;\n linkedIn?: string;\n telegram?: string;\n twitter?: string;\n github?: string;\n bluesky?: string;\n about?: string;\n profileType?: string;\n skills?: string[];\n tags?: string[];\n organizationId?: string;\n /** Link (or find-or-create) an organization by name. Ignored when organizationId is set. */\n organizationName?: string;\n}\n\nexport interface ContactUpdateInput {\n id: string;\n firstName?: string;\n lastName?: string;\n email?: string | null;\n phone?: string | null;\n linkedIn?: string | null;\n telegram?: string | null;\n twitter?: string | null;\n github?: string | null;\n bluesky?: string | null;\n about?: string;\n profileType?: string;\n skills?: string[];\n tags?: string[];\n organizationId?: string | null;\n /** Link (or find-or-create) an organization by name. Ignored when organizationId is set. */\n organizationName?: string;\n}\n\nexport interface EnrichContactResult {\n enqueued: boolean;\n /** The enrichment job id — the newly created one, or the in-flight one that blocked it. */\n enrichmentId?: string;\n /** Why nothing was enqueued (only set when `enqueued` is false). */\n reason?: 'auto-enrich-disabled' | 'already-in-flight';\n}\n\nexport interface AddInteractionInput {\n contactId: string;\n type: InteractionType;\n direction: InteractionDirection;\n subject?: string;\n notes?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport class ContactsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ContactsListOptions): Promise<ContactListOutput> {\n return await this.client.crmApi.contactList.query(options) as ContactListOutput;\n }\n\n async get(id: string, options?: { includeInteractions?: boolean }): Promise<Contact> {\n return await this.client.crmApi.contactGet.query({\n id,\n includeInteractions: options?.includeInteractions,\n }) as Contact;\n }\n\n async create(input: ContactCreateInput): Promise<Contact> {\n return await this.client.crmApi.contactCreate.mutate(input) as Contact;\n }\n\n async update(input: ContactUpdateInput): Promise<Contact> {\n return await this.client.crmApi.contactUpdate.mutate(input) as Contact;\n }\n\n async delete(id: string): Promise<void> {\n await this.client.crmApi.contactDelete.mutate({ id });\n }\n\n async addInteraction(input: AddInteractionInput): Promise<ContactInteraction> {\n return await this.client.crmApi.contactAddInteraction.mutate(input) as ContactInteraction;\n }\n\n /**\n * Enqueue a web-search enrichment job for an existing contact. This is an\n * explicit action, so it runs regardless of the workspace's auto-enrich\n * setting; the enrich-pending-contacts cron drains the job into the\n * enrichment agent. Idempotent — a contact with a job already in flight is\n * not re-queued.\n */\n async enrich(id: string): Promise<EnrichContactResult> {\n return await this.client.crmApi.contactEnrich.mutate({ contactId: id }) as EnrichContactResult;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n Decision,\n DecisionEvidenceTurn,\n DraftDecisionsResult,\n DecisionLink,\n DecisionListRow,\n DecisionReviewState,\n DecisionSource,\n DecisionStatus,\n MeetingDecisions,\n} from './types/decision.js';\n\n/** A person who made the decision; `name` is the only required half. */\nexport interface DecisionDeciderInput {\n userId?: string | null;\n name: string;\n email?: string | null;\n}\n\nexport interface DecisionListOptions {\n workspaceId: string;\n statuses?: DecisionStatus[];\n sources?: DecisionSource[];\n /** A product id, or the literal `\"workspace\"` for decisions with no product. */\n productId?: string;\n /** With a real `productId`: ALSO include decisions that have no product. */\n includeWorkspaceWide?: boolean;\n projectId?: string;\n /** Free-text over statement and body (max 200 characters). */\n search?: string;\n /** One decision by its workspace sequence number — `D-0003` is number 3. */\n number?: number;\n /** Cap the rows returned (1-500). Unset returns everything visible. */\n limit?: number;\n}\n\nexport interface DecisionCreateInput {\n workspaceId: string;\n /** The decision itself, or the open question. Max 500 characters. */\n statement: string;\n /** Markdown detail — context, alternatives, consequences. Max 20,000. */\n body?: string | null;\n /**\n * Defaults to `PROPOSED` server-side. Pass `OPEN` to log an OPEN QUESTION —\n * that is the only representation of one. `SUPERSEDED` and `DEPRECATED` are\n * rejected here; they are `setStatus` transitions.\n */\n status?: DecisionStatus;\n source?: DecisionSource;\n decidedAt?: Date | null;\n ownerId?: string | null;\n /** Meeting provenance. Requires EDIT access to that meeting. */\n transcriptionSessionId?: string | null;\n occurrenceId?: string | null;\n productId?: string | null;\n projectId?: string | null;\n goalId?: number | null;\n keyResultId?: string | null;\n /** Max 50. */\n deciders?: DecisionDeciderInput[];\n /**\n * Quoted transcript turns backing the decision (max 50). The server checks\n * every turn against the meeting's actual transcript: the index must\n * resolve and the words must be that turn's, compared loosely for case,\n * punctuation and whitespace. Turns that don't match are DROPPED, silently\n * from the caller's side, and `speaker`/`startTime` are overwritten with\n * the transcript's own values. Evidence therefore requires\n * `transcriptionSessionId` — sending it without one is a BAD_REQUEST.\n */\n evidence?: DecisionEvidenceTurn[];\n}\n\n/** Content and scope only — status changes go through {@link DecisionsApi.setStatus}. */\nexport interface DecisionUpdateInput {\n workspaceId: string;\n decisionId: string;\n statement?: string;\n body?: string | null;\n decidedAt?: Date | null;\n ownerId?: string | null;\n productId?: string | null;\n projectId?: string | null;\n goalId?: number | null;\n keyResultId?: string | null;\n adrDocumentId?: string | null;\n}\n\nexport interface DecisionSetStatusInput {\n workspaceId: string;\n decisionId: string;\n status: DecisionStatus;\n /** Required by convention when moving to `SUPERSEDED`. */\n supersededById?: string | null;\n}\n\n/**\n * Decisions — the writable half of the Decision Log (ADR-0060).\n *\n * The one thing worth knowing before using this: **an open question is a\n * decision with status `OPEN`**. There is no separate model, and it is what\n * the \"Open questions\" panel on a meeting page reads.\n *\n * Reads need workspace `view`; writes need workspace `edit`, and a decision\n * carrying `transcriptionSessionId` additionally needs edit access to that\n * meeting.\n */\nexport class DecisionsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * Confirmed decisions in a workspace, newest decided first. Drafts are\n * never included — see {@link listForMeeting} for those.\n */\n async list(options: DecisionListOptions): Promise<DecisionListRow[]> {\n return await this.client.decision.list.query(options) as DecisionListRow[];\n }\n\n async get(workspaceId: string, decisionId: string): Promise<Decision> {\n return await this.client.decision.get.query({\n workspaceId,\n decisionId,\n }) as Decision;\n }\n\n /**\n * Decisions logged from one meeting — both panels' contents. Drafts are\n * included for callers who can edit the meeting. No workspace id needed:\n * the meeting resolves it.\n */\n async listForMeeting(\n transcriptionSessionId: string,\n ): Promise<MeetingDecisions> {\n return await this.client.decision.listForMeeting.query({\n transcriptionSessionId,\n }) as MeetingDecisions;\n }\n\n /** Decisions formalised as one ADR (\"Decided in\"). */\n async listForAdr(\n workspaceId: string,\n adrDocumentId: string,\n ): Promise<DecisionListRow[]> {\n return await this.client.decision.listForAdr.query({\n workspaceId,\n adrDocumentId,\n }) as DecisionListRow[];\n }\n\n /**\n * Extract draft decisions from a meeting's notes and transcript. Drafts\n * only — someone confirms or rejects each one. Idempotent per meeting:\n * existing drafts come back untouched, and a meeting that already has\n * confirmed decisions reports `alreadyPublished` without calling the model.\n */\n async extractDrafts(\n transcriptionSessionId: string,\n ): Promise<DraftDecisionsResult> {\n return await this.client.decision.extractDrafts.mutate({\n transcriptionSessionId,\n }) as DraftDecisionsResult;\n }\n\n /**\n * Log a decision. Pass `status: 'OPEN'` for an open question, and\n * `transcriptionSessionId` to attach it to the meeting it came out of.\n */\n async create(input: DecisionCreateInput): Promise<Decision> {\n return await this.client.decision.create.mutate(input) as Decision;\n }\n\n async update(input: DecisionUpdateInput): Promise<Decision> {\n return await this.client.decision.update.mutate(input) as Decision;\n }\n\n /**\n * Lifecycle transition — including answering an open question by moving it\n * from `OPEN` to `ACCEPTED`.\n */\n async setStatus(input: DecisionSetStatusInput): Promise<Decision> {\n return await this.client.decision.setStatus.mutate(input) as Decision;\n }\n\n /** \"Implemented by\" a ticket. Idempotent: an existing link is returned. */\n async linkTicket(\n workspaceId: string,\n decisionId: string,\n ticketId: string,\n ): Promise<DecisionLink> {\n return await this.client.decision.linkTicket.mutate({\n workspaceId,\n decisionId,\n ticketId,\n }) as DecisionLink;\n }\n\n /** \"Implemented by\" a feature. Idempotent: an existing link is returned. */\n async linkFeature(\n workspaceId: string,\n decisionId: string,\n featureId: string,\n ): Promise<DecisionLink> {\n return await this.client.decision.linkFeature.mutate({\n workspaceId,\n decisionId,\n featureId,\n }) as DecisionLink;\n }\n\n /** Remove one link, by the `DecisionLink` id (not the ticket/feature id). */\n async unlink(workspaceId: string, linkId: string): Promise<{ deleted: boolean }> {\n return await this.client.decision.unlink.mutate({\n workspaceId,\n linkId,\n }) as { deleted: boolean };\n }\n\n /**\n * Publish a draft into the log. Needs a person's login: agent keys are\n * refused. Idempotent on a decision that is already confirmed.\n *\n * `status` moves it in the same write — `{ status: 'ACCEPTED' }` is\n * \"confirm as accepted\", and works on an already-confirmed decision too.\n * `SUPERSEDED` is refused (it needs a successor; use {@link setStatus}).\n * A person confirming or accepting a decision that no person stands behind\n * becomes its decider. `decisionId` may also be a `D-0006` label.\n */\n async confirmDraft(\n workspaceId: string,\n decisionId: string,\n options: { status?: DecisionStatus } = {},\n ): Promise<Decision> {\n return await this.client.decision.confirmDraft.mutate({\n workspaceId,\n decisionId,\n ...(options.status ? { status: options.status } : {}),\n }) as Decision;\n }\n\n /**\n * Reject a draft. Confirmed decisions are never rejected — deprecate or\n * supersede them through {@link setStatus}.\n */\n async rejectDraft(\n workspaceId: string,\n decisionId: string,\n ): Promise<{ id: string; reviewState: DecisionReviewState }> {\n return await this.client.decision.rejectDraft.mutate({\n workspaceId,\n decisionId,\n }) as { id: string; reviewState: DecisionReviewState };\n }\n\n /**\n * Hard-delete a draft or rejected row. The server refuses for a confirmed\n * decision — the log keeps its history.\n */\n async deleteDraft(\n workspaceId: string,\n decisionId: string,\n ): Promise<{ id: string }> {\n return await this.client.decision.deleteDraft.mutate({\n workspaceId,\n decisionId,\n }) as { id: string };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Organization, OrganizationListOutput, OrganizationSize } from './types/organization.js';\n\nexport interface OrganizationsListOptions {\n workspaceId: string;\n search?: string;\n industry?: string;\n limit?: number;\n cursor?: string;\n}\n\nexport interface OrganizationCreateInput {\n workspaceId: string;\n name: string;\n websiteUrl?: string | null;\n logoUrl?: string | null;\n description?: string;\n industry?: string;\n size?: OrganizationSize;\n}\n\nexport class OrganizationsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: OrganizationsListOptions): Promise<OrganizationListOutput> {\n return await this.client.crmApi.organizationList.query(options) as OrganizationListOutput;\n }\n\n async get(id: string): Promise<Organization> {\n return await this.client.crmApi.organizationGet.query({ id }) as Organization;\n }\n\n async create(input: OrganizationCreateInput): Promise<Organization> {\n return await this.client.crmApi.organizationCreate.mutate(input) as Organization;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Pipeline, PipelineStage, Deal } from './types/pipeline.js';\n\nexport interface DealCreateInput {\n workspaceId: string;\n stageId: string;\n title: string;\n description?: string;\n value?: number;\n currency?: string;\n probability?: number;\n expectedCloseDate?: Date;\n contactId?: string;\n organizationId?: string;\n assignedToId?: string;\n}\n\nexport interface DealUpdateInput {\n id: string;\n title?: string;\n description?: string | null;\n value?: number | null;\n currency?: string;\n probability?: number | null;\n expectedCloseDate?: Date | null;\n contactId?: string | null;\n organizationId?: string | null;\n assignedToId?: string | null;\n}\n\nexport interface DealMoveInput {\n id: string;\n stageId: string;\n stageOrder: number;\n}\n\nexport class PipelinesApi {\n constructor(private client: TrpcClient) {}\n\n async get(workspaceId: string): Promise<Pipeline | null> {\n return await this.client.crmApi.pipelineGet.query({ workspaceId }) as Pipeline | null;\n }\n\n async getStages(workspaceId: string): Promise<PipelineStage[]> {\n return await this.client.crmApi.pipelineGetStages.query({ workspaceId }) as PipelineStage[];\n }\n\n async listDeals(workspaceId: string): Promise<Deal[]> {\n return await this.client.crmApi.dealList.query({ workspaceId }) as Deal[];\n }\n\n async getDeal(id: string): Promise<Deal> {\n return await this.client.crmApi.dealGet.query({ id }) as Deal;\n }\n\n async createDeal(input: DealCreateInput): Promise<Deal> {\n return await this.client.crmApi.dealCreate.mutate(input) as Deal;\n }\n\n async updateDeal(input: DealUpdateInput): Promise<Deal> {\n return await this.client.crmApi.dealUpdate.mutate(input) as Deal;\n }\n\n async moveDeal(input: DealMoveInput): Promise<Deal> {\n return await this.client.crmApi.dealMove.mutate(input) as Deal;\n }\n\n async deleteDeal(id: string): Promise<void> {\n await this.client.crmApi.dealDelete.mutate({ id });\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { TicketComment } from './types/comment.js';\nimport type {\n Ticket,\n TicketDetail,\n TicketDependencyEdge,\n TicketStatus,\n TicketType,\n} from './types/ticket.js';\nimport type { Action } from './types/action.js';\n\nexport interface TicketListOptions {\n /**\n * Always required. `product.ticket.list` is product-scoped on the server —\n * there is no workspace-wide ticket query. To search several products, call\n * `list` once per product and merge the results.\n */\n productId: string;\n status?: TicketStatus;\n type?: TicketType;\n featureId?: string;\n epicId?: string;\n cycleId?: string;\n assigneeId?: string;\n /**\n * Filter by `Ticket.prUrl` (exact match).\n *\n * Applied **client-side**, after the product-scoped fetch — the server's\n * `list` input schema has no `prUrl` field. See the note on {@link\n * TicketsApi.list}.\n */\n prUrl?: string;\n /**\n * Filter by `Ticket.branchName` (exact match).\n *\n * Applied **client-side**, after the product-scoped fetch — the server's\n * `list` input schema has no `branchName` field. See the note on {@link\n * TicketsApi.list}.\n */\n branchName?: string;\n}\n\nexport interface TicketCreateInput {\n productId: string;\n title: string;\n body?: string;\n type?: TicketType;\n status?: TicketStatus;\n /** 0–4; lower is higher priority. */\n priority?: number;\n points?: number;\n branchName?: string;\n prUrl?: string;\n designUrl?: string;\n specUrl?: string;\n links?: Record<string, string>;\n epicId?: string;\n featureId?: string;\n cycleId?: string;\n scopeId?: string;\n assigneeId?: string;\n templateId?: string;\n}\n\nexport interface TicketUpdateInput {\n id: string;\n title?: string;\n body?: string;\n type?: TicketType;\n status?: TicketStatus;\n priority?: number | null;\n points?: number | null;\n branchName?: string | null;\n prUrl?: string | null;\n designUrl?: string | null;\n specUrl?: string | null;\n links?: Record<string, string> | null;\n epicId?: string | null;\n featureId?: string | null;\n cycleId?: string | null;\n scopeId?: string | null;\n assigneeId?: string | null;\n}\n\nexport interface TicketCommentAddInput {\n ticketId: string;\n content: string;\n}\n\nexport interface TicketCommentUpdateInput {\n id: string;\n content: string;\n}\n\nexport interface TicketSearchOptions {\n productId: string;\n query?: string;\n excludeTicketId?: string;\n limit?: number;\n}\n\nexport class TicketsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * List tickets in one product.\n *\n * `prUrl` and `branchName` are filtered here rather than on the server. The\n * `product.ticket.list` tRPC input schema accepts neither, and zod strips\n * unknown keys, so forwarding them was silently a no-op: a lookup by a branch\n * that matched nothing came back as *every ticket in the product*. Filtering\n * locally makes them mean what they say. Move them server-side once\n * `product.ticket.list` grows the matching input fields.\n */\n async list(options: TicketListOptions): Promise<Ticket[]> {\n const { prUrl, branchName, ...serverQuery } = options;\n const tickets = await this.client.product.ticket.list.query(\n serverQuery,\n ) as Ticket[];\n\n return tickets.filter((t) =>\n (prUrl === undefined || t.prUrl === prUrl) &&\n (branchName === undefined || t.branchName === branchName)\n );\n }\n\n async get(id: string): Promise<TicketDetail> {\n return await this.client.product.ticket.getById.query({\n id,\n }) as TicketDetail;\n }\n\n async create(input: TicketCreateInput): Promise<Ticket> {\n return await this.client.product.ticket.create.mutate(input) as Ticket;\n }\n\n async update(input: TicketUpdateInput): Promise<Ticket> {\n return await this.client.product.ticket.update.mutate(input) as Ticket;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.ticket.delete.mutate({ id }) as {\n success: boolean;\n };\n }\n\n async search(options: TicketSearchOptions): Promise<TicketDependencyEdge[]> {\n return await this.client.product.ticket.search.query(\n options,\n ) as TicketDependencyEdge[];\n }\n\n /** Mark `ticketId` as blocked by `dependsOnId`. */\n async addDependency(\n ticketId: string,\n dependsOnId: string,\n ): Promise<{ id: string; dependsOn: TicketDependencyEdge }> {\n return await this.client.product.ticket.addDependency.mutate({\n ticketId,\n dependsOnId,\n }) as { id: string; dependsOn: TicketDependencyEdge };\n }\n\n async removeDependency(\n ticketId: string,\n dependsOnId: string,\n ): Promise<{ success: boolean }> {\n return await this.client.product.ticket.removeDependency.mutate({\n ticketId,\n dependsOnId,\n }) as { success: boolean };\n }\n\n async addComment(input: TicketCommentAddInput): Promise<TicketComment> {\n return await this.client.product.ticket.addComment.mutate(\n input,\n ) as TicketComment;\n }\n\n async updateComment(input: TicketCommentUpdateInput): Promise<TicketComment> {\n return await this.client.product.ticket.updateComment.mutate(\n input,\n ) as TicketComment;\n }\n\n async deleteComment(id: string): Promise<{ success: boolean }> {\n return await this.client.product.ticket.deleteComment.mutate({\n id,\n }) as { success: boolean };\n }\n\n /** Attach an existing action to a ticket. */\n async linkAction(ticketId: string, actionId: string): Promise<Action> {\n return await this.client.product.ticket.linkAction.mutate({\n ticketId,\n actionId,\n }) as Action;\n }\n\n /** Detach an action from whatever ticket it's linked to. */\n async unlinkAction(actionId: string): Promise<Action> {\n return await this.client.product.ticket.unlinkAction.mutate({\n actionId,\n }) as Action;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Product } from './types/product.js';\n\nexport interface ProductCreateInput {\n workspaceId: string;\n name: string;\n /** Kebab-case slug; must match `/^[a-z0-9-]+$/`. */\n slug: string;\n description?: string;\n icon?: string;\n color?: string;\n}\n\nexport interface ProductUpdateInput {\n id: string;\n name?: string;\n description?: string;\n icon?: string;\n color?: string;\n funTicketIds?: boolean;\n}\n\nexport class ProductsApi {\n constructor(private client: TrpcClient) {}\n\n async list(workspaceId: string): Promise<Product[]> {\n return await this.client.product.product.list.query({\n workspaceId,\n }) as Product[];\n }\n\n async get(id: string): Promise<Product> {\n return await this.client.product.product.getById.query({ id }) as Product;\n }\n\n async getBySlug(workspaceId: string, slug: string): Promise<Product> {\n return await this.client.product.product.getBySlug.query({\n workspaceId,\n slug,\n }) as Product;\n }\n\n /**\n * Resolve a product reference (slug or CUID) to a full Product. Falls back\n * to slug lookup if the bare CUID lookup fails — callers can pass either.\n */\n async resolve(workspaceId: string, slugOrId: string): Promise<Product> {\n // Heuristic: CUIDs from Prisma start with 'c' and are 25 chars; otherwise\n // try slug first. We try both to stay forgiving.\n const looksLikeId = /^c[a-z0-9]{20,}$/.test(slugOrId);\n if (looksLikeId) {\n try {\n return await this.get(slugOrId);\n } catch {\n // fall through to slug\n }\n }\n return await this.getBySlug(workspaceId, slugOrId);\n }\n\n async create(input: ProductCreateInput): Promise<Product> {\n return await this.client.product.product.create.mutate(input) as Product;\n }\n\n async update(input: ProductUpdateInput): Promise<Product> {\n return await this.client.product.product.update.mutate(input) as Product;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.product.delete.mutate({ id }) as {\n success: boolean;\n };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Feature, FeatureStatus } from './types/feature.js';\n\nexport interface FeatureListOptions {\n productId: string;\n status?: FeatureStatus;\n}\n\nexport interface FeatureCreateInput {\n productId: string;\n name: string;\n description?: string;\n vision?: string;\n status?: FeatureStatus;\n effort?: number;\n /** 0–4; lower is higher priority. */\n priority?: number;\n goalId?: number;\n /** Area (per-product bucket) to file the feature under. */\n areaId?: string;\n}\n\nexport interface FeatureUpdateInput {\n id: string;\n name?: string;\n description?: string;\n vision?: string;\n status?: FeatureStatus;\n effort?: number;\n priority?: number;\n goalId?: number | null;\n areaId?: string | null;\n}\n\nexport interface FeatureLinkPageInput {\n featureId: string;\n pageId: string;\n /** Pin the linked page to one of the feature's scopes. */\n scopeId?: string;\n}\n\nexport class FeaturesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: FeatureListOptions): Promise<Feature[]> {\n return await this.client.product.feature.list.query({\n productId: options.productId,\n status: options.status,\n }) as Feature[];\n }\n\n async get(id: string): Promise<Feature> {\n return await this.client.product.feature.getById.query({ id }) as Feature;\n }\n\n async create(input: FeatureCreateInput): Promise<Feature> {\n return await this.client.product.feature.create.mutate(input) as Feature;\n }\n\n async update(input: FeatureUpdateInput): Promise<Feature> {\n return await this.client.product.feature.update.mutate(input) as Feature;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.delete.mutate({ id }) as {\n success: boolean;\n };\n }\n\n /** Link a Knowledge page (PRD, spec, research) to a feature. */\n async linkPage(input: FeatureLinkPageInput): Promise<unknown> {\n return await this.client.product.feature.linkPage.mutate(input);\n }\n\n async unlinkPage(featureId: string, pageId: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.unlinkPage.mutate({\n featureId,\n pageId,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Feature } from './types/feature.js';\nimport type { UserStory } from './types/userStory.js';\n\nexport interface UserStoryListOptions {\n featureId: string;\n}\n\nexport interface UserStoryCreateInput {\n featureId: string;\n asA?: string;\n iWant?: string;\n soThat?: string;\n acceptanceCriteria?: string;\n scopeId?: string;\n}\n\nexport interface UserStoryUpdateInput {\n id: string;\n asA?: string;\n iWant?: string;\n soThat?: string;\n acceptanceCriteria?: string;\n scopeId?: string | null;\n}\n\n/**\n * Native, structured user stories on a feature (As a / I want / So that).\n *\n * Mirrors the existing `FeaturesApi` shape and the `client.product.feature.*`\n * call style. `list` derives from the feature's `getById` payload, which\n * already includes `userStories` ordered by `displayOrder` — there is no\n * dedicated list procedure.\n */\nexport class UserStoriesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: UserStoryListOptions): Promise<UserStory[]> {\n const feature = await this.client.product.feature.getById.query({\n id: options.featureId,\n }) as Feature & { userStories?: UserStory[] };\n return feature.userStories ?? [];\n }\n\n async create(input: UserStoryCreateInput): Promise<UserStory> {\n return await this.client.product.feature.addUserStory.mutate(\n input,\n ) as UserStory;\n }\n\n async update(input: UserStoryUpdateInput): Promise<UserStory> {\n return await this.client.product.feature.updateUserStory.mutate(\n input,\n ) as UserStory;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.deleteUserStory.mutate({\n id,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Epic, EpicPriority, EpicStatus } from './types/epic.js';\n\nexport interface EpicListOptions {\n workspaceId: string;\n status?: EpicStatus;\n}\n\nexport interface EpicCreateInput {\n workspaceId: string;\n name: string;\n description?: string;\n priority?: EpicPriority;\n startDate?: Date;\n targetDate?: Date;\n}\n\nexport interface EpicUpdateInput {\n id: string;\n name?: string;\n description?: string | null;\n status?: EpicStatus;\n priority?: EpicPriority;\n startDate?: Date | null;\n targetDate?: Date | null;\n}\n\nexport class EpicsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: EpicListOptions): Promise<Epic[]> {\n return await this.client.epic.list.query({\n workspaceId: options.workspaceId,\n status: options.status,\n }) as Epic[];\n }\n\n async get(id: string): Promise<Epic> {\n return await this.client.epic.getById.query({ id }) as Epic;\n }\n\n async create(input: EpicCreateInput): Promise<Epic> {\n return await this.client.epic.create.mutate(input) as Epic;\n }\n\n async update(input: EpicUpdateInput): Promise<Epic> {\n return await this.client.epic.update.mutate(input) as Epic;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.epic.delete.mutate({ id }) as {\n success: boolean;\n };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Tag, TagEntityType, TagListResult } from './types/tag.js';\n\nexport interface LabelListOptions {\n workspaceId?: string;\n category?: string | null;\n}\n\nexport interface LabelCreateInput {\n workspaceId: string;\n name: string;\n color: string;\n description?: string;\n category?: string | null;\n}\n\nexport interface SetEntityTagsInput {\n entityType: TagEntityType;\n entityId: string;\n tagIds: string[];\n}\n\nexport interface ListForEntityInput {\n entityType: TagEntityType;\n entityId: string;\n}\n\nexport interface SetEntityTagsResult {\n entityType: TagEntityType;\n entityId: string;\n tags: Tag[];\n}\n\n/**\n * Labels API. Backed by the server's `tag.*` tRPC procedures. \"Label\" is the\n * user-facing word for a Tag (specifically when `category` is null).\n */\nexport class LabelsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: LabelListOptions = {}): Promise<TagListResult> {\n return (await this.client.tag.list.query({\n workspaceId: options.workspaceId,\n category: options.category,\n })) as TagListResult;\n }\n\n async create(input: LabelCreateInput): Promise<Tag> {\n return (await this.client.tag.create.mutate({\n workspaceId: input.workspaceId,\n name: input.name,\n color: input.color,\n description: input.description,\n category: input.category,\n })) as Tag;\n }\n\n async setEntityTags(input: SetEntityTagsInput): Promise<SetEntityTagsResult> {\n return (await this.client.tag.setEntityTags.mutate(input)) as SetEntityTagsResult;\n }\n\n async listForEntity(input: ListForEntityInput): Promise<Tag[]> {\n return (await this.client.tag.listForEntity.query(input)) as Tag[];\n }\n}\n","import type { TrpcClient } from './client.js';\n\nexport interface Area {\n id: string;\n productId: string;\n name: string;\n description: string | null;\n displayOrder: number;\n createdAt: Date;\n updatedAt: Date;\n _count?: {\n features?: number;\n };\n}\n\nexport interface AreaListOptions {\n productId: string;\n}\n\nexport interface AreaCreateInput {\n productId: string;\n name: string;\n description?: string;\n}\n\n/**\n * Areas: per-product buckets a feature is filed under (exactly one or none).\n */\nexport class AreasApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: AreaListOptions): Promise<Area[]> {\n return await this.client.product.feature.listAreas.query(options) as Area[];\n }\n\n async create(input: AreaCreateInput): Promise<Area> {\n return await this.client.product.feature.createArea.mutate(input) as Area;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Meeting } from './types/meeting.js';\n\nexport type MeetingTypeFilter =\n | 'all'\n | 'mine'\n | 'one_on_one'\n | 'customer'\n | 'internal';\n\nexport interface MeetingListOptions {\n workspaceId?: string;\n includeArchived?: boolean;\n /**\n * - `mine`: caller owns the meeting or is a participant\n * - `one_on_one`: exactly two participants\n * - `customer` / `internal`: always empty until meeting tagging ships\n */\n meetingType?: MeetingTypeFilter;\n}\n\n/** A member (userId), an existing CRM contact (contactId), or a name/email. */\nexport interface MeetingParticipantInput {\n userId?: string;\n contactId?: string;\n email?: string;\n name?: string;\n}\n\nexport interface MeetingCreateInput {\n title: string;\n /** Raw transcript text — required by the server, min 1 character. */\n transcription: string;\n description?: string;\n notes?: string;\n meetingDate?: Date;\n /** A project-linked meeting inherits its project's workspace. */\n projectId?: string;\n workspaceId?: string;\n participants?: MeetingParticipantInput[];\n}\n\nexport interface MeetingUpdateInput {\n id: string;\n title?: string;\n description?: string;\n notes?: string;\n summary?: string;\n transcription?: string;\n meetingDate?: Date | null;\n workspaceId?: string | null;\n}\n\n/**\n * Meetings (transcription sessions): recorded/imported meetings and manually\n * created ones, each carrying `notes`, an AI `summary`, and the raw\n * `transcription`.\n */\nexport class MeetingsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * List meetings visible to the caller (owner, participant, project access,\n * or workspace membership). Rows include full `notes`/`summary`/\n * `transcription` bodies, so expect large payloads.\n */\n async list(options: MeetingListOptions = {}): Promise<Meeting[]> {\n return await this.client.transcription.getAllTranscriptions.query(\n options,\n ) as Meeting[];\n }\n\n async get(id: string): Promise<Meeting> {\n return await this.client.transcription.getById.query({ id }) as Meeting;\n }\n\n async create(input: MeetingCreateInput): Promise<Meeting> {\n return await this.client.transcription.createManualTranscription.mutate(\n input,\n ) as Meeting;\n }\n\n /**\n * Partial update — only the keys present are written. The server splits\n * title from the other fields, so a title change is a second mutation.\n */\n async update(input: MeetingUpdateInput): Promise<Meeting> {\n const { id, title, ...details } = input;\n const hasDetails = Object.values(details).some((v) => v !== undefined);\n if (title === undefined && !hasDetails) {\n throw new Error('MeetingsApi.update: nothing to update');\n }\n\n let result: Meeting | undefined;\n if (title !== undefined) {\n result = await this.client.transcription.updateTitle.mutate({\n id,\n title,\n }) as Meeting;\n }\n if (hasDetails) {\n result = await this.client.transcription.updateDetails.mutate({\n id,\n ...details,\n }) as Meeting;\n }\n return result!;\n }\n\n /** The meeting-notes body alone (null when none have been written). */\n async getNotes(id: string): Promise<string | null> {\n const meeting = await this.get(id);\n return meeting.notes ?? null;\n }\n\n /** Replace the meeting's notes. */\n async setNotes(id: string, notes: string): Promise<Meeting> {\n return await this.update({ id, notes });\n }\n\n /**\n * Permanently delete one meeting. Owner-only: the server answers\n * NOT_FOUND for a missing id and FORBIDDEN for a meeting you don't own.\n * Linked actions survive (their meeting link is nulled).\n */\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.transcription.deleteTranscription.mutate({\n id,\n }) as { success: boolean };\n }\n\n /**\n * Permanently delete meetings in bulk. Scoped to meetings the caller\n * owns — ids that are missing or owned by someone else are silently\n * skipped, so compare `count` against the ids you sent.\n */\n async deleteMany(ids: string[]): Promise<{ count: number }> {\n return await this.client.transcription.bulkDeleteTranscriptions.mutate({\n ids,\n }) as { count: number };\n }\n\n /**\n * Append a block to the meeting's notes (separated by a blank line),\n * creating them if none exist. Read-modify-write, not atomic.\n */\n async appendNotes(id: string, text: string): Promise<Meeting> {\n const existing = await this.getNotes(id);\n const notes = existing?.trim()\n ? `${existing.replace(/\\s+$/, '')}\\n\\n${text}`\n : text;\n return await this.update({ id, notes });\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n KnowledgePage,\n PageDiff,\n PageGetFormat,\n PageHistory,\n PageRevisionDetail,\n PageSearchOutput,\n} from './types/page.js';\n\nexport interface PageListOptions {\n workspaceId: string;\n projectId?: string;\n /** Case-insensitive title match. To find pages by content or meaning use `search`. */\n search?: string;\n}\n\nexport interface PageGetOptions {\n /**\n * How much of the body to fetch. Defaults to `markdown` — the Markdown body\n * without the editor's ProseMirror doc, which is several times larger and\n * carries nothing an agent needs. `outline` returns headings only; `full`\n * is the editor payload.\n */\n format?: PageGetFormat;\n /**\n * Narrow the body to one section: the heading's text (case-insensitive;\n * `## ` prefix tolerated) through to the next heading of the same or a\n * higher level. Unknown headings fail with the list of headings that exist.\n */\n section?: string;\n}\n\nexport interface PageSearchOptions {\n workspaceId: string;\n /** What the page should be about (2–200 chars). */\n query: string;\n projectId?: string;\n /** Max pages returned (1–25, server default 10). */\n limit?: number;\n}\n\nexport interface PageHistoryOptions {\n /** Max revisions (1–200, server default 50). */\n limit?: number;\n /** `nextCursor` from a previous page of history. */\n cursor?: string;\n}\n\nexport interface PageDiffOptions {\n /**\n * What to compare the revision with: `previous` (default — what this\n * revision changed), `current` (the page as it is now), or another\n * revision's id.\n */\n against?: 'previous' | 'current' | string;\n}\n\nexport interface PageCreateInput {\n workspaceId: string;\n projectId?: string | null;\n title?: string;\n /** Markdown body. Indexed for search when non-empty. */\n body?: string;\n includeInSearch?: boolean;\n /** Why the page was created — recorded on its first revision. */\n note?: string;\n /** Provenance: where the facts come from (URL, document, person). */\n source?: string | null;\n /** Provenance: the date the facts were true. */\n asOf?: Date | null;\n}\n\nexport interface PageUpdateInput {\n id: string;\n title?: string;\n projectId?: string | null;\n includeInSearch?: boolean;\n /**\n * Markdown body. Sending `body` without a rich-text doc is a\n * Markdown-source write: the server treats the Markdown as canonical and\n * the editor re-derives its rich document on next open.\n */\n body?: string;\n /**\n * The `docVersion` you read before editing. With it, a body write is a\n * compare-and-set: if someone saved in between, the call fails with\n * CONFLICT instead of overwriting their work. Always send it when you can.\n */\n baseVersion?: number;\n /**\n * Why this change — recorded on the revision and shown in the page's\n * history. Always send one from an agent: a body write without a note\n * reads \"No reason given\" to everyone who looks at the history.\n */\n note?: string;\n /** Provenance: where the facts come from. Empty string / null clears it. */\n source?: string | null;\n /** Provenance: the date the facts were true. Null clears it. */\n asOf?: Date | null;\n}\n\nexport interface PageRestoreOptions {\n /** Why you are restoring; defaults to \"Restored the version from <date>\". */\n note?: string;\n /**\n * The page's `docVersion` when you decided to restore (the newest\n * revision's `docVersion` from `history`). With it, a page saved since then\n * fails with CONFLICT instead of being replaced. Always send it.\n */\n baseVersion?: number;\n}\n\n/**\n * Knowledge pages (PRDs, research, technical specs). Workspace-scoped\n * documents; link one to a feature via `FeaturesApi.linkPage`.\n *\n * Reads are lean by default: `get` returns Markdown only. Use `outline` to see\n * a long page's shape, then `get(id, { section })` for the part you need.\n * Every write is recorded in the page's history (`history`, `diff`,\n * `restore`); pass a `note` so the record says why.\n */\nexport class PagesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: PageListOptions): Promise<KnowledgePage[]> {\n return await this.client.page.list.query(options) as KnowledgePage[];\n }\n\n /** One page. Markdown body only unless `format` says otherwise. */\n async get(id: string, options: PageGetOptions = {}): Promise<KnowledgePage> {\n return await this.client.page.get.query({\n id,\n format: options.format ?? 'markdown',\n ...(options.section ? { section: options.section } : {}),\n }) as KnowledgePage;\n }\n\n /** The page's headings (level, text, line) and `bodyBytes`, no body. */\n async outline(id: string): Promise<KnowledgePage> {\n return await this.get(id, { format: 'outline' });\n }\n\n /**\n * Pages about something: semantic hits from the Knowledge index first\n * (nearest first, with the matching passage as `snippet`), then pages whose\n * title or body contain the query. Only pages the caller can view.\n */\n async search(options: PageSearchOptions): Promise<PageSearchOutput> {\n return await this.client.page.search.query(options) as PageSearchOutput;\n }\n\n async create(input: PageCreateInput): Promise<KnowledgePage> {\n return await this.client.page.create.mutate(input) as KnowledgePage;\n }\n\n async update(input: PageUpdateInput): Promise<KnowledgePage> {\n return await this.client.page.update.mutate(input) as KnowledgePage;\n }\n\n /** The page's revisions, newest first — who, when, why, size. Never the bodies. */\n async history(id: string, options: PageHistoryOptions = {}): Promise<PageHistory> {\n return await this.client.page.history.query({ id, ...options }) as PageHistory;\n }\n\n /** One revision with its Markdown body. */\n async revision(pageId: string, revisionId: string): Promise<PageRevisionDetail> {\n return await this.client.page.revision.query({ id: pageId, revisionId }) as PageRevisionDetail;\n }\n\n /** What a revision changed, as a unified diff of the Markdown. */\n async diff(pageId: string, revisionId: string, options: PageDiffOptions = {}): Promise<PageDiff> {\n return await this.client.page.diff.query({\n id: pageId,\n revisionId,\n against: options.against ?? 'previous',\n }) as PageDiff;\n }\n\n /**\n * Put a revision's content back as the page's current content. A forward\n * write: `docVersion` bumps and a \"restore\" revision is recorded.\n */\n async restore(\n pageId: string,\n revisionId: string,\n options: PageRestoreOptions = {},\n ): Promise<{ id: string; docVersion: number; revisionId: string }> {\n return await this.client.page.restore.mutate({ id: pageId, revisionId, ...options }) as {\n id: string;\n docVersion: number;\n revisionId: string;\n };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { ReadStatus, Resource, ResourceContentType } from './types/resource.js';\n\nexport interface ResourceListOptions {\n workspaceId?: string;\n projectId?: string;\n contentType?: ResourceContentType;\n /**\n * Reading-list filter. `'unread'` is the queue (`to_read` + `reading`);\n * a single status narrows to that status; omitted applies no read filter.\n */\n readStatus?: ReadStatus | 'unread';\n search?: string;\n tags?: string[];\n includeArchived?: boolean;\n limit?: number;\n cursor?: string;\n}\n\nexport interface ResourceListResult {\n resources: Resource[];\n nextCursor?: string;\n}\n\nexport interface ResourceCreateInput {\n title: string;\n url?: string;\n description?: string;\n /** Pasted body. Only a Resource with content is embedded for search. */\n content?: string;\n contentType?: ResourceContentType;\n tags?: string[];\n workspaceId?: string;\n projectId?: string;\n /** Defaults to `to_read` server-side, so a saved link lands in the Reading list. */\n readStatus?: ReadStatus;\n /** Defaults to true server-side; a no-op when there is no content to embed. */\n generateEmbeddings?: boolean;\n}\n\n/** Fields `update` may change. `tags` replaces the whole set. */\nexport interface ResourceUpdateInput {\n title?: string;\n description?: string;\n tags?: string[];\n readStatus?: ReadStatus;\n}\n\nexport interface ResourceReadState {\n id: string;\n readStatus: ReadStatus | string;\n readAt: Date | null;\n}\n\n/**\n * Resources: ingested external content (saved links, PDFs, pasted notes).\n * The Reading list is `list({ readStatus: 'unread' })`; `save` is the\n * quick-add that files a URL as a `bookmark` to read.\n *\n * Indexing follows content, never read state: a bare URL has nothing to\n * embed and is findable by title and URL only.\n */\nexport class ResourcesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ResourceListOptions = {}): Promise<ResourceListResult> {\n return await this.client.resource.list.query(options) as ResourceListResult;\n }\n\n async create(input: ResourceCreateInput): Promise<Resource> {\n const result = await this.client.resource.create.mutate(input) as { resource: Resource };\n return result.resource;\n }\n\n async get(id: string): Promise<Resource> {\n const result = await this.client.resource.get.query({ id }) as { resource: Resource };\n return result.resource;\n }\n\n async update(id: string, input: ResourceUpdateInput): Promise<Resource> {\n const result = await this.client.resource.update.mutate({ id, ...input }) as { resource: Resource };\n return result.resource;\n }\n\n /**\n * Save a link to the Reading list: a `bookmark` in `to_read`, not embedded.\n *\n * `tags` are added to the ones the link already has. The server dedupes by\n * URL and would replace the set on re-save, so the link is saved untagged\n * (which leaves existing tags alone) and the union written after.\n */\n async save(input: {\n url: string;\n title?: string;\n note?: string;\n tags?: string[];\n workspaceId?: string;\n readStatus?: ReadStatus;\n }): Promise<Resource> {\n const resource = await this.create({\n title: input.title?.trim() || hostnameOf(input.url) || input.url,\n url: input.url,\n description: input.note,\n contentType: 'bookmark',\n readStatus: input.readStatus ?? 'to_read',\n generateEmbeddings: false,\n workspaceId: input.workspaceId,\n });\n const existing = resource.tags ?? [];\n const added = (input.tags ?? []).filter((t) => !existing.includes(t));\n if (added.length === 0) return resource;\n return await this.update(resource.id, { tags: [...existing, ...added] });\n }\n\n async setReadStatus(id: string, readStatus: ReadStatus): Promise<ResourceReadState> {\n return await this.client.resource.setReadStatus.mutate({ id, readStatus }) as ResourceReadState;\n }\n\n async archive(id: string): Promise<{ success: boolean }> {\n return await this.client.resource.archive.mutate({ id }) as { success: boolean };\n }\n}\n\nfunction hostnameOf(url: string): string | null {\n try {\n return new URL(url).hostname.replace(/^www\\./, '');\n } catch {\n return null;\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Feature } from './types/feature.js';\nimport type { Requirement, RequirementKind } from './types/requirement.js';\n\nexport interface RequirementListOptions {\n featureId: string;\n /** Only requirements pinned to this scope. */\n scopeId?: string;\n}\n\nexport interface RequirementCreateInput {\n featureId: string;\n /** Pin the requirement to one of the feature's scopes. */\n scopeId?: string;\n /** One EARS-style \"shall\" statement. */\n statement: string;\n kind?: RequirementKind;\n}\n\n/**\n * Requirements on a feature (EARS-style \"shall\" statements, checkable\n * met/unmet). Replaces user stories as the requirements mechanism.\n *\n * Mirrors the `UserStoriesApi` shape: `list` derives from the feature's\n * `getById` payload, which includes `requirements` ordered by\n * `displayOrder` - there is no dedicated list procedure.\n */\nexport class RequirementsApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: RequirementListOptions): Promise<Requirement[]> {\n const feature = await this.client.product.feature.getById.query({\n id: options.featureId,\n }) as Feature & { requirements?: Requirement[] };\n const requirements = feature.requirements ?? [];\n return options.scopeId\n ? requirements.filter((r) => r.scopeId === options.scopeId)\n : requirements;\n }\n\n async create(input: RequirementCreateInput): Promise<Requirement> {\n return await this.client.product.feature.addRequirement.mutate(\n input,\n ) as Requirement;\n }\n\n /** Mark a requirement met (true) or unmet (false). */\n async setChecked(id: string, checked: boolean): Promise<Requirement> {\n return await this.client.product.feature.setRequirementChecked.mutate({\n id,\n checked,\n }) as Requirement;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.deleteRequirement.mutate({\n id,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type { Feature, FeatureScope, FeatureScopeStatus } from './types/feature.js';\n\nexport interface ScopeListOptions {\n featureId: string;\n}\n\nexport interface ScopeCreateInput {\n featureId: string;\n /** Short label for the increment, e.g. \"V1\" or \"V2: auto-sync\". */\n version: string;\n description: string;\n status?: FeatureScopeStatus;\n shippedAt?: Date;\n}\n\nexport interface ScopeUpdateInput {\n id: string;\n version?: string;\n description?: string;\n status?: FeatureScopeStatus;\n shippedAt?: Date | null;\n displayOrder?: number;\n}\n\n/**\n * Feature scopes: shippable increments of a feature (\"V1\", \"V2\"), each with\n * its own lifecycle. Setting a scope SHIPPED stamps `shippedAt` server-side\n * and rolls the feature's status up (any live scope makes the feature Live).\n *\n * Mirrors the `UserStoriesApi` shape: `list` derives from the feature's\n * `getById` payload, which includes `scopes` ordered by `displayOrder` -\n * there is no dedicated list procedure.\n */\nexport class ScopesApi {\n constructor(private client: TrpcClient) {}\n\n async list(options: ScopeListOptions): Promise<FeatureScope[]> {\n const feature = await this.client.product.feature.getById.query({\n id: options.featureId,\n }) as Feature & { scopes?: FeatureScope[] };\n return feature.scopes ?? [];\n }\n\n async create(input: ScopeCreateInput): Promise<FeatureScope> {\n return await this.client.product.feature.addScope.mutate(\n input,\n ) as FeatureScope;\n }\n\n async update(input: ScopeUpdateInput): Promise<FeatureScope> {\n return await this.client.product.feature.updateScope.mutate(\n input,\n ) as FeatureScope;\n }\n\n async delete(id: string): Promise<{ success: boolean }> {\n return await this.client.product.feature.deleteScope.mutate({\n id,\n }) as { success: boolean };\n }\n}\n","import type { TrpcClient } from './client.js';\nimport type {\n GlobalSearchOptions,\n GlobalSearchOutput,\n KnowledgeSearchOptions,\n KnowledgeSearchOutput,\n} from './types/search.js';\n\nexport class SearchApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * Global text search across the entities the caller can access — the same\n * coverage as the app's Cmd+K palette (projects, actions, goals,\n * workspaces, and other entity types as the API grows). Matches titles;\n * for pages by meaning use `knowledge` or `PagesApi.search`.\n */\n async global(options: GlobalSearchOptions): Promise<GlobalSearchOutput> {\n return (await this.client.search.global.query(options)) as GlobalSearchOutput;\n }\n\n /**\n * Semantic search over one workspace's Knowledge index — the caller's own\n * indexed meetings, resources, documents and pages, scored by meaning. Each\n * source contributes its best-matching passage. Costs an embedding call;\n * never throws for an index failure (returns no results instead).\n */\n async knowledge(options: KnowledgeSearchOptions): Promise<KnowledgeSearchOutput> {\n return (await this.client.search.knowledge.query(options)) as KnowledgeSearchOutput;\n }\n}\n","import type { TrpcClient } from './client.js';\n\nexport type TimeEntryStatus = 'PROPOSED' | 'CONFIRMED';\n\n/**\n * Where an entry came from. `plugin` is the legacy stamp of the in-app Timer\n * and calendar grids; new writes use the other three. `claude-desktop` is\n * Proposed time from the Daily worklog, `agent-run` is Agent-run time (an\n * agent working with no human turns, kept off the owner's attention totals).\n */\nexport type TimeEntrySource = 'plugin' | 'manual' | 'claude-desktop' | 'agent-run';\n\nexport interface TimeEntry {\n id: string;\n /** Whose time it is. Under an agent key this is the agent's OWNER (ADR-0061). */\n userId: string;\n actionId: string;\n workspaceId: string | null;\n startedAt: Date;\n endedAt: Date | null;\n source: string;\n status: TimeEntryStatus;\n /** Idempotency key, e.g. `claude-session:<sessionId>#<segmentIndex>`. */\n sourceRef: string | null;\n note: string | null;\n /** The external agent that wrote the row; null for human-made entries. */\n createdByAgentId: string | null;\n action: {\n id: string;\n name: string;\n projectId: string | null;\n workspaceId: string | null;\n };\n}\n\nexport interface TimeLogInput {\n actionId: string;\n startedAt: Date;\n endedAt: Date;\n /** Defaults to `manual` server-side. */\n source?: Exclude<TimeEntrySource, 'plugin'>;\n /**\n * Ignored under an agent key: agent-written entries are always PROPOSED.\n * A human's entry defaults to CONFIRMED.\n */\n status?: TimeEntryStatus;\n /**\n * With a `sourceRef` the write is idempotent per owner: a re-run updates a\n * PROPOSED entry in place and leaves a CONFIRMED one alone.\n */\n sourceRef?: string;\n /** One line shown in the day view and list row (max 1000 chars). */\n note?: string;\n}\n\n/**\n * `created` / `updated` — proposed pieces were written; `left` — a CONFIRMED\n * row already carries this ref and was not touched; `merged` — manual time\n * on the same Action covers it, so the manual entries were annotated instead\n * (V2, manual wins); `dropped` — manual time on other Actions covered every\n * minute, nothing written.\n */\nexport type TimeLogOutcome = 'created' | 'updated' | 'left' | 'merged' | 'dropped';\n\nexport interface TimeLogResult {\n /** The first written piece, or the untouched CONFIRMED row; null for merged/dropped. */\n entry: TimeEntry | null;\n outcome: TimeLogOutcome;\n /** Every piece written — several when manual time on another Action split the proposal. */\n pieces?: TimeEntry[];\n /** Manual entry ids whose note now carries the conversation reference. */\n mergedInto?: string[];\n}\n\nexport interface DayReportEntry extends TimeEntry {\n /** Whole minutes inside the day window (a running entry ends \"now\"). */\n minutes: number;\n /** `ticket.productId ?? project.productId ?? null`. */\n productId: string | null;\n productName: string | null;\n isAgentRun: boolean;\n flags: Array<'forgotten-timer'>;\n action: TimeEntry['action'] & {\n ticketId: string | null;\n project: { id: string; name: string; productId: string | null } | null;\n ticket: { id: string; number: number; shortId: string | null; title: string; productId: string } | null;\n };\n}\n\nexport interface DayReportProductRow {\n /** Null is Unassigned time. */\n productId: string | null;\n name: string;\n /** Overlap-split minutes; the rows sum to `attentionMinutes`. */\n minutes: number;\n}\n\nexport interface DayReportActionRow {\n actionId: string;\n name: string;\n /** Overlap-split minutes; the rows sum to `attentionMinutes`. */\n minutes: number;\n /** Plain sum of the Action's non-agent-run entries. */\n sessionMinutes: number;\n agentRunMinutes: number;\n productId: string | null;\n productName: string | null;\n projectId: string | null;\n projectName: string | null;\n ticket: { id: string; number: number; shortId: string | null; title: string } | null;\n proposedCount: number;\n}\n\n/**\n * One day of a person's time — the same numbers the `/time` Day tab shows.\n * Attention minutes count each covered minute once; session minutes are the\n * plain sum; Agent-run time is kept off both and reported on its own.\n */\nexport interface DayReport {\n dayStart: Date;\n dayEnd: Date;\n entries: DayReportEntry[];\n attentionMinutes: number;\n sessionMinutes: number;\n agentRunMinutes: number;\n byProduct: DayReportProductRow[];\n byAction: DayReportActionRow[];\n /** Non-agent-run entries whose Action has neither Ticket nor Project. */\n unassignedCount: number;\n proposedCount: number;\n flags: Array<{ entryId: string; flag: 'forgotten-timer' }>;\n}\n\nexport interface TimeConfirmDayResult {\n /** Proposed entries flipped to CONFIRMED. */\n confirmed: number;\n}\n\nexport interface TimeLogBatchResult {\n index: number;\n success: boolean;\n sourceRef?: string;\n /** Null when the outcome is `merged` or `dropped`. */\n entry?: TimeEntry | null;\n outcome?: TimeLogOutcome;\n pieces?: TimeEntry[];\n mergedInto?: string[];\n error?: string;\n}\n\nfunction startOfLocalDay(date: Date | string): Date {\n const d =\n typeof date === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(date)\n ? new Date(`${date}T00:00:00`)\n : new Date(date);\n if (Number.isNaN(d.getTime())) {\n throw new Error(`Invalid date: \"${String(date)}\". Use YYYY-MM-DD or an ISO timestamp.`);\n }\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\n/**\n * Time entries — the Daily worklog's write path (ADR-0061).\n *\n * The thing to know: an entry always belongs to the person whose time it\n * was. Called with an external-agent key, {@link log} writes an entry OWNED\n * by the agent's owner, records the agent as author and forces it to\n * `PROPOSED`; it shows on the owner's `/time` with a \"proposed\" chip and\n * stays out of `Action.timeSpentMins` until the owner confirms the day.\n * Manual time is never altered by these calls.\n */\nexport class TimeApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * Log one completed entry with explicit bounds. Never starts, stops or\n * alters the running Timer. With `sourceRef` the call is an upsert keyed\n * on (owner, sourceRef); without it every call creates a row.\n */\n async log(input: TimeLogInput): Promise<TimeLogResult> {\n if (input.sourceRef) {\n return (await this.client.timeEntry.upsertBySourceRef.mutate({\n ...input,\n sourceRef: input.sourceRef,\n })) as TimeLogResult;\n }\n const entry = (await this.client.timeEntry.create.mutate(input)) as TimeEntry;\n return { entry, outcome: 'created', pieces: [entry], mergedInto: [] };\n }\n\n /**\n * Log many entries, one call each and in order, so a failure names the\n * entry it belonged to instead of rejecting the whole batch. `defaults`\n * fill any field an entry leaves out.\n */\n async logBatch(\n entries: Partial<TimeLogInput>[],\n defaults: Partial<TimeLogInput> = {},\n ): Promise<TimeLogBatchResult[]> {\n const results: TimeLogBatchResult[] = [];\n for (const [index, item] of entries.entries()) {\n const merged = { ...defaults, ...item };\n const sourceRef = merged.sourceRef;\n try {\n if (!merged.actionId) throw new Error('actionId is required');\n if (!merged.startedAt || !merged.endedAt) {\n throw new Error('startedAt and endedAt are required');\n }\n const result = await this.log(merged as TimeLogInput);\n results.push({ index, success: true, sourceRef, ...result });\n } catch (error) {\n results.push({\n index,\n success: false,\n sourceRef,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n return results;\n }\n\n /**\n * Confirm a day: every PROPOSED entry of yours that starts on that local\n * calendar day becomes CONFIRMED and the Actions' spent time moves. Human\n * only — the server refuses agent keys, so run this with personal\n * credentials. A day with nothing proposed returns `{ confirmed: 0 }`.\n */\n async confirmDay(date: Date | string, workspaceId?: string): Promise<TimeConfirmDayResult> {\n return (await this.client.timeEntry.confirmDay.mutate({\n date: startOfLocalDay(date),\n workspaceId,\n })) as TimeConfirmDayResult;\n }\n\n /**\n * The day report for one local calendar day: entries joined to Action,\n * Ticket, Project and Product, attention / session / agent-run minutes,\n * the overlap-split roll-ups and the counts — exactly what the `/time` Day\n * tab and the Daily summary's Yesterday line read. Under an agent key the\n * report is the OWNER's day.\n */\n async dayReport(date: Date | string, workspaceId?: string): Promise<DayReport> {\n return (await this.client.timeEntry.dayReport.query({\n date: startOfLocalDay(date),\n workspaceId,\n })) as DayReport;\n }\n\n /**\n * The caller's entries that touch one calendar day (local time), oldest\n * first, each with its `status`. Pass `YYYY-MM-DD` or a Date.\n */\n async list(date: Date | string, workspaceId?: string): Promise<TimeEntry[]> {\n const startDate = startOfLocalDay(date);\n const endDate = new Date(startDate.getTime() + 24 * 60 * 60 * 1000);\n return (await this.client.timeEntry.listByDateRange.query({\n startDate,\n endDate,\n workspaceId,\n })) as TimeEntry[];\n }\n}\n","import type { TrpcClient } from './client.js';\n\n/**\n * Agent runs — the local runner's side of an Assistant run (Exponential\n * ADR-0067, \"Local runner (V2) procedures\" in dev-docs/AGENT_RUNS.md).\n *\n * An Assistant whose executor is LOCAL_CLI is never run by the hosted\n * dispatcher: a process on its owner's machine claims the run with the\n * Assistant's `exp_agent_` key, does the work with the owner's own tools,\n * streams what it did as events, and finishes. Every method needs an\n * **agent-key** client (a personal token or a run token is FORBIDDEN), and\n * every run is resolved through the key's own agent — a run id alone never\n * reaches another agent's work.\n */\n\nexport type AgentRunStatus =\n | 'QUEUED'\n | 'RUNNING'\n | 'WAITING_ON_OWNER'\n | 'SUCCEEDED'\n | 'FAILED'\n | 'CANCELLED'\n | 'TIMED_OUT';\n\nexport type RunnerEventKind = 'status' | 'tool_call' | 'tool_result' | 'text' | 'log' | 'error';\n\n/** One line of a run's transcript. The runner numbers `seq` itself, from 1, monotonically. */\nexport interface RunnerEvent {\n seq: number;\n kind: RunnerEventKind;\n payload: Record<string, unknown>;\n}\n\n/** A chat-shaped message the runner feeds to its CLI: the persona, then the brief. */\nexport interface RunMessage {\n role: 'system' | 'user';\n content: string;\n}\n\n/** What `claim` hands the runner: the run, the action, the owner, and the exact persona + brief the hosted executor would use. */\nexport interface ClaimedRun {\n id: string;\n actionId: string;\n predecessorId: string | null;\n claimedBy: string | null;\n startedAt: Date | string | null;\n action: {\n id: string;\n name: string;\n description: string | null;\n workspaceId: string | null;\n project: { id: string; name: string } | null;\n };\n owner: { id: string; name: string | null };\n messages: RunMessage[];\n}\n\nexport interface HeartbeatResult {\n /** false — the run left RUNNING (a cancel): stop now. */\n ok: boolean;\n lastEventAt: Date | string | null;\n}\n\nexport interface AppendEventsResult {\n /** Rows actually inserted; a retried batch inserts only the seqs not yet stored. */\n inserted: number;\n newToolCalls: number;\n toolCallCount: number;\n}\n\nexport type FinishInput =\n | {\n status: 'SUCCEEDED';\n /** Public: the requester, the owner and their teammates read it. */\n summary?: string;\n readyToClose?: boolean;\n usage?: Record<string, unknown>;\n }\n | { status: 'FAILED'; error?: string; summary?: string; usage?: Record<string, unknown> }\n | {\n status: 'WAITING_ON_OWNER';\n /** Required: the app posts it as a comment mentioning the owner and parks the run. */\n question: string;\n summary?: string;\n usage?: Record<string, unknown>;\n };\n\nexport interface FinishResult {\n /** false — a cancel landed first; nothing was posted. */\n finished: boolean;\n status: AgentRunStatus;\n /** The ask-owner comment, for WAITING_ON_OWNER. */\n commentId?: string | null;\n}\n\nexport class AgentRunsApi {\n constructor(private client: TrpcClient) {}\n\n /**\n * Claim the oldest queued LOCAL_CLI run of this key's Assistant, or null when\n * nothing is queued. `runnerId` names this machine/process; it is recorded on\n * the run and checked by the other calls.\n */\n async claim(runnerId: string): Promise<ClaimedRun | null> {\n return (await this.client.agentRun.claim.mutate({ runnerId })) as ClaimedRun | null;\n }\n\n /** Keep the run alive while a step is slow (the app times out a silent run after 5 minutes). */\n async heartbeat(runId: string, runnerId?: string): Promise<HeartbeatResult> {\n return (await this.client.agentRun.heartbeat.mutate({ runId, runnerId })) as HeartbeatResult;\n }\n\n /**\n * Append transcript events (1–200 per call). Idempotent on `seq`, so a batch\n * may be retried after a network error without duplicating lines.\n */\n async appendEvents(runId: string, events: RunnerEvent[], runnerId?: string): Promise<AppendEventsResult> {\n return (await this.client.agentRun.appendEvents.mutate({ runId, runnerId, events })) as AppendEventsResult;\n }\n\n /** End the run: succeeded, failed, or waiting on the owner's answer to `question`. */\n async finish(runId: string, input: FinishInput, runnerId?: string): Promise<FinishResult> {\n return (await this.client.agentRun.finish.mutate({ runId, runnerId, ...input })) as FinishResult;\n }\n}\n","import Conf from 'conf';\n\nexport interface ExponentialConfig {\n apiUrl: string;\n token: string;\n tokenExpiry?: string;\n defaultWorkspaceId?: string;\n defaultWorkspaceSlug?: string;\n}\n\nconst schema = {\n apiUrl: {\n type: 'string' as const,\n default: '',\n },\n token: {\n type: 'string' as const,\n default: '',\n },\n tokenExpiry: {\n type: 'string' as const,\n default: '',\n },\n defaultWorkspaceId: {\n type: 'string' as const,\n default: '',\n },\n defaultWorkspaceSlug: {\n type: 'string' as const,\n default: '',\n },\n};\n\nfunction createStore(projectName: string) {\n return new Conf<ExponentialConfig>({\n projectName,\n schema,\n });\n}\n\nfunction readConfig(store: Conf<ExponentialConfig>): ExponentialConfig {\n return {\n apiUrl: store.get('apiUrl'),\n token: store.get('token'),\n tokenExpiry: store.get('tokenExpiry'),\n defaultWorkspaceId: store.get('defaultWorkspaceId'),\n defaultWorkspaceSlug: store.get('defaultWorkspaceSlug'),\n };\n}\n\nfunction writeConfig(store: Conf<ExponentialConfig>, values: Partial<ExponentialConfig>): void {\n if (values.apiUrl !== undefined) store.set('apiUrl', values.apiUrl);\n if (values.token !== undefined) store.set('token', values.token);\n if (values.tokenExpiry !== undefined) store.set('tokenExpiry', values.tokenExpiry);\n if (values.defaultWorkspaceId !== undefined) store.set('defaultWorkspaceId', values.defaultWorkspaceId);\n if (values.defaultWorkspaceSlug !== undefined) store.set('defaultWorkspaceSlug', values.defaultWorkspaceSlug);\n}\n\nconst defaultStore = createStore('exponential-sdk');\n\nexport function createConfigStore(options?: { projectName?: string }) {\n const store = createStore(options?.projectName ?? 'exponential-sdk');\n\n return {\n loadConfig: () => readConfig(store),\n saveConfig: (values: Partial<ExponentialConfig>) => writeConfig(store, values),\n clearConfig: () => store.clear(),\n isAuthenticated: () => {\n const cfg = readConfig(store);\n return Boolean(cfg.token && cfg.apiUrl);\n },\n getConfigPath: () => store.path,\n };\n}\n\nexport function loadConfig(): ExponentialConfig {\n return readConfig(defaultStore);\n}\n\nexport function saveConfig(values: Partial<ExponentialConfig>): void {\n writeConfig(defaultStore, values);\n}\n\nexport function clearConfig(): void {\n defaultStore.clear();\n}\n\nexport function isAuthenticated(): boolean {\n const cfg = readConfig(defaultStore);\n return Boolean(cfg.token && cfg.apiUrl);\n}\n\nexport function getConfigPath(): string {\n return defaultStore.path;\n}\n","/**\n * Worklog segments (CONTEXT.md \"Worklog segment\"): cut a conversation into\n * the stretches of a person's attention it actually held. Pure — it lives in\n * the SDK because the Daily worklog that needs it runs outside the app\n * (decision 2026-09-12).\n */\n\nexport interface ConversationMessage {\n at: Date | string;\n role: 'user' | 'assistant';\n}\n\nexport interface WorklogSegment {\n start: Date;\n end: Date;\n /** Number of the person's messages inside. `0` marks an Agent-run stretch. */\n humanTurns: number;\n}\n\n/** Silence between the person's messages that ends a segment. */\nexport const DEFAULT_GAP_MINUTES = 30;\n/** Segment bounds are rounded outward to this grain. */\nexport const ROUND_MINUTES = 5;\n\nfunction roundDown(ms: number): Date {\n const grain = ROUND_MINUTES * 60_000;\n return new Date(Math.floor(ms / grain) * grain);\n}\n\nfunction roundUp(ms: number): Date {\n const grain = ROUND_MINUTES * 60_000;\n return new Date(Math.ceil(ms / grain) * grain);\n}\n\n/**\n * Rules:\n * - a segment opens at a user message and, as long as the person keeps\n * replying within `gapMinutes` of their previous message, runs to the\n * last reply before the next gap (CONTEXT.md: \"starts at the person's\n * first message and ends at the last reply\");\n * - the exception is unattended work: once the assistant has been talking\n * alone for longer than `gapMinutes` since the person's last message, the\n * rest of that run — when it lasts longer than `gapMinutes` itself — is\n * a separate segment with `humanTurns: 0`, and the person's segment ends\n * at the last message inside the window. A shorter tail is just the reply\n * and stays in the person's segment — but only when it starts within\n * `gapMinutes` of the window closing (two gaps after the person's last\n * message). A short burst that comes later, e.g. the assistant speaking\n * just before the person resumes days afterwards, belongs to no segment;\n * - an agent-run ends at a silence longer than two gaps: whatever the\n * assistant says after it starts a new candidate run, so a Monitor ticking\n * every few hours is not one unbroken stretch. A shorter silence is a long\n * tool call inside the run;\n * - every segment is rounded outward to 5 minutes.\n */\nexport function segmentConversation(\n messages: ConversationMessage[],\n gapMinutes = DEFAULT_GAP_MINUTES,\n): WorklogSegment[] {\n const gapMs = gapMinutes * 60_000;\n const sorted = messages\n .map((m) => ({ at: new Date(m.at).getTime(), role: m.role }))\n .filter((m) => !Number.isNaN(m.at))\n .sort((a, b) => a.at - b.at);\n\n const out: WorklogSegment[] = [];\n let seg: { start: number; end: number; humanTurns: number; lastUserAt: number } | null = null;\n // Assistant messages beyond the person's window: a candidate agent-run.\n let run: { start: number; end: number } | null = null;\n\n const closeSegment = () => {\n if (seg) out.push({ start: roundDown(seg.start), end: roundUp(seg.end), humanTurns: seg.humanTurns });\n seg = null;\n };\n const resolveRun = () => {\n if (!run) return;\n if (run.end - run.start > gapMs) {\n closeSegment();\n out.push({ start: roundDown(run.start), end: roundUp(run.end), humanTurns: 0 });\n } else if (seg && run.start - seg.lastUserAt <= 2 * gapMs) {\n seg.end = Math.max(seg.end, run.end);\n }\n run = null;\n };\n\n for (const m of sorted) {\n if (m.role === 'user') {\n resolveRun();\n if (seg && m.at - seg.lastUserAt > gapMs) closeSegment();\n if (!seg) seg = { start: m.at, end: m.at, humanTurns: 0, lastUserAt: m.at };\n seg.end = Math.max(seg.end, m.at);\n seg.lastUserAt = m.at;\n seg.humanTurns += 1;\n continue;\n }\n if (run) {\n if (m.at - run.end > 2 * gapMs) {\n resolveRun();\n run = { start: m.at, end: m.at };\n } else {\n run.end = m.at;\n }\n } else if (!seg || m.at - seg.lastUserAt > gapMs) {\n run = { start: m.at, end: m.at };\n } else {\n seg.end = Math.max(seg.end, m.at);\n }\n }\n resolveRun();\n closeSegment();\n return out;\n}\n","import { createClient, isTRPCError, TRPCClientError, type TrpcClient } from './client.js';\nimport { ActionsApi } from './actions.js';\nimport { ActionCommentsApi } from './actionComments.js';\nimport { FeatureCommentsApi } from './featureComments.js';\nimport { PageCommentsApi } from './pageComments.js';\nimport { GoalCommentsApi } from './goalComments.js';\nimport { GoalsApi } from './goals.js';\nimport { KeyResultsApi } from './keyResults.js';\nimport { ProjectsApi } from './projects.js';\nimport { WorkspacesApi } from './workspaces.js';\nimport { ContactsApi } from './contacts.js';\nimport { DecisionsApi } from './decisions.js';\nimport { OrganizationsApi } from './organizations.js';\nimport { PipelinesApi } from './pipelines.js';\nimport { TicketsApi } from './tickets.js';\nimport { ProductsApi } from './products.js';\nimport { FeaturesApi } from './features.js';\nimport { UserStoriesApi } from './userStories.js';\nimport { EpicsApi } from './epics.js';\nimport { LabelsApi } from './labels.js';\nimport { AreasApi } from './areas.js';\nimport { MeetingsApi } from './meetings.js';\nimport { PagesApi } from './pages.js';\nimport { ResourcesApi } from './resources.js';\nimport { RequirementsApi } from './requirements.js';\nimport { ScopesApi } from './scopes.js';\nimport { SearchApi } from './search.js';\nimport { TimeApi } from './time.js';\nimport { AgentRunsApi } from './agentRuns.js';\n\nexport class ExponentialClient {\n private client: TrpcClient;\n actions: ActionsApi;\n actionComments: ActionCommentsApi;\n featureComments: FeatureCommentsApi;\n pageComments: PageCommentsApi;\n goalComments: GoalCommentsApi;\n goals: GoalsApi;\n /** Same instance as `goals.keyResults`. */\n keyResults: KeyResultsApi;\n projects: ProjectsApi;\n workspaces: WorkspacesApi;\n contacts: ContactsApi;\n decisions: DecisionsApi;\n organizations: OrganizationsApi;\n pipelines: PipelinesApi;\n tickets: TicketsApi;\n products: ProductsApi;\n features: FeaturesApi;\n userStories: UserStoriesApi;\n epics: EpicsApi;\n labels: LabelsApi;\n areas: AreasApi;\n meetings: MeetingsApi;\n pages: PagesApi;\n resources: ResourcesApi;\n requirements: RequirementsApi;\n scopes: ScopesApi;\n search: SearchApi;\n /** Time entries — the Daily worklog's write path (ADR-0061). */\n time: TimeApi;\n /** Agent runs — the local runner's claim/heartbeat/append/finish (ADR-0067); agent-key only. */\n agentRuns: AgentRunsApi;\n\n constructor(private config: { token: string; apiUrl: string }) {\n this.client = createClient(this.config);\n this.actions = new ActionsApi(this.client);\n this.actionComments = new ActionCommentsApi(this.client);\n this.featureComments = new FeatureCommentsApi(this.client);\n this.pageComments = new PageCommentsApi(this.client);\n this.goalComments = new GoalCommentsApi(this.client);\n this.keyResults = new KeyResultsApi(this.client);\n this.goals = new GoalsApi(this.client, this.keyResults);\n this.projects = new ProjectsApi(this.client);\n this.workspaces = new WorkspacesApi(this.client);\n this.contacts = new ContactsApi(this.client);\n this.decisions = new DecisionsApi(this.client);\n this.organizations = new OrganizationsApi(this.client);\n this.pipelines = new PipelinesApi(this.client);\n this.tickets = new TicketsApi(this.client);\n this.products = new ProductsApi(this.client);\n this.features = new FeaturesApi(this.client);\n this.userStories = new UserStoriesApi(this.client);\n this.epics = new EpicsApi(this.client);\n this.labels = new LabelsApi(this.client);\n this.areas = new AreasApi(this.client);\n this.meetings = new MeetingsApi(this.client);\n this.pages = new PagesApi(this.client);\n this.resources = new ResourcesApi(this.client);\n this.requirements = new RequirementsApi(this.client);\n this.scopes = new ScopesApi(this.client);\n this.search = new SearchApi(this.client);\n this.time = new TimeApi(this.client);\n this.agentRuns = new AgentRunsApi(this.client);\n }\n}\n\nexport {\n createConfigStore,\n loadConfig,\n saveConfig,\n clearConfig,\n isAuthenticated,\n getConfigPath,\n} from './config.js';\n\nexport type { ExponentialConfig } from './config.js';\nexport type {\n Action,\n ActionOutput,\n ActionsListOutput,\n KanbanStatus,\n Priority,\n} from './types/action.js';\nexport type {\n ActionCreateInput,\n ActionUpdateInput,\n ActionUpsertBySourceInput,\n ActionUpsertBySourceResult,\n ActionStatus,\n TodaysActions,\n TodaysActionsGroup,\n TodaysActionRow,\n OverdueTriage,\n OverdueCohort,\n OverdueTriageRow,\n} from './actions.js';\nexport type {\n Project,\n ProjectDetail,\n ProjectKeyResultLink,\n ProjectOutput,\n ProjectPriority,\n ProjectStatus,\n ProjectsListOutput,\n} from './types/project.js';\nexport type { ProjectUpdateInput, ProjectsListOptions } from './projects.js';\nexport type {\n Workspace,\n WorkspaceMember,\n WorkspaceOutput,\n WorkspacesListOutput,\n} from './types/workspace.js';\nexport type {\n Contact,\n ContactInteraction,\n ContactListOutput,\n InteractionType,\n InteractionDirection,\n} from './types/contact.js';\nexport type {\n ContactCreateInput,\n ContactUpdateInput,\n AddInteractionInput,\n ContactsListOptions,\n EnrichContactResult,\n} from './contacts.js';\nexport type {\n Organization,\n OrganizationListOutput,\n OrganizationSize,\n} from './types/organization.js';\nexport type {\n OrganizationCreateInput,\n OrganizationsListOptions,\n} from './organizations.js';\nexport type {\n Pipeline,\n PipelineStage,\n Deal,\n DealActivity,\n} from './types/pipeline.js';\nexport type {\n DealCreateInput,\n DealUpdateInput,\n DealMoveInput,\n} from './pipelines.js';\nexport type {\n ActionComment,\n TicketComment,\n FeatureComment,\n PageComment,\n GoalComment,\n CommentAuthor,\n} from './types/comment.js';\nexport type {\n ActionCommentAddInput,\n ActionCommentUpdateInput,\n} from './actionComments.js';\nexport type {\n FeatureCommentCreateInput,\n FeatureCommentReplyInput,\n FeatureCommentUpdateInput,\n FeatureCommentThreadInput,\n} from './featureComments.js';\nexport type {\n PageCommentCreateInput,\n PageCommentUpdateInput,\n} from './pageComments.js';\nexport type {\n GoalCommentAddInput,\n GoalCommentUpdateInput,\n} from './goalComments.js';\nexport type {\n Goal,\n GoalChildSummary,\n GoalHealth,\n GoalKeyResultSummary,\n GoalLifeDomain,\n GoalPeriod,\n GoalProjectSummary,\n GoalStats,\n GoalStatus,\n GoalTreeNode,\n GoalUserSummary,\n GoalWritableStatus,\n} from './types/goal.js';\nexport type {\n GoalListOptions,\n GoalTreeOptions,\n GoalCreateInput,\n GoalUpdateInput,\n GoalSetStatusInput,\n GoalSetParentInput,\n GoalStatsOptions,\n} from './goals.js';\nexport type {\n KeyResult,\n KeyResultCheckIn,\n KeyResultFeatureLink,\n KeyResultProjectLink,\n KeyResultStatus,\n KeyResultUnit,\n ObjectiveWithKeyResults,\n} from './types/keyResult.js';\nexport type {\n KeyResultListOptions,\n KeyResultByObjectiveOptions,\n KeyResultCreateInput,\n KeyResultUpdateInput,\n KeyResultCheckInInput,\n} from './keyResults.js';\nexport type { Product } from './types/product.js';\nexport type { ProductCreateInput, ProductUpdateInput } from './products.js';\nexport type {\n Feature,\n FeatureKeyResultLink,\n FeatureScope,\n FeatureScopeStatus,\n FeatureStatus,\n} from './types/feature.js';\nexport type {\n FeatureCreateInput,\n FeatureUpdateInput,\n FeatureListOptions,\n FeatureLinkPageInput,\n} from './features.js';\nexport type { Area, AreaListOptions, AreaCreateInput } from './areas.js';\nexport type {\n Decision,\n DecisionAdrRef,\n DecisionChainRef,\n DecisionDecider,\n DecisionEvidenceTurn,\n DecisionFeatureRef,\n DecisionLink,\n DecisionListRow,\n DecisionMeetingRef,\n DecisionOccurrenceRef,\n DecisionProductRef,\n DecisionProjectRef,\n DecisionReviewState,\n DecisionSource,\n DecisionStatus,\n DecisionTicketRef,\n DecisionUserRef,\n DraftDecisionsResult,\n MeetingDecisions,\n} from './types/decision.js';\nexport type {\n DecisionCreateInput,\n DecisionDeciderInput,\n DecisionListOptions,\n DecisionSetStatusInput,\n DecisionUpdateInput,\n} from './decisions.js';\nexport type {\n Meeting,\n MeetingActionSummary,\n MeetingParticipant,\n MeetingProjectRef,\n MeetingSourceIntegration,\n MeetingWorkspaceRef,\n} from './types/meeting.js';\nexport type {\n MeetingListOptions,\n MeetingTypeFilter,\n MeetingParticipantInput,\n MeetingCreateInput,\n MeetingUpdateInput,\n} from './meetings.js';\nexport type {\n KnowledgePage,\n PageGetFormat,\n PageOutlineEntry,\n PageRevision,\n PageRevisionKind,\n PageRevisionAuthor,\n PageRevisionDetail,\n PageHistory,\n PageDiff,\n PageDiffSide,\n PageSearchResult,\n PageSearchOutput,\n} from './types/page.js';\nexport type { Resource, ResourceContentType, ReadStatus } from './types/resource.js';\nexport type {\n ResourceListOptions,\n ResourceListResult,\n ResourceCreateInput,\n ResourceUpdateInput,\n ResourceReadState,\n} from './resources.js';\nexport type {\n PageListOptions,\n PageGetOptions,\n PageSearchOptions,\n PageHistoryOptions,\n PageDiffOptions,\n PageRestoreOptions,\n PageCreateInput,\n PageUpdateInput,\n} from './pages.js';\nexport type { Requirement, RequirementKind } from './types/requirement.js';\nexport type {\n RequirementListOptions,\n RequirementCreateInput,\n} from './requirements.js';\nexport type {\n ScopeListOptions,\n ScopeCreateInput,\n ScopeUpdateInput,\n} from './scopes.js';\nexport type { UserStory } from './types/userStory.js';\nexport type {\n UserStoryCreateInput,\n UserStoryUpdateInput,\n UserStoryListOptions,\n} from './userStories.js';\nexport type {\n Ticket,\n TicketDetail,\n TicketAssignee,\n TicketDependencyEdge,\n TicketStatus,\n TicketType,\n} from './types/ticket.js';\nexport type {\n TicketListOptions,\n TicketCreateInput,\n TicketUpdateInput,\n TicketCommentAddInput,\n TicketCommentUpdateInput,\n TicketSearchOptions,\n} from './tickets.js';\nexport type { Epic, EpicStatus, EpicPriority } from './types/epic.js';\nexport type {\n EpicCreateInput,\n EpicUpdateInput,\n EpicListOptions,\n} from './epics.js';\nexport type {\n SearchResult,\n SearchResultType,\n SearchResultWorkspace,\n GlobalSearchOptions,\n GlobalSearchOutput,\n KnowledgeSourceType,\n KnowledgeSearchOptions,\n KnowledgeSearchResult,\n KnowledgeSearchOutput,\n} from './types/search.js';\nexport type { Tag, TagEntityType, TagListResult } from './types/tag.js';\nexport type {\n LabelListOptions,\n LabelCreateInput,\n SetEntityTagsInput,\n ListForEntityInput,\n SetEntityTagsResult,\n} from './labels.js';\nexport { isTRPCError, TRPCClientError };\nexport { TimeApi } from './time.js';\nexport type {\n TimeEntry,\n TimeEntryStatus,\n TimeEntrySource,\n TimeLogInput,\n TimeLogOutcome,\n TimeLogResult,\n TimeLogBatchResult,\n TimeConfirmDayResult,\n DayReport,\n DayReportEntry,\n DayReportProductRow,\n DayReportActionRow,\n} from './time.js';\nexport { segmentConversation, DEFAULT_GAP_MINUTES, ROUND_MINUTES } from './segment.js';\nexport type { ConversationMessage, WorklogSegment } from './segment.js';\nexport { AgentRunsApi } from './agentRuns.js';\nexport type {\n AgentRunStatus,\n RunnerEventKind,\n RunnerEvent,\n RunMessage,\n ClaimedRun,\n HeartbeatResult,\n AppendEventsResult,\n FinishInput,\n FinishResult,\n} from './agentRuns.js';\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exponential-sdk",
3
- "version": "1.24.0",
3
+ "version": "1.25.0",
4
4
  "description": "SDK for interacting with the Exponential API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",