exponential-sdk 1.16.0 → 1.18.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.js CHANGED
@@ -144,6 +144,15 @@ var ActionsApi = class {
144
144
  async update(input) {
145
145
  return await this.client.action.update.mutate(input);
146
146
  }
147
+ /**
148
+ * One Action per external source: find by (workspaceId, sourceType,
149
+ * sourceId), refresh its name and links, else create it. `outcome` says
150
+ * which happened. Agents may call this; the created Action records the
151
+ * agent's shadow user as creator with `source: "agent"` (ADR-0049).
152
+ */
153
+ async upsertBySource(input) {
154
+ return await this.client.action.upsertBySource.mutate(input);
155
+ }
147
156
  };
148
157
 
149
158
  // src/actionComments.ts
@@ -548,6 +557,121 @@ var ContactsApi = class {
548
557
  }
549
558
  };
550
559
 
560
+ // src/decisions.ts
561
+ var DecisionsApi = class {
562
+ constructor(client) {
563
+ this.client = client;
564
+ }
565
+ /**
566
+ * Confirmed decisions in a workspace, newest decided first. Drafts are
567
+ * never included — see {@link listForMeeting} for those.
568
+ */
569
+ async list(options) {
570
+ return await this.client.decision.list.query(options);
571
+ }
572
+ async get(workspaceId, decisionId) {
573
+ return await this.client.decision.get.query({
574
+ workspaceId,
575
+ decisionId
576
+ });
577
+ }
578
+ /**
579
+ * Decisions logged from one meeting — both panels' contents. Drafts are
580
+ * included for callers who can edit the meeting. No workspace id needed:
581
+ * the meeting resolves it.
582
+ */
583
+ async listForMeeting(transcriptionSessionId) {
584
+ return await this.client.decision.listForMeeting.query({
585
+ transcriptionSessionId
586
+ });
587
+ }
588
+ /** Decisions formalised as one ADR ("Decided in"). */
589
+ async listForAdr(workspaceId, adrDocumentId) {
590
+ return await this.client.decision.listForAdr.query({
591
+ workspaceId,
592
+ adrDocumentId
593
+ });
594
+ }
595
+ /**
596
+ * Extract draft decisions from a meeting's notes and transcript. Drafts
597
+ * only — someone confirms or rejects each one. Idempotent per meeting:
598
+ * existing drafts come back untouched, and a meeting that already has
599
+ * confirmed decisions reports `alreadyPublished` without calling the model.
600
+ */
601
+ async extractDrafts(transcriptionSessionId) {
602
+ return await this.client.decision.extractDrafts.mutate({
603
+ transcriptionSessionId
604
+ });
605
+ }
606
+ /**
607
+ * Log a decision. Pass `status: 'OPEN'` for an open question, and
608
+ * `transcriptionSessionId` to attach it to the meeting it came out of.
609
+ */
610
+ async create(input) {
611
+ return await this.client.decision.create.mutate(input);
612
+ }
613
+ async update(input) {
614
+ return await this.client.decision.update.mutate(input);
615
+ }
616
+ /**
617
+ * Lifecycle transition — including answering an open question by moving it
618
+ * from `OPEN` to `ACCEPTED`.
619
+ */
620
+ async setStatus(input) {
621
+ return await this.client.decision.setStatus.mutate(input);
622
+ }
623
+ /** "Implemented by" a ticket. Idempotent: an existing link is returned. */
624
+ async linkTicket(workspaceId, decisionId, ticketId) {
625
+ return await this.client.decision.linkTicket.mutate({
626
+ workspaceId,
627
+ decisionId,
628
+ ticketId
629
+ });
630
+ }
631
+ /** "Implemented by" a feature. Idempotent: an existing link is returned. */
632
+ async linkFeature(workspaceId, decisionId, featureId) {
633
+ return await this.client.decision.linkFeature.mutate({
634
+ workspaceId,
635
+ decisionId,
636
+ featureId
637
+ });
638
+ }
639
+ /** Remove one link, by the `DecisionLink` id (not the ticket/feature id). */
640
+ async unlink(workspaceId, linkId) {
641
+ return await this.client.decision.unlink.mutate({
642
+ workspaceId,
643
+ linkId
644
+ });
645
+ }
646
+ /** Publish a draft into the log. */
647
+ async confirmDraft(workspaceId, decisionId) {
648
+ return await this.client.decision.confirmDraft.mutate({
649
+ workspaceId,
650
+ decisionId
651
+ });
652
+ }
653
+ /**
654
+ * Reject a draft. Confirmed decisions are never rejected — deprecate or
655
+ * supersede them through {@link setStatus}.
656
+ */
657
+ async rejectDraft(workspaceId, decisionId) {
658
+ return await this.client.decision.rejectDraft.mutate({
659
+ workspaceId,
660
+ decisionId
661
+ });
662
+ }
663
+ /**
664
+ * Hard-delete a draft or rejected row. The server refuses for a confirmed
665
+ * decision — the log keeps its history.
666
+ */
667
+ async deleteDraft(workspaceId, decisionId) {
668
+ return await this.client.decision.deleteDraft.mutate({
669
+ workspaceId,
670
+ decisionId
671
+ });
672
+ }
673
+ };
674
+
551
675
  // src/organizations.ts
552
676
  var OrganizationsApi = class {
553
677
  constructor(client) {
@@ -1037,6 +1161,76 @@ var SearchApi = class {
1037
1161
  }
1038
1162
  };
1039
1163
 
1164
+ // src/time.ts
1165
+ function startOfLocalDay(date) {
1166
+ const d = typeof date === "string" && /^\d{4}-\d{2}-\d{2}$/.test(date) ? /* @__PURE__ */ new Date(`${date}T00:00:00`) : new Date(date);
1167
+ if (Number.isNaN(d.getTime())) {
1168
+ throw new Error(`Invalid date: "${String(date)}". Use YYYY-MM-DD or an ISO timestamp.`);
1169
+ }
1170
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate());
1171
+ }
1172
+ var TimeApi = class {
1173
+ constructor(client) {
1174
+ this.client = client;
1175
+ }
1176
+ /**
1177
+ * Log one completed entry with explicit bounds. Never starts, stops or
1178
+ * alters the running Timer. With `sourceRef` the call is an upsert keyed
1179
+ * on (owner, sourceRef); without it every call creates a row.
1180
+ */
1181
+ async log(input) {
1182
+ if (input.sourceRef) {
1183
+ return await this.client.timeEntry.upsertBySourceRef.mutate({
1184
+ ...input,
1185
+ sourceRef: input.sourceRef
1186
+ });
1187
+ }
1188
+ const entry = await this.client.timeEntry.create.mutate(input);
1189
+ return { entry, outcome: "created" };
1190
+ }
1191
+ /**
1192
+ * Log many entries, one call each and in order, so a failure names the
1193
+ * entry it belonged to instead of rejecting the whole batch. `defaults`
1194
+ * fill any field an entry leaves out.
1195
+ */
1196
+ async logBatch(entries, defaults = {}) {
1197
+ const results = [];
1198
+ for (const [index, item] of entries.entries()) {
1199
+ const merged = { ...defaults, ...item };
1200
+ const sourceRef = merged.sourceRef;
1201
+ try {
1202
+ if (!merged.actionId) throw new Error("actionId is required");
1203
+ if (!merged.startedAt || !merged.endedAt) {
1204
+ throw new Error("startedAt and endedAt are required");
1205
+ }
1206
+ const result = await this.log(merged);
1207
+ results.push({ index, success: true, sourceRef, ...result });
1208
+ } catch (error) {
1209
+ results.push({
1210
+ index,
1211
+ success: false,
1212
+ sourceRef,
1213
+ error: error instanceof Error ? error.message : String(error)
1214
+ });
1215
+ }
1216
+ }
1217
+ return results;
1218
+ }
1219
+ /**
1220
+ * The caller's entries that touch one calendar day (local time), oldest
1221
+ * first, each with its `status`. Pass `YYYY-MM-DD` or a Date.
1222
+ */
1223
+ async list(date, workspaceId) {
1224
+ const startDate = startOfLocalDay(date);
1225
+ const endDate = new Date(startDate.getTime() + 24 * 60 * 60 * 1e3);
1226
+ return await this.client.timeEntry.listByDateRange.query({
1227
+ startDate,
1228
+ endDate,
1229
+ workspaceId
1230
+ });
1231
+ }
1232
+ };
1233
+
1040
1234
  // src/config.ts
1041
1235
  import Conf from "conf";
1042
1236
  var schema = {
@@ -1129,6 +1323,7 @@ var ExponentialClient = class {
1129
1323
  this.projects = new ProjectsApi(this.client);
1130
1324
  this.workspaces = new WorkspacesApi(this.client);
1131
1325
  this.contacts = new ContactsApi(this.client);
1326
+ this.decisions = new DecisionsApi(this.client);
1132
1327
  this.organizations = new OrganizationsApi(this.client);
1133
1328
  this.pipelines = new PipelinesApi(this.client);
1134
1329
  this.tickets = new TicketsApi(this.client);
@@ -1143,6 +1338,7 @@ var ExponentialClient = class {
1143
1338
  this.requirements = new RequirementsApi(this.client);
1144
1339
  this.scopes = new ScopesApi(this.client);
1145
1340
  this.search = new SearchApi(this.client);
1341
+ this.time = new TimeApi(this.client);
1146
1342
  }
1147
1343
  client;
1148
1344
  actions;
@@ -1156,6 +1352,7 @@ var ExponentialClient = class {
1156
1352
  projects;
1157
1353
  workspaces;
1158
1354
  contacts;
1355
+ decisions;
1159
1356
  organizations;
1160
1357
  pipelines;
1161
1358
  tickets;
@@ -1170,10 +1367,13 @@ var ExponentialClient = class {
1170
1367
  requirements;
1171
1368
  scopes;
1172
1369
  search;
1370
+ /** Time entries — the Daily worklog's write path (ADR-0061). */
1371
+ time;
1173
1372
  };
1174
1373
  export {
1175
1374
  ExponentialClient,
1176
1375
  TRPCClientError,
1376
+ TimeApi,
1177
1377
  clearConfig,
1178
1378
  createConfigStore,
1179
1379
  getConfigPath,