exponential-sdk 1.10.0 → 1.12.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
@@ -41,6 +41,77 @@ type ActionCreateInput$1 = {
41
41
  effortEstimate?: number;
42
42
  blockedByIds?: string[];
43
43
  };
44
+ type GoalStatusInput = 'planned' | 'active' | 'completed' | 'archived';
45
+ /** Reads and `updateGoalStatus` also accept `on-hold`; `updateGoal` does not. */
46
+ type GoalQueryStatusInput = GoalStatusInput | 'on-hold';
47
+ type GoalCreateProcedureInput = {
48
+ title: string;
49
+ description?: string;
50
+ whyThisGoal?: string;
51
+ notes?: string;
52
+ dueDate?: Date;
53
+ period?: string;
54
+ status?: GoalStatusInput;
55
+ lifeDomainId?: number;
56
+ projectId?: string;
57
+ outcomeIds?: string[];
58
+ driUserId?: string;
59
+ workspaceId?: string;
60
+ parentGoalId?: number;
61
+ icon?: string | null;
62
+ iconColor?: string | null;
63
+ };
64
+ type GoalUpdateProcedureInput = {
65
+ id: number;
66
+ title?: string;
67
+ description?: string | null;
68
+ whyThisGoal?: string | null;
69
+ notes?: string | null;
70
+ dueDate?: Date | null;
71
+ period?: string | null;
72
+ status?: GoalStatusInput;
73
+ lifeDomainId?: number | null;
74
+ projectId?: string | null;
75
+ projectIds?: string[];
76
+ outcomeIds?: string[];
77
+ driUserId?: string | null;
78
+ workspaceId?: string | null;
79
+ parentGoalId?: number | null;
80
+ displayOrder?: number;
81
+ icon?: string | null;
82
+ iconColor?: string | null;
83
+ };
84
+ type KeyResultStatusInput = 'not-started' | 'on-track' | 'at-risk' | 'off-track' | 'achieved';
85
+ type KeyResultUnitInput = 'percent' | 'count' | 'currency' | 'hours' | 'custom';
86
+ type KeyResultCreateProcedureInput = {
87
+ goalId: number;
88
+ title: string;
89
+ description?: string;
90
+ targetValue: number;
91
+ startValue?: number;
92
+ currentValue?: number;
93
+ unit?: KeyResultUnitInput;
94
+ unitLabel?: string;
95
+ period: string;
96
+ periodStart?: Date;
97
+ periodEnd?: Date;
98
+ driUserId?: string;
99
+ workspaceId?: string;
100
+ };
101
+ type KeyResultUpdateProcedureInput = {
102
+ id: string;
103
+ title?: string;
104
+ description?: string;
105
+ targetValue?: number;
106
+ currentValue?: number;
107
+ startValue?: number;
108
+ unit?: KeyResultUnitInput;
109
+ unitLabel?: string;
110
+ status?: KeyResultStatusInput;
111
+ confidence?: number;
112
+ driUserId?: string;
113
+ goalId?: number;
114
+ };
44
115
  type ActionUpdateInput$1 = {
45
116
  id: string;
46
117
  name?: string;
@@ -120,6 +191,194 @@ interface TrpcClient {
120
191
  list: {
121
192
  query: () => Promise<unknown[]>;
122
193
  };
194
+ listMembers: {
195
+ query: (input: {
196
+ workspaceId: string;
197
+ }) => Promise<unknown[]>;
198
+ };
199
+ };
200
+ goal: {
201
+ getById: {
202
+ query: (input: {
203
+ id: number;
204
+ }) => Promise<unknown>;
205
+ };
206
+ getAllMyGoals: {
207
+ query: (input?: {
208
+ workspaceId?: string;
209
+ period?: string;
210
+ status?: GoalQueryStatusInput;
211
+ }) => Promise<unknown[]>;
212
+ };
213
+ getGoalTree: {
214
+ query: (input?: {
215
+ workspaceId?: string;
216
+ status?: GoalQueryStatusInput;
217
+ }) => Promise<unknown[]>;
218
+ };
219
+ getProjectGoals: {
220
+ query: (input: {
221
+ projectId: string;
222
+ }) => Promise<unknown[]>;
223
+ };
224
+ createGoal: {
225
+ mutate: (input: GoalCreateProcedureInput) => Promise<unknown>;
226
+ };
227
+ /**
228
+ * Partial update — only the keys present are written, and an explicit null
229
+ * clears. Every nullable field is therefore `T | null | undefined`.
230
+ */
231
+ updateGoal: {
232
+ mutate: (input: GoalUpdateProcedureInput) => Promise<unknown>;
233
+ };
234
+ /** Status-only write; the only path that accepts `on-hold`. */
235
+ updateGoalStatus: {
236
+ mutate: (input: {
237
+ id: number;
238
+ status: GoalQueryStatusInput;
239
+ }) => Promise<unknown>;
240
+ };
241
+ /** Single-column re-parent; validates no-self / no-cycle / depth-5. */
242
+ setParent: {
243
+ mutate: (input: {
244
+ id: number;
245
+ parentGoalId: number | null;
246
+ }) => Promise<unknown>;
247
+ };
248
+ deleteGoal: {
249
+ mutate: (input: {
250
+ id: number;
251
+ }) => Promise<unknown>;
252
+ };
253
+ };
254
+ okr: {
255
+ getAll: {
256
+ query: (input?: {
257
+ workspaceId?: string;
258
+ goalId?: number;
259
+ period?: string;
260
+ status?: KeyResultStatusInput;
261
+ onlyMine?: boolean;
262
+ }) => Promise<unknown[]>;
263
+ };
264
+ getByObjective: {
265
+ query: (input: {
266
+ workspaceId?: string;
267
+ period?: string;
268
+ includePairedPeriod?: boolean;
269
+ onlyMine?: boolean;
270
+ }) => Promise<unknown[]>;
271
+ };
272
+ getById: {
273
+ query: (input: {
274
+ id: string;
275
+ }) => Promise<unknown>;
276
+ };
277
+ getByIds: {
278
+ query: (input: {
279
+ ids: string[];
280
+ }) => Promise<unknown[]>;
281
+ };
282
+ create: {
283
+ mutate: (input: KeyResultCreateProcedureInput) => Promise<unknown>;
284
+ };
285
+ update: {
286
+ mutate: (input: KeyResultUpdateProcedureInput) => Promise<unknown>;
287
+ };
288
+ checkIn: {
289
+ mutate: (input: {
290
+ keyResultId: string;
291
+ newValue: number;
292
+ notes?: string;
293
+ }) => Promise<unknown>;
294
+ };
295
+ delete: {
296
+ mutate: (input: {
297
+ id: string;
298
+ }) => Promise<unknown>;
299
+ };
300
+ linkProject: {
301
+ mutate: (input: {
302
+ keyResultId: string;
303
+ projectId: string;
304
+ }) => Promise<unknown>;
305
+ };
306
+ unlinkProject: {
307
+ mutate: (input: {
308
+ keyResultId: string;
309
+ projectId: string;
310
+ }) => Promise<unknown>;
311
+ };
312
+ linkFeature: {
313
+ mutate: (input: {
314
+ keyResultId: string;
315
+ featureId: string;
316
+ }) => Promise<unknown>;
317
+ };
318
+ unlinkFeature: {
319
+ mutate: (input: {
320
+ keyResultId: string;
321
+ featureId: string;
322
+ }) => Promise<unknown>;
323
+ };
324
+ getPeriods: {
325
+ query: () => Promise<unknown[]>;
326
+ };
327
+ getStats: {
328
+ query: (input: {
329
+ workspaceId?: string;
330
+ period?: string;
331
+ }) => Promise<unknown>;
332
+ };
333
+ };
334
+ goalComment: {
335
+ getComments: {
336
+ query: (input: {
337
+ goalId: number;
338
+ }) => Promise<unknown[]>;
339
+ };
340
+ addComment: {
341
+ mutate: (input: {
342
+ goalId: number;
343
+ content: string;
344
+ parentUpdateId?: string;
345
+ }) => Promise<unknown>;
346
+ };
347
+ updateComment: {
348
+ mutate: (input: {
349
+ commentId: string;
350
+ content: string;
351
+ }) => Promise<unknown>;
352
+ };
353
+ deleteComment: {
354
+ mutate: (input: {
355
+ commentId: string;
356
+ }) => Promise<unknown>;
357
+ };
358
+ };
359
+ pageComment: {
360
+ list: {
361
+ query: (input: {
362
+ pageId: string;
363
+ }) => Promise<unknown[]>;
364
+ };
365
+ create: {
366
+ mutate: (input: {
367
+ pageId: string;
368
+ body: string;
369
+ }) => Promise<unknown>;
370
+ };
371
+ update: {
372
+ mutate: (input: {
373
+ commentId: string;
374
+ body: string;
375
+ }) => Promise<unknown>;
376
+ };
377
+ delete: {
378
+ mutate: (input: {
379
+ commentId: string;
380
+ }) => Promise<unknown>;
381
+ };
123
382
  };
124
383
  crmApi: {
125
384
  contactList: {
@@ -454,6 +713,51 @@ interface TrpcClient {
454
713
  }) => Promise<unknown>;
455
714
  };
456
715
  };
716
+ featureComment: {
717
+ list: {
718
+ query: (input: {
719
+ featureId: string;
720
+ }) => Promise<unknown[]>;
721
+ };
722
+ create: {
723
+ mutate: (input: {
724
+ featureId: string;
725
+ scopeId?: string;
726
+ threadId?: string;
727
+ body: string;
728
+ quotedText?: string;
729
+ }) => Promise<unknown>;
730
+ };
731
+ reply: {
732
+ mutate: (input: {
733
+ parentId: string;
734
+ body: string;
735
+ }) => Promise<unknown>;
736
+ };
737
+ update: {
738
+ mutate: (input: {
739
+ commentId: string;
740
+ body: string;
741
+ }) => Promise<unknown>;
742
+ };
743
+ delete: {
744
+ mutate: (input: {
745
+ commentId: string;
746
+ }) => Promise<unknown>;
747
+ };
748
+ resolve: {
749
+ mutate: (input: {
750
+ featureId: string;
751
+ threadId: string;
752
+ }) => Promise<unknown>;
753
+ };
754
+ unresolve: {
755
+ mutate: (input: {
756
+ featureId: string;
757
+ threadId: string;
758
+ }) => Promise<unknown>;
759
+ };
760
+ };
457
761
  feature: {
458
762
  list: {
459
763
  query: (input: {
@@ -684,6 +988,12 @@ interface TrpcClient {
684
988
  content: string;
685
989
  }) => Promise<unknown>;
686
990
  };
991
+ updateComment: {
992
+ mutate: (input: {
993
+ id: string;
994
+ content: string;
995
+ }) => Promise<unknown>;
996
+ };
687
997
  deleteComment: {
688
998
  mutate: (input: {
689
999
  id: string;
@@ -950,6 +1260,47 @@ interface TicketComment {
950
1260
  updatedAt: Date;
951
1261
  author: CommentAuthor;
952
1262
  }
1263
+ /**
1264
+ * Comments on a Feature (PRD). `body` is Markdown. A comment is either
1265
+ * doc-level (`threadId` null), anchored to a span of the PRD body (`threadId`
1266
+ * matches a comment mark in the doc), or attached to a scope's feed
1267
+ * (`scopeId` set). `parentId` marks a reply; threads are one level deep.
1268
+ */
1269
+ interface FeatureComment {
1270
+ id: string;
1271
+ featureId: string;
1272
+ scopeId: string | null;
1273
+ threadId: string | null;
1274
+ parentId: string | null;
1275
+ body: string;
1276
+ quotedText: string | null;
1277
+ resolvedAt: Date | null;
1278
+ createdById: string;
1279
+ createdAt: Date;
1280
+ updatedAt: Date;
1281
+ createdBy: CommentAuthor;
1282
+ }
1283
+ /** Comments on a Knowledge Page — a flat, doc-level feed. `body` is Markdown. */
1284
+ interface PageComment {
1285
+ id: string;
1286
+ pageId: string;
1287
+ body: string;
1288
+ createdById: string;
1289
+ createdAt: Date;
1290
+ updatedAt: Date;
1291
+ createdBy: CommentAuthor;
1292
+ }
1293
+ /** Comments on a Goal/Objective. `content` is Markdown. */
1294
+ interface GoalComment {
1295
+ id: string;
1296
+ goalId: number;
1297
+ authorId: string;
1298
+ content: string;
1299
+ parentUpdateId: string | null;
1300
+ createdAt: Date;
1301
+ updatedAt: Date;
1302
+ author: CommentAuthor;
1303
+ }
953
1304
 
954
1305
  interface ActionCommentAddInput {
955
1306
  actionId: string;
@@ -968,6 +1319,659 @@ declare class ActionCommentsApi {
968
1319
  delete(commentId: string): Promise<ActionComment>;
969
1320
  }
970
1321
 
1322
+ interface FeatureCommentCreateInput {
1323
+ featureId: string;
1324
+ /** Attach to a scope's activity feed instead of the feature's own feed. */
1325
+ scopeId?: string;
1326
+ /** Anchor to a span of the PRD body. Omit for a doc-level comment. */
1327
+ threadId?: string;
1328
+ /** Markdown. Mention members with `@[Name](userId)` — see `workspaces.listMembers()`. */
1329
+ body: string;
1330
+ quotedText?: string;
1331
+ }
1332
+ interface FeatureCommentReplyInput {
1333
+ parentId: string;
1334
+ body: string;
1335
+ }
1336
+ interface FeatureCommentUpdateInput {
1337
+ commentId: string;
1338
+ body: string;
1339
+ }
1340
+ interface FeatureCommentThreadInput {
1341
+ featureId: string;
1342
+ threadId: string;
1343
+ }
1344
+ /**
1345
+ * Discussion on a Feature (PRD). Any workspace member can read and comment;
1346
+ * editing and deleting are author-only.
1347
+ *
1348
+ * Mentions are `@[Display Name](userId)` in the body — that markup is what
1349
+ * triggers a notification. `workspaces.listMembers()` returns a ready-made
1350
+ * `mentionSyntax` per member so callers never have to build it by hand.
1351
+ */
1352
+ declare class FeatureCommentsApi {
1353
+ private client;
1354
+ constructor(client: TrpcClient);
1355
+ list(featureId: string): Promise<FeatureComment[]>;
1356
+ create(input: FeatureCommentCreateInput): Promise<FeatureComment>;
1357
+ /** Reply to an existing comment. Replies to replies still hang off the root. */
1358
+ reply(input: FeatureCommentReplyInput): Promise<FeatureComment>;
1359
+ update(input: FeatureCommentUpdateInput): Promise<FeatureComment>;
1360
+ delete(commentId: string): Promise<{
1361
+ success: boolean;
1362
+ }>;
1363
+ /** Mark an anchored thread resolved. Only anchored threads have a threadId. */
1364
+ resolve(input: FeatureCommentThreadInput): Promise<{
1365
+ success: boolean;
1366
+ }>;
1367
+ unresolve(input: FeatureCommentThreadInput): Promise<{
1368
+ success: boolean;
1369
+ }>;
1370
+ }
1371
+
1372
+ interface PageCommentCreateInput {
1373
+ pageId: string;
1374
+ /** Markdown. Mention members with `@[Name](userId)` — see `workspaces.listMembers()`. */
1375
+ body: string;
1376
+ }
1377
+ interface PageCommentUpdateInput {
1378
+ commentId: string;
1379
+ body: string;
1380
+ }
1381
+ /**
1382
+ * Discussion on a Knowledge Page — a flat, doc-level feed under the page body.
1383
+ * View access is the commenting gate: anyone the page is shared with can join
1384
+ * the thread. Editing and deleting are author-only.
1385
+ */
1386
+ declare class PageCommentsApi {
1387
+ private client;
1388
+ constructor(client: TrpcClient);
1389
+ list(pageId: string): Promise<PageComment[]>;
1390
+ create(input: PageCommentCreateInput): Promise<PageComment>;
1391
+ update(input: PageCommentUpdateInput): Promise<PageComment>;
1392
+ delete(commentId: string): Promise<{
1393
+ success: boolean;
1394
+ }>;
1395
+ }
1396
+
1397
+ interface GoalCommentAddInput {
1398
+ goalId: number;
1399
+ /** Markdown. Mention members with `@[Name](userId)` — see `workspaces.listMembers()`. */
1400
+ content: string;
1401
+ /** Thread this comment under a specific goal update rather than the goal itself. */
1402
+ parentUpdateId?: string;
1403
+ }
1404
+ interface GoalCommentUpdateInput {
1405
+ commentId: string;
1406
+ content: string;
1407
+ }
1408
+ /**
1409
+ * Discussion on a Goal/Objective. Note `goalId` is numeric — goals use integer
1410
+ * ids, unlike the cuid-keyed product entities.
1411
+ */
1412
+ declare class GoalCommentsApi {
1413
+ private client;
1414
+ constructor(client: TrpcClient);
1415
+ list(goalId: number): Promise<GoalComment[]>;
1416
+ add(input: GoalCommentAddInput): Promise<GoalComment>;
1417
+ update(input: GoalCommentUpdateInput): Promise<GoalComment>;
1418
+ delete(commentId: string): Promise<{
1419
+ success: boolean;
1420
+ }>;
1421
+ }
1422
+
1423
+ type KeyResultStatus = 'not-started' | 'on-track' | 'at-risk' | 'off-track' | 'achieved';
1424
+ type KeyResultUnit = 'percent' | 'count' | 'currency' | 'hours' | 'custom';
1425
+ interface KeyResultCheckIn {
1426
+ id: string;
1427
+ keyResultId: string;
1428
+ previousValue: number;
1429
+ newValue: number;
1430
+ notes: string | null;
1431
+ createdById: string | null;
1432
+ createdAt: Date;
1433
+ createdBy?: {
1434
+ id: string;
1435
+ name: string | null;
1436
+ image?: string | null;
1437
+ } | null;
1438
+ }
1439
+ interface KeyResultProjectLink {
1440
+ keyResultId: string;
1441
+ projectId: string;
1442
+ project?: {
1443
+ id: string;
1444
+ name: string;
1445
+ status?: string | null;
1446
+ };
1447
+ }
1448
+ interface KeyResultFeatureLink {
1449
+ keyResultId: string;
1450
+ featureId: string;
1451
+ feature?: {
1452
+ id: string;
1453
+ name: string;
1454
+ status?: string | null;
1455
+ /** Done/total ticket counts, or null for a feature with no tickets. */
1456
+ ticketProgress?: {
1457
+ done: number;
1458
+ total: number;
1459
+ } | null;
1460
+ };
1461
+ }
1462
+ interface KeyResult {
1463
+ /** cuid — unlike the objective's integer `goalId`. */
1464
+ id: string;
1465
+ goalId: number;
1466
+ title: string;
1467
+ description: string | null;
1468
+ status: string;
1469
+ /** Manual status override. When set it wins over `status`. */
1470
+ statusOverride?: string | null;
1471
+ startValue: number;
1472
+ currentValue: number;
1473
+ targetValue: number;
1474
+ unit: string;
1475
+ unitLabel?: string | null;
1476
+ confidence?: number | null;
1477
+ period: string;
1478
+ periodStart?: Date | null;
1479
+ periodEnd?: Date | null;
1480
+ userId: string;
1481
+ driUserId: string | null;
1482
+ workspaceId: string | null;
1483
+ createdAt: Date;
1484
+ updatedAt: Date;
1485
+ goal?: {
1486
+ id: number;
1487
+ title: string;
1488
+ period?: string | null;
1489
+ } | null;
1490
+ checkIns?: KeyResultCheckIn[];
1491
+ projects?: KeyResultProjectLink[];
1492
+ features?: KeyResultFeatureLink[];
1493
+ driUser?: {
1494
+ id: string;
1495
+ name: string | null;
1496
+ email?: string | null;
1497
+ image?: string | null;
1498
+ } | null;
1499
+ }
1500
+ /**
1501
+ * One objective with its key results, as returned by
1502
+ * `goals.keyResults.byObjective()` — the richest OKR read, and workspace-scoped
1503
+ * rather than user-scoped. This is the shape `exponential okrs list` renders.
1504
+ */
1505
+ interface ObjectiveWithKeyResults {
1506
+ id: number;
1507
+ title: string;
1508
+ description: string | null;
1509
+ status: string;
1510
+ period: string | null;
1511
+ health: string | null;
1512
+ workspaceId: string | null;
1513
+ driUserId: string | null;
1514
+ parentGoalId: number | null;
1515
+ /**
1516
+ * Not returned by the procedure — attached by callers that already know which
1517
+ * workspace they queried, so a cross-workspace list can label each row.
1518
+ */
1519
+ workspace?: {
1520
+ id: string;
1521
+ name: string;
1522
+ slug: string;
1523
+ } | null;
1524
+ keyResults: KeyResult[];
1525
+ /** Manual progress override if set, else the mean of the key results, else 0. */
1526
+ progress: number;
1527
+ statusCounts: {
1528
+ 'on-track': number;
1529
+ 'at-risk': number;
1530
+ 'off-track': number;
1531
+ achieved: number;
1532
+ };
1533
+ lifeDomain?: {
1534
+ id: number;
1535
+ title: string;
1536
+ color?: string | null;
1537
+ } | null;
1538
+ driUser?: {
1539
+ id: string;
1540
+ name: string | null;
1541
+ email?: string | null;
1542
+ image?: string | null;
1543
+ } | null;
1544
+ }
1545
+
1546
+ interface KeyResultListOptions {
1547
+ /**
1548
+ * Scope to a workspace. With it the list is workspace-**wide** — every
1549
+ * member's key results, not just yours. Without it you get your own.
1550
+ */
1551
+ workspaceId?: string;
1552
+ /** Objective id — an integer, unlike the key result's own cuid. */
1553
+ goalId?: number;
1554
+ period?: string;
1555
+ status?: KeyResultStatus;
1556
+ /** Narrow a workspace-scoped list back to the key results you own. */
1557
+ onlyMine?: boolean;
1558
+ }
1559
+ interface KeyResultByObjectiveOptions {
1560
+ workspaceId?: string;
1561
+ period?: string;
1562
+ /** Also include the period's parent annual period (Q3-2026 → Annual-2026). */
1563
+ includePairedPeriod?: boolean;
1564
+ onlyMine?: boolean;
1565
+ }
1566
+ interface KeyResultCreateInput {
1567
+ /** Objective (integer id) the key result hangs off. */
1568
+ goalId: number;
1569
+ title: string;
1570
+ targetValue: number;
1571
+ /** Free-form, e.g. `"Q3-2026"`. */
1572
+ period: string;
1573
+ description?: string;
1574
+ startValue?: number;
1575
+ currentValue?: number;
1576
+ unit?: KeyResultUnit;
1577
+ unitLabel?: string;
1578
+ driUserId?: string;
1579
+ /**
1580
+ * Omit to inherit the objective's workspace — {@link KeyResultsApi.create}
1581
+ * resolves it before writing. Pass one explicitly only to override.
1582
+ */
1583
+ workspaceId?: string;
1584
+ }
1585
+ interface KeyResultUpdateInput {
1586
+ /** cuid. */
1587
+ id: string;
1588
+ title?: string;
1589
+ description?: string;
1590
+ targetValue?: number;
1591
+ currentValue?: number;
1592
+ startValue?: number;
1593
+ unit?: KeyResultUnit;
1594
+ unitLabel?: string;
1595
+ status?: KeyResultStatus;
1596
+ /** 0–100. */
1597
+ confidence?: number;
1598
+ driUserId?: string;
1599
+ /** Move the key result to a different objective. */
1600
+ goalId?: number;
1601
+ }
1602
+ interface KeyResultCheckInInput {
1603
+ /** cuid. */
1604
+ id: string;
1605
+ /** The new current value. */
1606
+ value: number;
1607
+ note?: string;
1608
+ }
1609
+ /**
1610
+ * Key results — the measurable half of an OKR.
1611
+ *
1612
+ * Reachable both as `client.keyResults` and as `client.goals.keyResults`; they
1613
+ * are the same instance. Every id here is a **cuid string**, while the `goalId`
1614
+ * that ties a key result to its objective is an **integer**. The tRPC router
1615
+ * behind these calls is mounted at `okr`, which is the key-result router — not
1616
+ * an objective router. Objectives live on {@link GoalsApi}.
1617
+ */
1618
+ declare class KeyResultsApi {
1619
+ private client;
1620
+ constructor(client: TrpcClient);
1621
+ /**
1622
+ * List key results. Pass `workspaceId` for the workspace-wide list (every
1623
+ * member's), omit it for your own.
1624
+ *
1625
+ * ⚠️ Workspace scoping here depends on a server-side fix to `okr.getAll`,
1626
+ * which previously accepted a `workspaceId` while still filtering on the
1627
+ * caller's `userId` — so against an older instance this returns only your own
1628
+ * key results, or `[]`, rather than the workspace's. Unlike the filters in
1629
+ * `goals.list()` that cannot be repaired here: the other members' rows never
1630
+ * reach the client. {@link KeyResultsApi.byObjective} is workspace-correct on
1631
+ * every server version and is the safer read when that matters.
1632
+ */
1633
+ list(options?: KeyResultListOptions): Promise<KeyResult[]>;
1634
+ /**
1635
+ * Objectives with their key results nested — the richest OKR read, and the
1636
+ * one to reach for when rendering "here is the quarter".
1637
+ */
1638
+ byObjective(options?: KeyResultByObjectiveOptions): Promise<ObjectiveWithKeyResults[]>;
1639
+ get(id: string): Promise<KeyResult>;
1640
+ /**
1641
+ * Create a key result on an objective.
1642
+ *
1643
+ * When `workspaceId` is omitted it is resolved from the objective first,
1644
+ * rather than left to the server. `okr.create` writes the input through as-is
1645
+ * on older instances, so an absent workspace persists as `null` — and a key
1646
+ * result with no workspace is invisible to every workspace-scoped read and
1647
+ * unwritable by teammates once owner-OR-member authz applies. That is the
1648
+ * same orphaning that has already cost a goal; one extra read on a mutation
1649
+ * is a cheap way not to repeat it.
1650
+ */
1651
+ create(input: KeyResultCreateInput): Promise<KeyResult>;
1652
+ update(input: KeyResultUpdateInput): Promise<KeyResult>;
1653
+ /**
1654
+ * Record a progress check-in. The server derives the new status from where
1655
+ * `value` lands between `startValue` and `targetValue`, so a check-in both
1656
+ * moves the number and re-colours the key result.
1657
+ */
1658
+ checkIn(input: KeyResultCheckInInput): Promise<KeyResultCheckIn>;
1659
+ delete(id: string): Promise<{
1660
+ success: boolean;
1661
+ }>;
1662
+ /** Link a project to a key result as executing work. Idempotent. */
1663
+ linkProject(input: {
1664
+ keyResultId: string;
1665
+ projectId: string;
1666
+ }): Promise<{
1667
+ success: boolean;
1668
+ }>;
1669
+ unlinkProject(input: {
1670
+ keyResultId: string;
1671
+ projectId: string;
1672
+ }): Promise<{
1673
+ success: boolean;
1674
+ }>;
1675
+ /**
1676
+ * Link a feature to a key result as executing work. Idempotent. The feature's
1677
+ * product must live in the key result's workspace. A feature with no
1678
+ * objective alignment inherits the key result's objective; one that already
1679
+ * has an objective is never overwritten.
1680
+ */
1681
+ linkFeature(input: {
1682
+ keyResultId: string;
1683
+ featureId: string;
1684
+ }): Promise<{
1685
+ success: boolean;
1686
+ }>;
1687
+ /** Removes only the link row — never the feature's objective alignment. */
1688
+ unlinkFeature(input: {
1689
+ keyResultId: string;
1690
+ featureId: string;
1691
+ }): Promise<{
1692
+ success: boolean;
1693
+ }>;
1694
+ }
1695
+
1696
+ /**
1697
+ * Status on the goal write paths. `on-hold` is accepted only by
1698
+ * `goals.setStatus()` (`goal.updateGoalStatus`), never by `goals.update()`.
1699
+ */
1700
+ type GoalStatus = 'planned' | 'active' | 'completed' | 'archived' | 'on-hold';
1701
+ /** The subset `goals.update()` accepts. */
1702
+ type GoalWritableStatus = Exclude<GoalStatus, 'on-hold'>;
1703
+ /**
1704
+ * Rolled-up health, computed from key results, linked projects and child
1705
+ * goals. `healthOverride` wins over `health` when set.
1706
+ */
1707
+ type GoalHealth = 'on-track' | 'at-risk' | 'off-track' | 'no-update';
1708
+ interface GoalLifeDomain {
1709
+ id: number;
1710
+ title: string;
1711
+ description?: string | null;
1712
+ color?: string | null;
1713
+ icon?: string | null;
1714
+ }
1715
+ interface GoalProjectSummary {
1716
+ id: string;
1717
+ name: string;
1718
+ /** Present on list reads; the detail read selects a narrower project shape. */
1719
+ slug?: string;
1720
+ status?: string | null;
1721
+ progress?: number | null;
1722
+ priority?: string | null;
1723
+ endDate?: Date | null;
1724
+ }
1725
+ /**
1726
+ * The lean key-result shape list reads carry — enough to resolve progress
1727
+ * without the full KeyResult payload. `startValue` is absent on `tree()`,
1728
+ * whose select predates it.
1729
+ */
1730
+ interface GoalKeyResultSummary {
1731
+ id: string;
1732
+ status: string;
1733
+ startValue?: number;
1734
+ currentValue: number;
1735
+ targetValue: number;
1736
+ }
1737
+ interface GoalChildSummary {
1738
+ id: number;
1739
+ title: string;
1740
+ status: string;
1741
+ health: string | null;
1742
+ }
1743
+ interface GoalUserSummary {
1744
+ id: string;
1745
+ name: string | null;
1746
+ image?: string | null;
1747
+ }
1748
+ interface Goal {
1749
+ id: number;
1750
+ title: string;
1751
+ description: string | null;
1752
+ whyThisGoal?: string | null;
1753
+ notes?: string | null;
1754
+ dueDate: Date | null;
1755
+ /**
1756
+ * OKR period. A **free-form string** — `"Q3-2026"`, `"Annual-2026"`,
1757
+ * `"H1-2027"` — not an enum. `goals.periods()` lists the conventional values.
1758
+ */
1759
+ period: string | null;
1760
+ status: string;
1761
+ health: string | null;
1762
+ healthOverride?: string | null;
1763
+ progressOverride?: number | null;
1764
+ lifeDomainId: number | null;
1765
+ userId: string;
1766
+ driUserId: string | null;
1767
+ workspaceId: string | null;
1768
+ parentGoalId: number | null;
1769
+ icon?: string | null;
1770
+ iconColor?: string | null;
1771
+ displayOrder?: number;
1772
+ createdAt: Date;
1773
+ updatedAt: Date;
1774
+ lifeDomain?: GoalLifeDomain | null;
1775
+ projects?: GoalProjectSummary[];
1776
+ outcomes?: {
1777
+ id: string;
1778
+ description: string;
1779
+ }[];
1780
+ childGoals?: GoalChildSummary[];
1781
+ parentGoal?: {
1782
+ id: number;
1783
+ title: string;
1784
+ } | null;
1785
+ user?: GoalUserSummary;
1786
+ driUser?: GoalUserSummary | null;
1787
+ workspace?: {
1788
+ id: string;
1789
+ name: string;
1790
+ slug: string;
1791
+ } | null;
1792
+ /**
1793
+ * Effective progress 0–100: a manual `progressOverride` if set, else the mean
1794
+ * across measurable key results, else `null` for "no signal". Resolved
1795
+ * server-side so every consumer reads one number.
1796
+ */
1797
+ resolvedProgress?: number | null;
1798
+ /** Whether `resolvedProgress` came from the manual override. */
1799
+ isProgressManual?: boolean;
1800
+ keyResults?: GoalKeyResultSummary[];
1801
+ _count?: {
1802
+ keyResults?: number;
1803
+ comments?: number;
1804
+ };
1805
+ }
1806
+ /**
1807
+ * A goal with its children nested, as returned by `goals.tree()`. Only roots
1808
+ * (goals with no parent) come back at the top level; the server nests up to
1809
+ * the 5-level cap.
1810
+ */
1811
+ interface GoalTreeNode extends Goal {
1812
+ childGoals?: GoalTreeNode[] & GoalChildSummary[];
1813
+ keyResults?: GoalKeyResultSummary[];
1814
+ }
1815
+ /** One entry from `goals.periods()`. */
1816
+ interface GoalPeriod {
1817
+ value: string;
1818
+ label: string;
1819
+ }
1820
+ /** Aggregate OKR numbers from `goals.stats()`. */
1821
+ interface GoalStats {
1822
+ totalObjectives: number;
1823
+ totalKeyResults: number;
1824
+ completedKeyResults: number;
1825
+ statusBreakdown: {
1826
+ onTrack: number;
1827
+ atRisk: number;
1828
+ offTrack: number;
1829
+ achieved: number;
1830
+ };
1831
+ averageProgress: number;
1832
+ averageConfidence: number | null;
1833
+ periodEndDate: Date | null;
1834
+ }
1835
+
1836
+ interface GoalListOptions {
1837
+ /**
1838
+ * Scope to a workspace. With it the list is workspace-**wide** — every
1839
+ * member's objectives, not just yours. Without it you get your own.
1840
+ */
1841
+ workspaceId?: string;
1842
+ /** Free-form period string, e.g. `"Q3-2026"` or `"Annual-2026"`. */
1843
+ period?: string;
1844
+ status?: GoalStatus;
1845
+ }
1846
+ interface GoalTreeOptions {
1847
+ workspaceId?: string;
1848
+ status?: GoalStatus;
1849
+ }
1850
+ interface GoalCreateInput {
1851
+ title: string;
1852
+ description?: string;
1853
+ whyThisGoal?: string;
1854
+ notes?: string;
1855
+ dueDate?: Date;
1856
+ period?: string;
1857
+ status?: GoalWritableStatus;
1858
+ lifeDomainId?: number;
1859
+ /** Link the objective to one project on creation. */
1860
+ projectId?: string;
1861
+ outcomeIds?: string[];
1862
+ driUserId?: string;
1863
+ workspaceId?: string;
1864
+ /** Nest under a parent objective. Max nesting depth is 5. */
1865
+ parentGoalId?: number;
1866
+ icon?: string | null;
1867
+ iconColor?: string | null;
1868
+ }
1869
+ /**
1870
+ * A **partial** update: omit a field and it is left untouched, pass an explicit
1871
+ * `null` to clear it. Nothing you don't name is written.
1872
+ *
1873
+ * Prefer {@link GoalsApi.setStatus} for a status change and
1874
+ * {@link GoalsApi.setParent} for a re-parent — both write exactly one column.
1875
+ */
1876
+ interface GoalUpdateInput {
1877
+ id: number;
1878
+ title?: string;
1879
+ description?: string | null;
1880
+ whyThisGoal?: string | null;
1881
+ notes?: string | null;
1882
+ dueDate?: Date | null;
1883
+ period?: string | null;
1884
+ status?: GoalWritableStatus;
1885
+ lifeDomainId?: number | null;
1886
+ /** Replace the project links with this one project; `null` clears them. */
1887
+ projectId?: string | null;
1888
+ /** Replace the project links wholesale; `[]` clears them. */
1889
+ projectIds?: string[];
1890
+ outcomeIds?: string[];
1891
+ driUserId?: string | null;
1892
+ workspaceId?: string | null;
1893
+ parentGoalId?: number | null;
1894
+ displayOrder?: number;
1895
+ icon?: string | null;
1896
+ iconColor?: string | null;
1897
+ }
1898
+ interface GoalSetStatusInput {
1899
+ id: number;
1900
+ /** `on-hold` is accepted here and only here. */
1901
+ status: GoalStatus;
1902
+ }
1903
+ interface GoalSetParentInput {
1904
+ id: number;
1905
+ /** `null` detaches the objective from its parent. */
1906
+ parentGoalId: number | null;
1907
+ }
1908
+ interface GoalStatsOptions {
1909
+ workspaceId?: string;
1910
+ period?: string;
1911
+ }
1912
+ /**
1913
+ * Objectives (`Goal`) — the qualitative half of an OKR, keyed by **integer** id.
1914
+ * Their measurable key results hang off {@link KeyResultsApi}, reachable here as
1915
+ * `goals.keyResults`.
1916
+ *
1917
+ * On writes: `update()` is a partial update, but `setStatus()` and `setParent()`
1918
+ * each write a single column and are the right call whenever that is all you
1919
+ * mean to change — closing a quarter or re-parenting a cascade should never risk
1920
+ * a collateral write.
1921
+ */
1922
+ declare class GoalsApi {
1923
+ private client;
1924
+ /** Key results for these objectives. Same instance as `client.keyResults`. */
1925
+ keyResults: KeyResultsApi;
1926
+ constructor(client: TrpcClient,
1927
+ /** Key results for these objectives. Same instance as `client.keyResults`. */
1928
+ keyResults: KeyResultsApi);
1929
+ /**
1930
+ * List objectives. Pass `workspaceId` for the workspace-wide list (every
1931
+ * member's), omit it for your own. Includes each objective's linked
1932
+ * `projects`, which is the join that maps day-to-day work back to an OKR:
1933
+ * every action carries a `projectId`.
1934
+ *
1935
+ * `period` and `status` are sent to the server *and* re-applied here. The
1936
+ * server grew those filters recently; against an instance that predates them
1937
+ * zod strips the unknown keys and hands back **every** objective — a filter
1938
+ * that silently matches everything is worse than one that errors. Re-applying
1939
+ * is a no-op once the server has done the work. Same reasoning as the
1940
+ * client-side `branchName`/`prUrl` filters in `tickets.ts`.
1941
+ */
1942
+ list(options?: GoalListOptions): Promise<Goal[]>;
1943
+ /**
1944
+ * The same objectives nested parent → child (up to 5 levels), each with its
1945
+ * projects and key results. One call for the whole annual → quarterly cascade.
1946
+ */
1947
+ tree(options?: GoalTreeOptions): Promise<GoalTreeNode[]>;
1948
+ get(id: number): Promise<Goal>;
1949
+ /** Objectives linked to a given project. */
1950
+ listByProject(projectId: string): Promise<Goal[]>;
1951
+ create(input: GoalCreateInput): Promise<Goal>;
1952
+ /**
1953
+ * Partial update — see {@link GoalUpdateInput}. Fields you omit are left
1954
+ * alone; pass an explicit `null` to clear one.
1955
+ */
1956
+ update(input: GoalUpdateInput): Promise<Goal>;
1957
+ /**
1958
+ * Status-only write. Never touches another field, and is the only path that
1959
+ * accepts `on-hold`. Moving an objective to `completed` also records a
1960
+ * workspace milestone.
1961
+ */
1962
+ setStatus(input: GoalSetStatusInput): Promise<Goal>;
1963
+ /**
1964
+ * Re-parent an objective, or detach it with `parentGoalId: null`. Writes only
1965
+ * `parentGoalId`, and validates the no-self / no-cycle / depth-5 rules.
1966
+ */
1967
+ setParent(input: GoalSetParentInput): Promise<Goal>;
1968
+ delete(id: number): Promise<Goal>;
1969
+ /** The conventional period strings (quarters, halves, annual) for this year and next. */
1970
+ periods(): Promise<GoalPeriod[]>;
1971
+ /** Aggregate objective/key-result counts and average progress. */
1972
+ stats(options?: GoalStatsOptions): Promise<GoalStats>;
1973
+ }
1974
+
971
1975
  interface Project {
972
1976
  id: string;
973
1977
  name: string;
@@ -1018,6 +2022,37 @@ interface Workspace {
1018
2022
  createdAt: Date;
1019
2023
  updatedAt: Date;
1020
2024
  }
2025
+ /**
2026
+ * A member of a workspace, from `workspaces.listMembers()`.
2027
+ *
2028
+ * `source` is how they reach the workspace: `workspace` for a direct
2029
+ * membership, `team` for access inherited from a linked team. It matters for
2030
+ * mentions — name-only `@[Name]` markup only resolves against direct members,
2031
+ * so team-based members must be mentioned by id. Use `mentionSyntax`, which is
2032
+ * always the id form and therefore always works.
2033
+ */
2034
+ interface WorkspaceMember {
2035
+ id: string;
2036
+ name: string | null;
2037
+ email: string | null;
2038
+ image: string | null;
2039
+ /**
2040
+ * The member's WORKSPACE role. Team-based members are reported as `member`
2041
+ * regardless of their team role — a team `owner` holds no workspace
2042
+ * authority, so never gate on this expecting otherwise.
2043
+ */
2044
+ role: string;
2045
+ /** The team role, when access is team-based. Null for direct members. */
2046
+ teamRole: string | null;
2047
+ source: 'workspace' | 'team';
2048
+ /** Teams in this workspace the member belongs to. Empty for direct-only members. */
2049
+ teams: {
2050
+ id: string;
2051
+ name: string;
2052
+ }[];
2053
+ /** Ready-to-paste mention token, e.g. `@[Andi Stanner](clx123...)`. */
2054
+ mentionSyntax: string;
2055
+ }
1021
2056
  interface WorkspaceOutput {
1022
2057
  id: string;
1023
2058
  name: string;
@@ -1033,6 +2068,13 @@ declare class WorkspacesApi {
1033
2068
  private client;
1034
2069
  constructor(client: TrpcClient);
1035
2070
  list(): Promise<Workspace[]>;
2071
+ /**
2072
+ * Everyone who belongs to a workspace — direct members plus anyone with
2073
+ * access through a linked team. This is the lookup that makes mentions
2074
+ * possible from outside the app: match a name or email here, then drop the
2075
+ * row's `mentionSyntax` into a comment body.
2076
+ */
2077
+ listMembers(workspaceId: string): Promise<WorkspaceMember[]>;
1036
2078
  }
1037
2079
 
1038
2080
  type InteractionType = 'EMAIL' | 'TELEGRAM' | 'PHONE_CALL' | 'MEETING' | 'NOTE' | 'LINKEDIN' | 'OTHER';
@@ -1428,13 +2470,11 @@ interface TicketDetail extends Ticket {
1428
2470
  completedAt: Date | null;
1429
2471
  kanbanStatus: string | null;
1430
2472
  }>;
1431
- comments?: Array<{
1432
- id: string;
1433
- content: string;
1434
- createdAt: Date;
1435
- updatedAt: Date;
1436
- author: TicketAssignee;
1437
- }>;
2473
+ /**
2474
+ * The ticket's discussion, newest first. The detail fetch is the only way to
2475
+ * read ticket comments — there is no standalone list endpoint.
2476
+ */
2477
+ comments?: TicketComment[];
1438
2478
  }
1439
2479
 
1440
2480
  interface TicketListOptions {
@@ -1500,6 +2540,10 @@ interface TicketCommentAddInput {
1500
2540
  ticketId: string;
1501
2541
  content: string;
1502
2542
  }
2543
+ interface TicketCommentUpdateInput {
2544
+ id: string;
2545
+ content: string;
2546
+ }
1503
2547
  interface TicketSearchOptions {
1504
2548
  productId: string;
1505
2549
  query?: string;
@@ -1526,6 +2570,7 @@ declare class TicketsApi {
1526
2570
  success: boolean;
1527
2571
  }>;
1528
2572
  addComment(input: TicketCommentAddInput): Promise<TicketComment>;
2573
+ updateComment(input: TicketCommentUpdateInput): Promise<TicketComment>;
1529
2574
  deleteComment(id: string): Promise<{
1530
2575
  success: boolean;
1531
2576
  }>;
@@ -2099,6 +3144,12 @@ declare class ExponentialClient {
2099
3144
  private client;
2100
3145
  actions: ActionsApi;
2101
3146
  actionComments: ActionCommentsApi;
3147
+ featureComments: FeatureCommentsApi;
3148
+ pageComments: PageCommentsApi;
3149
+ goalComments: GoalCommentsApi;
3150
+ goals: GoalsApi;
3151
+ /** Same instance as `goals.keyResults`. */
3152
+ keyResults: KeyResultsApi;
2102
3153
  projects: ProjectsApi;
2103
3154
  workspaces: WorkspacesApi;
2104
3155
  contacts: ContactsApi;
@@ -2121,4 +3172,4 @@ declare class ExponentialClient {
2121
3172
  });
2122
3173
  }
2123
3174
 
2124
- export { type Action, type ActionComment, type ActionCommentAddInput, type ActionCommentUpdateInput, type ActionCreateInput, type ActionOutput, type ActionStatus, type ActionUpdateInput, 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 Deal, type DealActivity, type DealCreateInput, type DealMoveInput, type DealUpdateInput, type EnrichContactResult, type Epic, type EpicCreateInput, type EpicListOptions, type EpicPriority, type EpicStatus, type EpicUpdateInput, ExponentialClient, type ExponentialConfig, type Feature, type FeatureCreateInput, type FeatureLinkPageInput, type FeatureListOptions, type FeatureScope, type FeatureScopeStatus, type FeatureStatus, type FeatureUpdateInput, type GlobalSearchOptions, type GlobalSearchOutput, type InteractionDirection, type InteractionType, type KanbanStatus, type KnowledgePage, type LabelCreateInput, type LabelListOptions, type ListForEntityInput, type Organization, type OrganizationCreateInput, type OrganizationListOutput, type OrganizationSize, type OrganizationsListOptions, type OverdueCohort, type OverdueTriage, type OverdueTriageRow, type PageCreateInput, type PageListOptions, type PageUpdateInput, type Pipeline, type PipelineStage, type Priority, type Product, type ProductCreateInput, type ProductUpdateInput, type Project, type ProjectOutput, type ProjectsListOutput, 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 TicketCreateInput, type TicketDependencyEdge, type TicketDetail, type TicketListOptions, type TicketSearchOptions, type TicketStatus, type TicketType, type TicketUpdateInput, type TodaysActionRow, type TodaysActions, type TodaysActionsGroup, type UserStory, type UserStoryCreateInput, type UserStoryListOptions, type UserStoryUpdateInput, type Workspace, type WorkspaceOutput, type WorkspacesListOutput, clearConfig, createConfigStore, getConfigPath, isAuthenticated, isTRPCError, loadConfig, saveConfig };
3175
+ export { type Action, type ActionComment, type ActionCommentAddInput, type ActionCommentUpdateInput, type ActionCreateInput, type ActionOutput, type ActionStatus, type ActionUpdateInput, 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 Deal, type DealActivity, type DealCreateInput, type DealMoveInput, type DealUpdateInput, 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 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 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 ProjectOutput, type ProjectsListOutput, 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, type TodaysActionRow, type TodaysActions, type TodaysActionsGroup, type UserStory, type UserStoryCreateInput, type UserStoryListOptions, type UserStoryUpdateInput, type Workspace, type WorkspaceMember, type WorkspaceOutput, type WorkspacesListOutput, clearConfig, createConfigStore, getConfigPath, isAuthenticated, isTRPCError, loadConfig, saveConfig };