exponential-sdk 1.20.1 → 1.22.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: {
@@ -889,6 +926,46 @@ interface TrpcClient {
889
926
  }) => Promise<unknown>;
890
927
  };
891
928
  };
929
+ resource: {
930
+ list: {
931
+ query: (input: {
932
+ workspaceId?: string;
933
+ projectId?: string;
934
+ contentType?: string;
935
+ readStatus?: string;
936
+ search?: string;
937
+ tags?: string[];
938
+ includeArchived?: boolean;
939
+ limit?: number;
940
+ cursor?: string;
941
+ }) => Promise<unknown>;
942
+ };
943
+ create: {
944
+ mutate: (input: {
945
+ title: string;
946
+ url?: string;
947
+ description?: string;
948
+ content?: string;
949
+ contentType?: string;
950
+ tags?: string[];
951
+ workspaceId?: string;
952
+ projectId?: string;
953
+ readStatus?: string;
954
+ generateEmbeddings?: boolean;
955
+ }) => Promise<unknown>;
956
+ };
957
+ setReadStatus: {
958
+ mutate: (input: {
959
+ id: string;
960
+ readStatus: string;
961
+ }) => Promise<unknown>;
962
+ };
963
+ archive: {
964
+ mutate: (input: {
965
+ id: string;
966
+ }) => Promise<unknown>;
967
+ };
968
+ };
892
969
  epic: {
893
970
  list: {
894
971
  query: (input: {
@@ -4019,6 +4096,97 @@ declare class PagesApi {
4019
4096
  update(input: PageUpdateInput): Promise<KnowledgePage>;
4020
4097
  }
4021
4098
 
4099
+ type ResourceContentType = 'web_page' | 'document' | 'pdf' | 'bookmark' | 'note';
4100
+ /** Has the owner consumed this Resource yet? Orthogonal to archiving. */
4101
+ type ReadStatus = 'to_read' | 'reading' | 'read';
4102
+ /** The row shape `resource.list` returns. */
4103
+ interface Resource {
4104
+ id: string;
4105
+ title: string;
4106
+ description: string | null;
4107
+ url: string | null;
4108
+ contentType: ResourceContentType | string;
4109
+ wordCount: number | null;
4110
+ tags: string[];
4111
+ pinnedAsContext: boolean;
4112
+ readStatus: ReadStatus | string;
4113
+ /** First time the resource was marked read; null while unread. */
4114
+ readAt: Date | null;
4115
+ createdAt: Date;
4116
+ updatedAt: Date;
4117
+ archivedAt: Date | null;
4118
+ project?: {
4119
+ id: string;
4120
+ name: string;
4121
+ } | null;
4122
+ }
4123
+
4124
+ interface ResourceListOptions {
4125
+ workspaceId?: string;
4126
+ projectId?: string;
4127
+ contentType?: ResourceContentType;
4128
+ /**
4129
+ * Reading-list filter. `'unread'` is the queue (`to_read` + `reading`);
4130
+ * a single status narrows to that status; omitted applies no read filter.
4131
+ */
4132
+ readStatus?: ReadStatus | 'unread';
4133
+ search?: string;
4134
+ tags?: string[];
4135
+ includeArchived?: boolean;
4136
+ limit?: number;
4137
+ cursor?: string;
4138
+ }
4139
+ interface ResourceListResult {
4140
+ resources: Resource[];
4141
+ nextCursor?: string;
4142
+ }
4143
+ interface ResourceCreateInput {
4144
+ title: string;
4145
+ url?: string;
4146
+ description?: string;
4147
+ /** Pasted body. Only a Resource with content is embedded for search. */
4148
+ content?: string;
4149
+ contentType?: ResourceContentType;
4150
+ tags?: string[];
4151
+ workspaceId?: string;
4152
+ projectId?: string;
4153
+ /** Defaults to `to_read` server-side, so a saved link lands in the Reading list. */
4154
+ readStatus?: ReadStatus;
4155
+ /** Defaults to true server-side; a no-op when there is no content to embed. */
4156
+ generateEmbeddings?: boolean;
4157
+ }
4158
+ interface ResourceReadState {
4159
+ id: string;
4160
+ readStatus: ReadStatus | string;
4161
+ readAt: Date | null;
4162
+ }
4163
+ /**
4164
+ * Resources: ingested external content (saved links, PDFs, pasted notes).
4165
+ * The Reading list is `list({ readStatus: 'unread' })`; `save` is the
4166
+ * quick-add that files a URL as a `bookmark` to read.
4167
+ *
4168
+ * Indexing follows content, never read state: a bare URL has nothing to
4169
+ * embed and is findable by title and URL only.
4170
+ */
4171
+ declare class ResourcesApi {
4172
+ private client;
4173
+ constructor(client: TrpcClient);
4174
+ list(options?: ResourceListOptions): Promise<ResourceListResult>;
4175
+ create(input: ResourceCreateInput): Promise<Resource>;
4176
+ /** Save a link to the Reading list: a `bookmark` in `to_read`, not embedded. */
4177
+ save(input: {
4178
+ url: string;
4179
+ title?: string;
4180
+ note?: string;
4181
+ workspaceId?: string;
4182
+ readStatus?: ReadStatus;
4183
+ }): Promise<Resource>;
4184
+ setReadStatus(id: string, readStatus: ReadStatus): Promise<ResourceReadState>;
4185
+ archive(id: string): Promise<{
4186
+ success: boolean;
4187
+ }>;
4188
+ }
4189
+
4022
4190
  type RequirementKind = 'FUNCTIONAL' | 'NON_FUNCTIONAL' | 'CONSTRAINT';
4023
4191
  interface Requirement {
4024
4192
  id: string;
@@ -4349,6 +4517,110 @@ declare class TimeApi {
4349
4517
  list(date: Date | string, workspaceId?: string): Promise<TimeEntry[]>;
4350
4518
  }
4351
4519
 
4520
+ /**
4521
+ * Agent runs — the local runner's side of an Assistant run (Exponential
4522
+ * ADR-0067, "Local runner (V2) procedures" in dev-docs/AGENT_RUNS.md).
4523
+ *
4524
+ * An Assistant whose executor is LOCAL_CLI is never run by the hosted
4525
+ * dispatcher: a process on its owner's machine claims the run with the
4526
+ * Assistant's `exp_agent_` key, does the work with the owner's own tools,
4527
+ * streams what it did as events, and finishes. Every method needs an
4528
+ * **agent-key** client (a personal token or a run token is FORBIDDEN), and
4529
+ * every run is resolved through the key's own agent — a run id alone never
4530
+ * reaches another agent's work.
4531
+ */
4532
+ type AgentRunStatus = 'QUEUED' | 'RUNNING' | 'WAITING_ON_OWNER' | 'SUCCEEDED' | 'FAILED' | 'CANCELLED' | 'TIMED_OUT';
4533
+ type RunnerEventKind = 'status' | 'tool_call' | 'tool_result' | 'text' | 'log' | 'error';
4534
+ /** One line of a run's transcript. The runner numbers `seq` itself, from 1, monotonically. */
4535
+ interface RunnerEvent {
4536
+ seq: number;
4537
+ kind: RunnerEventKind;
4538
+ payload: Record<string, unknown>;
4539
+ }
4540
+ /** A chat-shaped message the runner feeds to its CLI: the persona, then the brief. */
4541
+ interface RunMessage {
4542
+ role: 'system' | 'user';
4543
+ content: string;
4544
+ }
4545
+ /** What `claim` hands the runner: the run, the action, the owner, and the exact persona + brief the hosted executor would use. */
4546
+ interface ClaimedRun {
4547
+ id: string;
4548
+ actionId: string;
4549
+ predecessorId: string | null;
4550
+ claimedBy: string | null;
4551
+ startedAt: Date | string | null;
4552
+ action: {
4553
+ id: string;
4554
+ name: string;
4555
+ description: string | null;
4556
+ workspaceId: string | null;
4557
+ project: {
4558
+ id: string;
4559
+ name: string;
4560
+ } | null;
4561
+ };
4562
+ owner: {
4563
+ id: string;
4564
+ name: string | null;
4565
+ };
4566
+ messages: RunMessage[];
4567
+ }
4568
+ interface HeartbeatResult {
4569
+ /** false — the run left RUNNING (a cancel): stop now. */
4570
+ ok: boolean;
4571
+ lastEventAt: Date | string | null;
4572
+ }
4573
+ interface AppendEventsResult {
4574
+ /** Rows actually inserted; a retried batch inserts only the seqs not yet stored. */
4575
+ inserted: number;
4576
+ newToolCalls: number;
4577
+ toolCallCount: number;
4578
+ }
4579
+ type FinishInput = {
4580
+ status: 'SUCCEEDED';
4581
+ /** Public: the requester, the owner and their teammates read it. */
4582
+ summary?: string;
4583
+ readyToClose?: boolean;
4584
+ usage?: Record<string, unknown>;
4585
+ } | {
4586
+ status: 'FAILED';
4587
+ error?: string;
4588
+ summary?: string;
4589
+ usage?: Record<string, unknown>;
4590
+ } | {
4591
+ status: 'WAITING_ON_OWNER';
4592
+ /** Required: the app posts it as a comment mentioning the owner and parks the run. */
4593
+ question: string;
4594
+ summary?: string;
4595
+ usage?: Record<string, unknown>;
4596
+ };
4597
+ interface FinishResult {
4598
+ /** false — a cancel landed first; nothing was posted. */
4599
+ finished: boolean;
4600
+ status: AgentRunStatus;
4601
+ /** The ask-owner comment, for WAITING_ON_OWNER. */
4602
+ commentId?: string | null;
4603
+ }
4604
+ declare class AgentRunsApi {
4605
+ private client;
4606
+ constructor(client: TrpcClient);
4607
+ /**
4608
+ * Claim the oldest queued LOCAL_CLI run of this key's Assistant, or null when
4609
+ * nothing is queued. `runnerId` names this machine/process; it is recorded on
4610
+ * the run and checked by the other calls.
4611
+ */
4612
+ claim(runnerId: string): Promise<ClaimedRun | null>;
4613
+ /** Keep the run alive while a step is slow (the app times out a silent run after 5 minutes). */
4614
+ heartbeat(runId: string, runnerId?: string): Promise<HeartbeatResult>;
4615
+ /**
4616
+ * Append transcript events (1–200 per call). Idempotent on `seq`, so a batch
4617
+ * may be retried after a network error without duplicating lines.
4618
+ */
4619
+ appendEvents(runId: string, events: RunnerEvent[], runnerId?: string): Promise<AppendEventsResult>;
4620
+ /** End the run: succeeded, failed, or waiting on the owner's answer to `question`. */
4621
+ finish(runId: string, input: FinishInput, runnerId?: string): Promise<FinishResult>;
4622
+ }
4623
+
4352
4624
  interface ExponentialConfig {
4353
4625
  apiUrl: string;
4354
4626
  token: string;
@@ -4440,15 +4712,18 @@ declare class ExponentialClient {
4440
4712
  areas: AreasApi;
4441
4713
  meetings: MeetingsApi;
4442
4714
  pages: PagesApi;
4715
+ resources: ResourcesApi;
4443
4716
  requirements: RequirementsApi;
4444
4717
  scopes: ScopesApi;
4445
4718
  search: SearchApi;
4446
4719
  /** Time entries — the Daily worklog's write path (ADR-0061). */
4447
4720
  time: TimeApi;
4721
+ /** Agent runs — the local runner's claim/heartbeat/append/finish (ADR-0067); agent-key only. */
4722
+ agentRuns: AgentRunsApi;
4448
4723
  constructor(config: {
4449
4724
  token: string;
4450
4725
  apiUrl: string;
4451
4726
  });
4452
4727
  }
4453
4728
 
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 };
4729
+ 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 ReadStatus, type Requirement, type RequirementCreateInput, type RequirementKind, type RequirementListOptions, type Resource, type ResourceContentType, type ResourceCreateInput, type ResourceListOptions, type ResourceListResult, type ResourceReadState, type RunMessage, type RunnerEvent, type RunnerEventKind, type ScopeCreateInput, type ScopeListOptions, type ScopeUpdateInput, type SearchResult, type SearchResultType, type SearchResultWorkspace, type SetEntityTagsInput, type SetEntityTagsResult, type Tag, type TagEntityType, type TagListResult, type Ticket, type TicketAssignee, type TicketComment, type TicketCommentAddInput, type TicketCommentUpdateInput, type TicketCreateInput, type TicketDependencyEdge, type TicketDetail, type TicketListOptions, type TicketSearchOptions, type TicketStatus, type TicketType, type TicketUpdateInput, TimeApi, type TimeConfirmDayResult, type TimeEntry, type TimeEntrySource, type TimeEntryStatus, type TimeLogBatchResult, type TimeLogInput, type TimeLogOutcome, type TimeLogResult, type TodaysActionRow, type TodaysActions, type TodaysActionsGroup, type UserStory, type UserStoryCreateInput, type UserStoryListOptions, type UserStoryUpdateInput, type WorklogSegment, type Workspace, type WorkspaceMember, type WorkspaceOutput, type WorkspacesListOutput, clearConfig, createConfigStore, getConfigPath, isAuthenticated, isTRPCError, loadConfig, saveConfig, segmentConversation };
package/dist/index.js CHANGED
@@ -1087,6 +1087,45 @@ var PagesApi = class {
1087
1087
  }
1088
1088
  };
1089
1089
 
1090
+ // src/resources.ts
1091
+ var ResourcesApi = class {
1092
+ constructor(client) {
1093
+ this.client = client;
1094
+ }
1095
+ async list(options = {}) {
1096
+ return await this.client.resource.list.query(options);
1097
+ }
1098
+ async create(input) {
1099
+ const result = await this.client.resource.create.mutate(input);
1100
+ return result.resource;
1101
+ }
1102
+ /** Save a link to the Reading list: a `bookmark` in `to_read`, not embedded. */
1103
+ async save(input) {
1104
+ return await this.create({
1105
+ title: input.title?.trim() || hostnameOf(input.url) || input.url,
1106
+ url: input.url,
1107
+ description: input.note,
1108
+ contentType: "bookmark",
1109
+ readStatus: input.readStatus ?? "to_read",
1110
+ generateEmbeddings: false,
1111
+ workspaceId: input.workspaceId
1112
+ });
1113
+ }
1114
+ async setReadStatus(id, readStatus) {
1115
+ return await this.client.resource.setReadStatus.mutate({ id, readStatus });
1116
+ }
1117
+ async archive(id) {
1118
+ return await this.client.resource.archive.mutate({ id });
1119
+ }
1120
+ };
1121
+ function hostnameOf(url) {
1122
+ try {
1123
+ return new URL(url).hostname.replace(/^www\./, "");
1124
+ } catch {
1125
+ return null;
1126
+ }
1127
+ }
1128
+
1090
1129
  // src/requirements.ts
1091
1130
  var RequirementsApi = class {
1092
1131
  constructor(client) {
@@ -1256,6 +1295,36 @@ var TimeApi = class {
1256
1295
  }
1257
1296
  };
1258
1297
 
1298
+ // src/agentRuns.ts
1299
+ var AgentRunsApi = class {
1300
+ constructor(client) {
1301
+ this.client = client;
1302
+ }
1303
+ /**
1304
+ * Claim the oldest queued LOCAL_CLI run of this key's Assistant, or null when
1305
+ * nothing is queued. `runnerId` names this machine/process; it is recorded on
1306
+ * the run and checked by the other calls.
1307
+ */
1308
+ async claim(runnerId) {
1309
+ return await this.client.agentRun.claim.mutate({ runnerId });
1310
+ }
1311
+ /** Keep the run alive while a step is slow (the app times out a silent run after 5 minutes). */
1312
+ async heartbeat(runId, runnerId) {
1313
+ return await this.client.agentRun.heartbeat.mutate({ runId, runnerId });
1314
+ }
1315
+ /**
1316
+ * Append transcript events (1–200 per call). Idempotent on `seq`, so a batch
1317
+ * may be retried after a network error without duplicating lines.
1318
+ */
1319
+ async appendEvents(runId, events, runnerId) {
1320
+ return await this.client.agentRun.appendEvents.mutate({ runId, runnerId, events });
1321
+ }
1322
+ /** End the run: succeeded, failed, or waiting on the owner's answer to `question`. */
1323
+ async finish(runId, input, runnerId) {
1324
+ return await this.client.agentRun.finish.mutate({ runId, runnerId, ...input });
1325
+ }
1326
+ };
1327
+
1259
1328
  // src/config.ts
1260
1329
  import Conf from "conf";
1261
1330
  var schema = {
@@ -1419,10 +1488,12 @@ var ExponentialClient = class {
1419
1488
  this.areas = new AreasApi(this.client);
1420
1489
  this.meetings = new MeetingsApi(this.client);
1421
1490
  this.pages = new PagesApi(this.client);
1491
+ this.resources = new ResourcesApi(this.client);
1422
1492
  this.requirements = new RequirementsApi(this.client);
1423
1493
  this.scopes = new ScopesApi(this.client);
1424
1494
  this.search = new SearchApi(this.client);
1425
1495
  this.time = new TimeApi(this.client);
1496
+ this.agentRuns = new AgentRunsApi(this.client);
1426
1497
  }
1427
1498
  client;
1428
1499
  actions;
@@ -1448,13 +1519,17 @@ var ExponentialClient = class {
1448
1519
  areas;
1449
1520
  meetings;
1450
1521
  pages;
1522
+ resources;
1451
1523
  requirements;
1452
1524
  scopes;
1453
1525
  search;
1454
1526
  /** Time entries — the Daily worklog's write path (ADR-0061). */
1455
1527
  time;
1528
+ /** Agent runs — the local runner's claim/heartbeat/append/finish (ADR-0067); agent-key only. */
1529
+ agentRuns;
1456
1530
  };
1457
1531
  export {
1532
+ AgentRunsApi,
1458
1533
  DEFAULT_GAP_MINUTES,
1459
1534
  ExponentialClient,
1460
1535
  ROUND_MINUTES,