@camox/api-contract 0.75.0 → 0.76.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/threads.d.ts CHANGED
@@ -69,6 +69,14 @@ export type PushOutcome = z.infer<typeof pushOutcomeSchema>;
69
69
  * call of it went through ends on the draft's card.
70
70
  */
71
71
  export declare const START_DRAFT_TOOL = "startDraft";
72
+ /**
73
+ * The agent on Live's tool restoring an archived draft and handing the editor to it, as
74
+ * `startDraft` does (ADR 0025, ADR 0046). A run whose call of it went through ends on the
75
+ * draft's card.
76
+ */
77
+ export declare const RESTORE_DRAFT_TOOL = "restoreDraft";
78
+ /** Whether a call of the tool `name` hands the editor off to a draft, which ends the run on its card. */
79
+ export declare const handsOffToDraft: (name: string) => name is "restoreDraft" | "startDraft";
72
80
  /** The agent's tool building its code changes mid-turn, which the end of a turn also does. */
73
81
  export declare const BUILD_TOOL = "build";
74
82
  /** The agent's tool rendering the draft in a browser and returning screenshots to the model. */
@@ -140,21 +148,27 @@ export declare const handsOff: (name: string) => boolean;
140
148
  * keeps this in step with the tools themselves.
141
149
  */
142
150
  export declare const CHANGING_TOOLS: ReadonlySet<string>;
143
- /** The draft a `startDraft` call started, as its result's details name it for the card. */
151
+ /**
152
+ * The draft a `startDraft` call started, or a `restoreDraft` call restored, as its result's
153
+ * details name it for the card.
154
+ */
144
155
  export declare const startedDraftCardSchema: z.ZodObject<{
145
156
  draftId: z.ZodString;
146
157
  name: z.ZodString;
158
+ restored: z.ZodOptional<z.ZodLiteral<true>>;
147
159
  }, z.core.$strip>;
148
160
  export type StartedDraftCard = z.infer<typeof startedDraftCardSchema>;
149
161
  /**
150
162
  * Where a draft a Live thread's card names stands, as the thread looks it up whenever it's shown
151
- * (ADR 0025): its current name, or its last once it ended, and how it ended. Never written into
152
- * the transcript, so the model's cached prompt keeps up. A name cleared by a rename is null: the
153
- * card keeps the name the agent gave it.
163
+ * (ADR 0025): its current name, or its last once it ended, and how it ended. An archived draft
164
+ * hasn't ended: `archived` says it's set aside until someone restores it (ADR 0046). Never written
165
+ * into the transcript, so the model's cached prompt keeps up. A name cleared by a rename is null:
166
+ * the card keeps the name the agent gave it.
154
167
  */
155
168
  export type DraftCardState = {
156
169
  name: string | null;
157
170
  ended?: DraftOutcome;
171
+ archived?: true;
158
172
  };
159
173
  /** The drafts a Live thread's cards name, by id, as the thread last looked them up. */
160
174
  export type DraftCardStates = Readonly<Record<string, DraftCardState>>;
@@ -245,13 +259,14 @@ export declare const editorMessageDataSchema: z.ZodObject<{
245
259
  operationId: z.ZodOptional<z.ZodString>;
246
260
  }, z.core.$strip>;
247
261
  /**
248
- * A draft the agent on Live started with `startDraft`, and the operation ids of the messages of
249
- * the run that started it: the studio that sent one of them enters the draft, if it still shows
262
+ * A draft the agent on Live started with `startDraft`, or restored with `restoreDraft`, and the
263
+ * operation ids of the messages of the run that did: the studio that sent one of them enters the draft, if it still shows
250
264
  * Live.
251
265
  */
252
266
  export declare const startedDraftSchema: z.ZodObject<{
253
267
  draftId: z.ZodString;
254
268
  operationIds: z.ZodArray<z.ZodString>;
269
+ restored: z.ZodOptional<z.ZodLiteral<true>>;
255
270
  }, z.core.$strip>;
256
271
  export type StartedDraft = z.infer<typeof startedDraftSchema>;
257
272
  /** How a write touched what it names. */
@@ -405,12 +420,14 @@ export type ThreadMessage = {
405
420
  /**
406
421
  * In place of the agent's message, for a Live turn handed off to a draft the agent started:
407
422
  * the draft's card, with its current name, which opens it. Once the draft ended, it has its
408
- * last name and how it ended, and opens nothing. The turn is finished.
423
+ * last name and how it ended, and opens nothing. While the draft is archived, `archived` is set,
424
+ * and the card offers to restore it. The turn is finished.
409
425
  */
410
426
  ({
411
427
  id: string;
412
428
  from: "draft";
413
429
  ended?: DraftOutcome;
430
+ archived?: true;
414
431
  } & StartedDraftCard) |
415
432
  /**
416
433
  * A member's push to the draft's code from their own checkout: who pushed, their commits'
package/dist/threads.js CHANGED
@@ -66,6 +66,14 @@ const pushOutcomeSchema = z.enum([
66
66
  * call of it went through ends on the draft's card.
67
67
  */
68
68
  const START_DRAFT_TOOL = "startDraft";
69
+ /**
70
+ * The agent on Live's tool restoring an archived draft and handing the editor to it, as
71
+ * `startDraft` does (ADR 0025, ADR 0046). A run whose call of it went through ends on the
72
+ * draft's card.
73
+ */
74
+ const RESTORE_DRAFT_TOOL = "restoreDraft";
75
+ /** Whether a call of the tool `name` hands the editor off to a draft, which ends the run on its card. */
76
+ const handsOffToDraft = (name) => name === "startDraft" || name === "restoreDraft";
69
77
  /** The agent's tool building its code changes mid-turn, which the end of a turn also does. */
70
78
  const BUILD_TOOL = "build";
71
79
  /** The agent's tool rendering the draft in a browser and returning screenshots to the model. */
@@ -138,6 +146,7 @@ const CHANGING_TOOLS = /* @__PURE__ */ new Set([
138
146
  "addBackToLocale",
139
147
  "addLocale",
140
148
  "applyFindingFix",
149
+ "copyFromPastWork",
141
150
  "createBlock",
142
151
  "createCollectionRecord",
143
152
  "createPage",
@@ -158,10 +167,15 @@ const CHANGING_TOOLS = /* @__PURE__ */ new Set([
158
167
  "rm",
159
168
  "write"
160
169
  ]);
161
- /** The draft a `startDraft` call started, as its result's details name it for the card. */
170
+ /**
171
+ * The draft a `startDraft` call started, or a `restoreDraft` call restored, as its result's
172
+ * details name it for the card.
173
+ */
162
174
  const startedDraftCardSchema = z.object({
163
175
  draftId: z.string(),
164
- name: z.string()
176
+ name: z.string(),
177
+ /** The agent restored the archived draft rather than starting it (ADR 0046). */
178
+ restored: z.literal(true).optional()
165
179
  });
166
180
  const reconcileDataSchema = z.object({ message: z.string() });
167
181
  const buildStatusSchema = z.enum(["building", "fixing"]);
@@ -210,13 +224,18 @@ const pushDataSchema = z.object({
210
224
  /** What an editor's message entry records: who sent it, and the operation id it was sent with. */
211
225
  const editorMessageDataSchema = threadSenderSchema.extend({ operationId: z.string().optional() });
212
226
  /**
213
- * A draft the agent on Live started with `startDraft`, and the operation ids of the messages of
214
- * the run that started it: the studio that sent one of them enters the draft, if it still shows
227
+ * A draft the agent on Live started with `startDraft`, or restored with `restoreDraft`, and the
228
+ * operation ids of the messages of the run that did: the studio that sent one of them enters the draft, if it still shows
215
229
  * Live.
216
230
  */
217
231
  const startedDraftSchema = z.object({
218
232
  draftId: z.string(),
219
- operationIds: z.array(z.string())
233
+ operationIds: z.array(z.string()),
234
+ /**
235
+ * The agent restored the archived draft rather than starting it: its thread goes on from its
236
+ * own messages, without the run's.
237
+ */
238
+ restored: z.literal(true).optional()
220
239
  });
221
240
  /** How a write touched what it names. */
222
241
  const touchKindSchema = z.enum([
@@ -460,7 +479,7 @@ function threadStepOf(entry) {
460
479
  text: details.answer
461
480
  };
462
481
  }
463
- const card = message.toolName === "startDraft" && !message.isError ? startedDraftCardSchema.safeParse(message.details).data : void 0;
482
+ const card = handsOffToDraft(message.toolName) && !message.isError ? startedDraftCardSchema.safeParse(message.details).data : void 0;
464
483
  return card ? {
465
484
  id,
466
485
  type: "draft",
@@ -583,7 +602,9 @@ function threadViewOf({ steps, running, toolCalls = [], callingTools = false, ch
583
602
  from: "draft",
584
603
  draftId: step.draftId,
585
604
  name: draft?.name ?? step.name,
586
- ...draft?.ended && { ended: draft.ended }
605
+ ...step.restored && { restored: true },
606
+ ...draft?.ended && { ended: draft.ended },
607
+ ...draft?.archived && { archived: true }
587
608
  });
588
609
  }
589
610
  endTurn();
@@ -640,7 +661,7 @@ function activityOf({ status, toolCalls, callingTools, changing, checking, hande
640
661
  if (status === "fixing") return "fixing";
641
662
  if (toolCalls.some((call) => handsOff(call.name))) return handedOffActivity ?? "changing";
642
663
  if (checking) return "checking";
643
- if (calling("startDraft")) return "startingDraft";
664
+ if (toolCalls.some((call) => handsOffToDraft(call.name))) return "startingDraft";
644
665
  if (changing) return "changing";
645
666
  if (callingTools || toolCalls.length > 0) return "exploring";
646
667
  return "thinking";
@@ -772,4 +793,4 @@ function reduceThreadFrame(state, frame) {
772
793
  }
773
794
 
774
795
  //#endregion
775
- export { ARTIFACT_REQUEST_ENTRY, ARTIFACT_TOOL, ASK_TOOL, BRIEF_ENTRY, BUILD_STATUS_ENTRY, BUILD_TOOL, CHANGING_TOOLS, CODE_REQUEST_ENTRY, CODE_TOOL, CONNECTED_AGENT_MESSAGE_ENTRY, DRAFT_CARD_ENTRY, DRAFT_ENDED_ENTRY, EDITOR_MESSAGE_ENTRY, EMPTY_THREAD_STATE, EMPTY_THREAD_VIEW, LOOK_TOOL, PUSH_ENTRY, QUESTIONS_ENTRY, RECONCILE_ENTRY, RUN_STOPPED_ENTRY, START_DRAFT_TOOL, THREAD_ENDED_CLOSE_CODE, agentActivitySchema, artifactRequestDataSchema, buildStatusDataSchema, buildStatusSchema, codeRequestDataSchema, connectedAgentClientSchema, connectedAgentMessageDataSchema, editorMessageDataSchema, editorSelectionSchema, editorTextOf, editorWhereSchema, handOffDetailsSchema, handsOff, isSender, messageAttachmentSchema, pushDataSchema, pushOutcomeSchema, questionsDataSchema, reconcileDataSchema, reduceThreadEvents, reduceThreadFrame, reduceThreadState, startedDraftCardSchema, startedDraftSchema, textOf, threadClientMessageSchema, threadSenderSchema, threadViewOf, touchKindSchema, touchSchema, touchedBatchSchema };
796
+ export { ARTIFACT_REQUEST_ENTRY, ARTIFACT_TOOL, ASK_TOOL, BRIEF_ENTRY, BUILD_STATUS_ENTRY, BUILD_TOOL, CHANGING_TOOLS, CODE_REQUEST_ENTRY, CODE_TOOL, CONNECTED_AGENT_MESSAGE_ENTRY, DRAFT_CARD_ENTRY, DRAFT_ENDED_ENTRY, EDITOR_MESSAGE_ENTRY, EMPTY_THREAD_STATE, EMPTY_THREAD_VIEW, LOOK_TOOL, PUSH_ENTRY, QUESTIONS_ENTRY, RECONCILE_ENTRY, RESTORE_DRAFT_TOOL, RUN_STOPPED_ENTRY, START_DRAFT_TOOL, THREAD_ENDED_CLOSE_CODE, agentActivitySchema, artifactRequestDataSchema, buildStatusDataSchema, buildStatusSchema, codeRequestDataSchema, connectedAgentClientSchema, connectedAgentMessageDataSchema, editorMessageDataSchema, editorSelectionSchema, editorTextOf, editorWhereSchema, handOffDetailsSchema, handsOff, handsOffToDraft, isSender, messageAttachmentSchema, pushDataSchema, pushOutcomeSchema, questionsDataSchema, reconcileDataSchema, reduceThreadEvents, reduceThreadFrame, reduceThreadState, startedDraftCardSchema, startedDraftSchema, textOf, threadClientMessageSchema, threadSenderSchema, threadViewOf, touchKindSchema, touchSchema, touchedBatchSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camox/api-contract",
3
- "version": "0.75.0",
3
+ "version": "0.76.0",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "src",
package/src/drafts.ts CHANGED
@@ -158,6 +158,22 @@ export type EndedDraft = {
158
158
  endedAt: number;
159
159
  };
160
160
 
161
+ /**
162
+ * A draft set aside without ending it (ADR 0046): who archived it, a member or Camox, and when.
163
+ * It keeps its id, changes, thread and code until it's restored or deleted.
164
+ */
165
+ export type ArchivedDraft = {
166
+ draftId: string;
167
+ archivedBy: { id: string; name: string };
168
+ archivedAt: number;
169
+ };
170
+
171
+ /**
172
+ * The oRPC error code a request naming an archived draft fails with: its `data` is an
173
+ * `ArchivedDraft`. Nothing reads or writes the draft until it's restored.
174
+ */
175
+ export const DRAFT_ARCHIVED_ERROR_CODE = "DRAFT_ARCHIVED";
176
+
161
177
  /**
162
178
  * The oRPC error code a request naming an ended draft fails with. Its `data` is an `EndedDraft`,
163
179
  * so a page can render Live and say who published or deleted the draft.
package/src/query-keys.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { EndedDraft } from "./drafts";
1
+ import type { ArchivedDraft, EndedDraft } from "./drafts";
2
2
 
3
3
  /**
4
4
  * Use TypeScript to enforce 'camox' as the first query key to ensure they're all namespaced.
@@ -58,6 +58,14 @@ export const queryKeys = {
58
58
  list: ["camox", "drafts", "list"],
59
59
  // The draft a viewer is in, scoped to it like content.
60
60
  get: ["camox", "drafts", "get"],
61
+ // Archived drafts (ADR 0046): under `all`, so whatever changes the drafts list refreshes it.
62
+ archived: ["camox", "drafts", "archived"],
63
+ },
64
+ // Publications (ADR 0045): the same for every viewer, whatever they're in.
65
+ publications: {
66
+ all: ["camox", "publications"],
67
+ list: ["camox", "publications", "list"],
68
+ get: ["camox", "publications", "get"],
61
69
  },
62
70
  // The Specialists of a scope: their reports and pending work.
63
71
  specialists: {
@@ -100,6 +108,9 @@ export type InvalidationMessage = {
100
108
  /** A draft was published or deleted: its viewers go back to Live. */
101
109
  export type DraftEndedMessage = { type: "draftEnded" } & EndedDraft;
102
110
 
111
+ /** A draft was archived: its viewers go back to Live (ADR 0046). */
112
+ export type DraftArchivedMessage = { type: "draftArchived" } & ArchivedDraft;
113
+
103
114
  /** A draft with code has a new revision, built with Camox's `sdkVersion`. */
104
115
  export type RevisionAnnouncement = { draftId: string; revisionId: string; sdkVersion: string };
105
116
 
@@ -107,4 +118,8 @@ export type RevisionAnnouncement = { draftId: string; revisionId: string; sdkVer
107
118
  export type RevisionMessage = { type: "revision" } & RevisionAnnouncement;
108
119
 
109
120
  /** Everything the project room broadcasts. */
110
- export type ProjectRoomMessage = InvalidationMessage | DraftEndedMessage | RevisionMessage;
121
+ export type ProjectRoomMessage =
122
+ | InvalidationMessage
123
+ | DraftEndedMessage
124
+ | DraftArchivedMessage
125
+ | RevisionMessage;
package/src/threads.ts CHANGED
@@ -81,6 +81,17 @@ export type PushOutcome = z.infer<typeof pushOutcomeSchema>;
81
81
  */
82
82
  export const START_DRAFT_TOOL = "startDraft";
83
83
 
84
+ /**
85
+ * The agent on Live's tool restoring an archived draft and handing the editor to it, as
86
+ * `startDraft` does (ADR 0025, ADR 0046). A run whose call of it went through ends on the
87
+ * draft's card.
88
+ */
89
+ export const RESTORE_DRAFT_TOOL = "restoreDraft";
90
+
91
+ /** Whether a call of the tool `name` hands the editor off to a draft, which ends the run on its card. */
92
+ export const handsOffToDraft = (name: string) =>
93
+ name === START_DRAFT_TOOL || name === RESTORE_DRAFT_TOOL;
94
+
84
95
  /** The agent's tool building its code changes mid-turn, which the end of a turn also does. */
85
96
  export const BUILD_TOOL = "build";
86
97
 
@@ -169,6 +180,7 @@ export const CHANGING_TOOLS: ReadonlySet<string> = new Set([
169
180
  "addBackToLocale",
170
181
  "addLocale",
171
182
  "applyFindingFix",
183
+ "copyFromPastWork",
172
184
  "createBlock",
173
185
  "createCollectionRecord",
174
186
  "createPage",
@@ -191,17 +203,26 @@ export const CHANGING_TOOLS: ReadonlySet<string> = new Set([
191
203
  "write",
192
204
  ]);
193
205
 
194
- /** The draft a `startDraft` call started, as its result's details name it for the card. */
195
- export const startedDraftCardSchema = z.object({ draftId: z.string(), name: z.string() });
206
+ /**
207
+ * The draft a `startDraft` call started, or a `restoreDraft` call restored, as its result's
208
+ * details name it for the card.
209
+ */
210
+ export const startedDraftCardSchema = z.object({
211
+ draftId: z.string(),
212
+ name: z.string(),
213
+ /** The agent restored the archived draft rather than starting it (ADR 0046). */
214
+ restored: z.literal(true).optional(),
215
+ });
196
216
  export type StartedDraftCard = z.infer<typeof startedDraftCardSchema>;
197
217
 
198
218
  /**
199
219
  * Where a draft a Live thread's card names stands, as the thread looks it up whenever it's shown
200
- * (ADR 0025): its current name, or its last once it ended, and how it ended. Never written into
201
- * the transcript, so the model's cached prompt keeps up. A name cleared by a rename is null: the
202
- * card keeps the name the agent gave it.
220
+ * (ADR 0025): its current name, or its last once it ended, and how it ended. An archived draft
221
+ * hasn't ended: `archived` says it's set aside until someone restores it (ADR 0046). Never written
222
+ * into the transcript, so the model's cached prompt keeps up. A name cleared by a rename is null:
223
+ * the card keeps the name the agent gave it.
203
224
  */
204
- export type DraftCardState = { name: string | null; ended?: DraftOutcome };
225
+ export type DraftCardState = { name: string | null; ended?: DraftOutcome; archived?: true };
205
226
 
206
227
  /** The drafts a Live thread's cards name, by id, as the thread last looked them up. */
207
228
  export type DraftCardStates = Readonly<Record<string, DraftCardState>>;
@@ -269,13 +290,18 @@ export const editorMessageDataSchema = threadSenderSchema.extend({
269
290
  });
270
291
 
271
292
  /**
272
- * A draft the agent on Live started with `startDraft`, and the operation ids of the messages of
273
- * the run that started it: the studio that sent one of them enters the draft, if it still shows
293
+ * A draft the agent on Live started with `startDraft`, or restored with `restoreDraft`, and the
294
+ * operation ids of the messages of the run that did: the studio that sent one of them enters the draft, if it still shows
274
295
  * Live.
275
296
  */
276
297
  export const startedDraftSchema = z.object({
277
298
  draftId: z.string(),
278
299
  operationIds: z.array(z.string()),
300
+ /**
301
+ * The agent restored the archived draft rather than starting it: its thread goes on from its
302
+ * own messages, without the run's.
303
+ */
304
+ restored: z.literal(true).optional(),
279
305
  });
280
306
  export type StartedDraft = z.infer<typeof startedDraftSchema>;
281
307
 
@@ -359,9 +385,10 @@ export type ThreadMessage =
359
385
  /**
360
386
  * In place of the agent's message, for a Live turn handed off to a draft the agent started:
361
387
  * the draft's card, with its current name, which opens it. Once the draft ended, it has its
362
- * last name and how it ended, and opens nothing. The turn is finished.
388
+ * last name and how it ended, and opens nothing. While the draft is archived, `archived` is set,
389
+ * and the card offers to restore it. The turn is finished.
363
390
  */
364
- | ({ id: string; from: "draft"; ended?: DraftOutcome } & StartedDraftCard)
391
+ | ({ id: string; from: "draft"; ended?: DraftOutcome; archived?: true } & StartedDraftCard)
365
392
  /**
366
393
  * A member's push to the draft's code from their own checkout: who pushed, their commits'
367
394
  * subjects, oldest first, and how the pushed head built. It's no turn: the agent doesn't
@@ -659,7 +686,7 @@ function threadStepOf(entry: EntryRecord): ThreadStep | undefined {
659
686
  if (details?.final && details.answer) return { id, type: "answer", text: details.answer };
660
687
  }
661
688
  const card =
662
- message.toolName === START_DRAFT_TOOL && !message.isError
689
+ handsOffToDraft(message.toolName) && !message.isError
663
690
  ? startedDraftCardSchema.safeParse(message.details).data
664
691
  : undefined;
665
692
  return card ? { id, type: "draft", ...card } : { id, type: "tools" };
@@ -771,7 +798,9 @@ export function threadViewOf({
771
798
  from: "draft",
772
799
  draftId: step.draftId,
773
800
  name: draft?.name ?? step.name,
801
+ ...(step.restored && { restored: true as const }),
774
802
  ...(draft?.ended && { ended: draft.ended }),
803
+ ...(draft?.archived && { archived: true as const }),
775
804
  });
776
805
  }
777
806
  endTurn();
@@ -850,7 +879,7 @@ function activityOf({
850
879
  // the agent's.
851
880
  if (toolCalls.some((call) => handsOff(call.name))) return handedOffActivity ?? "changing";
852
881
  if (checking) return "checking";
853
- if (calling(START_DRAFT_TOOL)) return "startingDraft";
882
+ if (toolCalls.some((call) => handsOffToDraft(call.name))) return "startingDraft";
854
883
  if (changing) return "changing";
855
884
  if (callingTools || toolCalls.length > 0) return "exploring";
856
885
  return "thinking";