exponential-sdk 1.20.1 → 1.21.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
@@ -543,6 +543,43 @@ interface TrpcClient {
543
543
  }) => Promise<unknown>;
544
544
  };
545
545
  };
546
+ /** Local-runner side of Agent runs (ADR-0067); agent-key principals only. */
547
+ agentRun: {
548
+ claim: {
549
+ mutate: (input: {
550
+ runnerId: string;
551
+ }) => Promise<unknown>;
552
+ };
553
+ heartbeat: {
554
+ mutate: (input: {
555
+ runId: string;
556
+ runnerId?: string;
557
+ }) => Promise<unknown>;
558
+ };
559
+ appendEvents: {
560
+ mutate: (input: {
561
+ runId: string;
562
+ runnerId?: string;
563
+ events: Array<{
564
+ seq: number;
565
+ kind: string;
566
+ payload: Record<string, unknown>;
567
+ }>;
568
+ }) => Promise<unknown>;
569
+ };
570
+ finish: {
571
+ mutate: (input: {
572
+ runId: string;
573
+ runnerId?: string;
574
+ status: 'SUCCEEDED' | 'FAILED' | 'WAITING_ON_OWNER';
575
+ summary?: string;
576
+ readyToClose?: boolean;
577
+ error?: string;
578
+ usage?: Record<string, unknown>;
579
+ question?: string;
580
+ }) => Promise<unknown>;
581
+ };
582
+ };
546
583
  timeEntry: {
547
584
  /** Explicit-bounds entry; never touches the running Timer (ADR-0061). */
548
585
  create: {
@@ -4349,6 +4386,110 @@ declare class TimeApi {
4349
4386
  list(date: Date | string, workspaceId?: string): Promise<TimeEntry[]>;
4350
4387
  }
4351
4388
 
4389
+ /**
4390
+ * Agent runs — the local runner's side of an Assistant run (Exponential
4391
+ * ADR-0067, "Local runner (V2) procedures" in dev-docs/AGENT_RUNS.md).
4392
+ *
4393
+ * An Assistant whose executor is LOCAL_CLI is never run by the hosted
4394
+ * dispatcher: a process on its owner's machine claims the run with the
4395
+ * Assistant's `exp_agent_` key, does the work with the owner's own tools,
4396
+ * streams what it did as events, and finishes. Every method needs an
4397
+ * **agent-key** client (a personal token or a run token is FORBIDDEN), and
4398
+ * every run is resolved through the key's own agent — a run id alone never
4399
+ * reaches another agent's work.
4400
+ */
4401
+ type AgentRunStatus = 'QUEUED' | 'RUNNING' | 'WAITING_ON_OWNER' | 'SUCCEEDED' | 'FAILED' | 'CANCELLED' | 'TIMED_OUT';
4402
+ type RunnerEventKind = 'status' | 'tool_call' | 'tool_result' | 'text' | 'log' | 'error';
4403
+ /** One line of a run's transcript. The runner numbers `seq` itself, from 1, monotonically. */
4404
+ interface RunnerEvent {
4405
+ seq: number;
4406
+ kind: RunnerEventKind;
4407
+ payload: Record<string, unknown>;
4408
+ }
4409
+ /** A chat-shaped message the runner feeds to its CLI: the persona, then the brief. */
4410
+ interface RunMessage {
4411
+ role: 'system' | 'user';
4412
+ content: string;
4413
+ }
4414
+ /** What `claim` hands the runner: the run, the action, the owner, and the exact persona + brief the hosted executor would use. */
4415
+ interface ClaimedRun {
4416
+ id: string;
4417
+ actionId: string;
4418
+ predecessorId: string | null;
4419
+ claimedBy: string | null;
4420
+ startedAt: Date | string | null;
4421
+ action: {
4422
+ id: string;
4423
+ name: string;
4424
+ description: string | null;
4425
+ workspaceId: string | null;
4426
+ project: {
4427
+ id: string;
4428
+ name: string;
4429
+ } | null;
4430
+ };
4431
+ owner: {
4432
+ id: string;
4433
+ name: string | null;
4434
+ };
4435
+ messages: RunMessage[];
4436
+ }
4437
+ interface HeartbeatResult {
4438
+ /** false — the run left RUNNING (a cancel): stop now. */
4439
+ ok: boolean;
4440
+ lastEventAt: Date | string | null;
4441
+ }
4442
+ interface AppendEventsResult {
4443
+ /** Rows actually inserted; a retried batch inserts only the seqs not yet stored. */
4444
+ inserted: number;
4445
+ newToolCalls: number;
4446
+ toolCallCount: number;
4447
+ }
4448
+ type FinishInput = {
4449
+ status: 'SUCCEEDED';
4450
+ /** Public: the requester, the owner and their teammates read it. */
4451
+ summary?: string;
4452
+ readyToClose?: boolean;
4453
+ usage?: Record<string, unknown>;
4454
+ } | {
4455
+ status: 'FAILED';
4456
+ error?: string;
4457
+ summary?: string;
4458
+ usage?: Record<string, unknown>;
4459
+ } | {
4460
+ status: 'WAITING_ON_OWNER';
4461
+ /** Required: the app posts it as a comment mentioning the owner and parks the run. */
4462
+ question: string;
4463
+ summary?: string;
4464
+ usage?: Record<string, unknown>;
4465
+ };
4466
+ interface FinishResult {
4467
+ /** false — a cancel landed first; nothing was posted. */
4468
+ finished: boolean;
4469
+ status: AgentRunStatus;
4470
+ /** The ask-owner comment, for WAITING_ON_OWNER. */
4471
+ commentId?: string | null;
4472
+ }
4473
+ declare class AgentRunsApi {
4474
+ private client;
4475
+ constructor(client: TrpcClient);
4476
+ /**
4477
+ * Claim the oldest queued LOCAL_CLI run of this key's Assistant, or null when
4478
+ * nothing is queued. `runnerId` names this machine/process; it is recorded on
4479
+ * the run and checked by the other calls.
4480
+ */
4481
+ claim(runnerId: string): Promise<ClaimedRun | null>;
4482
+ /** Keep the run alive while a step is slow (the app times out a silent run after 5 minutes). */
4483
+ heartbeat(runId: string, runnerId?: string): Promise<HeartbeatResult>;
4484
+ /**
4485
+ * Append transcript events (1–200 per call). Idempotent on `seq`, so a batch
4486
+ * may be retried after a network error without duplicating lines.
4487
+ */
4488
+ appendEvents(runId: string, events: RunnerEvent[], runnerId?: string): Promise<AppendEventsResult>;
4489
+ /** End the run: succeeded, failed, or waiting on the owner's answer to `question`. */
4490
+ finish(runId: string, input: FinishInput, runnerId?: string): Promise<FinishResult>;
4491
+ }
4492
+
4352
4493
  interface ExponentialConfig {
4353
4494
  apiUrl: string;
4354
4495
  token: string;
@@ -4445,10 +4586,12 @@ declare class ExponentialClient {
4445
4586
  search: SearchApi;
4446
4587
  /** Time entries — the Daily worklog's write path (ADR-0061). */
4447
4588
  time: TimeApi;
4589
+ /** Agent runs — the local runner's claim/heartbeat/append/finish (ADR-0067); agent-key only. */
4590
+ agentRuns: AgentRunsApi;
4448
4591
  constructor(config: {
4449
4592
  token: string;
4450
4593
  apiUrl: string;
4451
4594
  });
4452
4595
  }
4453
4596
 
4454
- 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 Area, type AreaCreateInput, type AreaListOptions, 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 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 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 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 PageListOptions, 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 Requirement, type RequirementCreateInput, type RequirementKind, type RequirementListOptions, 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 };
4597
+ 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 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 PageListOptions, 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 Requirement, type RequirementCreateInput, type RequirementKind, type RequirementListOptions, 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
@@ -1256,6 +1256,36 @@ var TimeApi = class {
1256
1256
  }
1257
1257
  };
1258
1258
 
1259
+ // src/agentRuns.ts
1260
+ var AgentRunsApi = class {
1261
+ constructor(client) {
1262
+ this.client = client;
1263
+ }
1264
+ /**
1265
+ * Claim the oldest queued LOCAL_CLI run of this key's Assistant, or null when
1266
+ * nothing is queued. `runnerId` names this machine/process; it is recorded on
1267
+ * the run and checked by the other calls.
1268
+ */
1269
+ async claim(runnerId) {
1270
+ return await this.client.agentRun.claim.mutate({ runnerId });
1271
+ }
1272
+ /** Keep the run alive while a step is slow (the app times out a silent run after 5 minutes). */
1273
+ async heartbeat(runId, runnerId) {
1274
+ return await this.client.agentRun.heartbeat.mutate({ runId, runnerId });
1275
+ }
1276
+ /**
1277
+ * Append transcript events (1–200 per call). Idempotent on `seq`, so a batch
1278
+ * may be retried after a network error without duplicating lines.
1279
+ */
1280
+ async appendEvents(runId, events, runnerId) {
1281
+ return await this.client.agentRun.appendEvents.mutate({ runId, runnerId, events });
1282
+ }
1283
+ /** End the run: succeeded, failed, or waiting on the owner's answer to `question`. */
1284
+ async finish(runId, input, runnerId) {
1285
+ return await this.client.agentRun.finish.mutate({ runId, runnerId, ...input });
1286
+ }
1287
+ };
1288
+
1259
1289
  // src/config.ts
1260
1290
  import Conf from "conf";
1261
1291
  var schema = {
@@ -1423,6 +1453,7 @@ var ExponentialClient = class {
1423
1453
  this.scopes = new ScopesApi(this.client);
1424
1454
  this.search = new SearchApi(this.client);
1425
1455
  this.time = new TimeApi(this.client);
1456
+ this.agentRuns = new AgentRunsApi(this.client);
1426
1457
  }
1427
1458
  client;
1428
1459
  actions;
@@ -1453,8 +1484,11 @@ var ExponentialClient = class {
1453
1484
  search;
1454
1485
  /** Time entries — the Daily worklog's write path (ADR-0061). */
1455
1486
  time;
1487
+ /** Agent runs — the local runner's claim/heartbeat/append/finish (ADR-0067); agent-key only. */
1488
+ agentRuns;
1456
1489
  };
1457
1490
  export {
1491
+ AgentRunsApi,
1458
1492
  DEFAULT_GAP_MINUTES,
1459
1493
  ExponentialClient,
1460
1494
  ROUND_MINUTES,
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/requirements.ts","../src/scopes.ts","../src/search.ts","../src/time.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 };\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 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 }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; projectId?: string | null; title?: string; body?: string; includeInSearch?: boolean }) => Promise<unknown> };\n update: { mutate: (input: { id: string; title?: string; projectId?: string | null; includeInSearch?: boolean; body?: 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 /** Publish a draft into the log. */\n async confirmDraft(workspaceId: string, decisionId: string): Promise<Decision> {\n return await this.client.decision.confirmDraft.mutate({\n workspaceId,\n decisionId,\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 { KnowledgePage } from './types/page.js';\n\nexport interface PageListOptions {\n workspaceId: string;\n projectId?: string;\n search?: 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}\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\n/**\n * Knowledge pages (PRDs, research, technical specs). Workspace-scoped\n * documents; link one to a feature via `FeaturesApi.linkPage`.\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 async get(id: string): Promise<KnowledgePage> {\n return await this.client.page.get.query({ id }) as KnowledgePage;\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","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 { GlobalSearchOptions, GlobalSearchOutput } 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).\n */\n async global(options: GlobalSearchOptions): Promise<GlobalSearchOutput> {\n return (await this.client.search.global.query(options)) as GlobalSearchOutput;\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 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 { RequirementsApi } from './requirements.js';\nimport { ScopesApi } from './scopes.js';\nimport { SearchApi } from './search.js';\nimport { TimeApi } from './time.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 requirements: RequirementsApi;\n scopes: ScopesApi;\n search: SearchApi;\n /** Time entries — the Daily worklog's write path (ADR-0061). */\n time: TimeApi;\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.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 }\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 { KnowledgePage } from './types/page.js';\nexport type {\n PageListOptions,\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} 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';\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/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 };\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 }) => Promise<unknown> };\n create: { mutate: (input: { workspaceId: string; projectId?: string | null; title?: string; body?: string; includeInSearch?: boolean }) => Promise<unknown> };\n update: { mutate: (input: { id: string; title?: string; projectId?: string | null; includeInSearch?: boolean; body?: 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 /** Publish a draft into the log. */\n async confirmDraft(workspaceId: string, decisionId: string): Promise<Decision> {\n return await this.client.decision.confirmDraft.mutate({\n workspaceId,\n decisionId,\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 { KnowledgePage } from './types/page.js';\n\nexport interface PageListOptions {\n workspaceId: string;\n projectId?: string;\n search?: 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}\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\n/**\n * Knowledge pages (PRDs, research, technical specs). Workspace-scoped\n * documents; link one to a feature via `FeaturesApi.linkPage`.\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 async get(id: string): Promise<KnowledgePage> {\n return await this.client.page.get.query({ id }) as KnowledgePage;\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","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 { GlobalSearchOptions, GlobalSearchOutput } 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).\n */\n async global(options: GlobalSearchOptions): Promise<GlobalSearchOutput> {\n return (await this.client.search.global.query(options)) as GlobalSearchOutput;\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 { 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 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.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 { KnowledgePage } from './types/page.js';\nexport type {\n PageListOptions,\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} 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.20.1",
3
+ "version": "1.21.0",
4
4
  "description": "SDK for interacting with the Exponential API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",