@camox/api-contract 0.58.1 → 0.59.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/drafts.d.ts +1 -13
- package/dist/drafts.js +1 -11
- package/dist/projects.d.ts +8 -2
- package/dist/projects.js +5 -2
- package/dist/router.d.ts +629 -356
- package/dist/threads.d.ts +46 -3
- package/dist/threads.js +37 -3
- package/package.json +1 -1
- package/src/drafts.ts +3 -18
- package/src/projects.ts +6 -2
- package/src/threads.ts +43 -3
package/dist/threads.d.ts
CHANGED
|
@@ -34,6 +34,19 @@ export declare const BRIEF_ENTRY = "camox.brief";
|
|
|
34
34
|
* it at the end of the conversation; editors never see it, since the draft's card says so.
|
|
35
35
|
*/
|
|
36
36
|
export declare const DRAFT_ENDED_ENTRY = "camox.draft-ended";
|
|
37
|
+
/**
|
|
38
|
+
* The kind of the transcript entry recording a member's push to the draft's code from their own
|
|
39
|
+
* checkout (ADR 0026), with a `pushDataSchema` as data. The model reads it as context, never
|
|
40
|
+
* answering it, and editors see who pushed, their commits, and whether they built.
|
|
41
|
+
*/
|
|
42
|
+
export declare const PUSH_ENTRY = "camox.push";
|
|
43
|
+
/** How a pushed head's build ended: built, built with type errors, or built but not previewed. */
|
|
44
|
+
export declare const pushOutcomeSchema: z.ZodEnum<{
|
|
45
|
+
built: "built";
|
|
46
|
+
typeErrors: "typeErrors";
|
|
47
|
+
notPreviewed: "notPreviewed";
|
|
48
|
+
}>;
|
|
49
|
+
export type PushOutcome = z.infer<typeof pushOutcomeSchema>;
|
|
37
50
|
/**
|
|
38
51
|
* The agent's tool on Live handing a request off to a draft it starts (ADR 0025). A run whose
|
|
39
52
|
* call of it went through ends on the draft's card.
|
|
@@ -80,6 +93,21 @@ export declare const threadSenderSchema: z.ZodObject<{
|
|
|
80
93
|
export type ThreadSender = z.infer<typeof threadSenderSchema>;
|
|
81
94
|
/** Whether `data` names a sender. */
|
|
82
95
|
export declare const isSender: (data: unknown) => data is ThreadSender;
|
|
96
|
+
/** What a push's entry records: who pushed, their commits' subjects, oldest first, and the build. */
|
|
97
|
+
export declare const pushDataSchema: z.ZodObject<{
|
|
98
|
+
pusher: z.ZodObject<{
|
|
99
|
+
id: z.ZodString;
|
|
100
|
+
name: z.ZodString;
|
|
101
|
+
image: z.ZodNullable<z.ZodString>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
subjects: z.ZodArray<z.ZodString>;
|
|
104
|
+
outcome: z.ZodEnum<{
|
|
105
|
+
built: "built";
|
|
106
|
+
typeErrors: "typeErrors";
|
|
107
|
+
notPreviewed: "notPreviewed";
|
|
108
|
+
}>;
|
|
109
|
+
}, z.core.$strip>;
|
|
110
|
+
export type PushData = z.infer<typeof pushDataSchema>;
|
|
83
111
|
/**
|
|
84
112
|
* What an editor's message entry records: who sent it, the operation id it was sent with, and for
|
|
85
113
|
* a message sent on Live as the agent handed the request off, the draft it went to with it.
|
|
@@ -233,7 +261,19 @@ export type ThreadMessage = {
|
|
|
233
261
|
id: string;
|
|
234
262
|
from: "draft";
|
|
235
263
|
ended?: DraftOutcome;
|
|
236
|
-
} & StartedDraftCard)
|
|
264
|
+
} & StartedDraftCard) |
|
|
265
|
+
/**
|
|
266
|
+
* A member's push to the draft's code from their own checkout: who pushed, their commits'
|
|
267
|
+
* subjects, oldest first, and how the pushed head built. It's no turn: the agent doesn't
|
|
268
|
+
* answer it.
|
|
269
|
+
*/
|
|
270
|
+
{
|
|
271
|
+
id: string;
|
|
272
|
+
from: "push";
|
|
273
|
+
sender: ThreadSender;
|
|
274
|
+
subjects: string[];
|
|
275
|
+
outcome: PushOutcome;
|
|
276
|
+
};
|
|
237
277
|
/** Everything the studio shows for a thread. */
|
|
238
278
|
export type ThreadView = {
|
|
239
279
|
messages: readonly ThreadMessage[];
|
|
@@ -305,6 +345,10 @@ type ThreadStep = {
|
|
|
305
345
|
type: "build";
|
|
306
346
|
status: BuildStatus;
|
|
307
347
|
} |
|
|
348
|
+
/** A member's push, between turns. */
|
|
349
|
+
({
|
|
350
|
+
type: "push";
|
|
351
|
+
} & PushData) |
|
|
308
352
|
/**
|
|
309
353
|
* The end of the turn sent the agent back to work, after its answer: the answer wasn't the
|
|
310
354
|
* turn's last, and what the agent was told is never shown.
|
|
@@ -368,8 +412,7 @@ export type ThreadServerMessage =
|
|
|
368
412
|
};
|
|
369
413
|
/**
|
|
370
414
|
* The code a thread closes its sockets with once it ended with its draft, and for good: it's
|
|
371
|
-
* deleted, so reconnecting reaches nothing.
|
|
372
|
-
* thread the next time the studio connects.
|
|
415
|
+
* deleted, so reconnecting reaches nothing.
|
|
373
416
|
*/
|
|
374
417
|
export declare const THREAD_ENDED_CLOSE_CODE = 4000;
|
|
375
418
|
/** The text of a message's content: its text parts, joined. */
|
package/dist/threads.js
CHANGED
|
@@ -33,6 +33,18 @@ const BRIEF_ENTRY = "camox.brief";
|
|
|
33
33
|
*/
|
|
34
34
|
const DRAFT_ENDED_ENTRY = "camox.draft-ended";
|
|
35
35
|
/**
|
|
36
|
+
* The kind of the transcript entry recording a member's push to the draft's code from their own
|
|
37
|
+
* checkout (ADR 0026), with a `pushDataSchema` as data. The model reads it as context, never
|
|
38
|
+
* answering it, and editors see who pushed, their commits, and whether they built.
|
|
39
|
+
*/
|
|
40
|
+
const PUSH_ENTRY = "camox.push";
|
|
41
|
+
/** How a pushed head's build ended: built, built with type errors, or built but not previewed. */
|
|
42
|
+
const pushOutcomeSchema = z.enum([
|
|
43
|
+
"built",
|
|
44
|
+
"typeErrors",
|
|
45
|
+
"notPreviewed"
|
|
46
|
+
]);
|
|
47
|
+
/**
|
|
36
48
|
* The agent's tool on Live handing a request off to a draft it starts (ADR 0025). A run whose
|
|
37
49
|
* call of it went through ends on the draft's card.
|
|
38
50
|
*/
|
|
@@ -53,6 +65,12 @@ const threadSenderSchema = z.object({
|
|
|
53
65
|
});
|
|
54
66
|
/** Whether `data` names a sender. */
|
|
55
67
|
const isSender = (data) => threadSenderSchema.safeParse(data).success;
|
|
68
|
+
/** What a push's entry records: who pushed, their commits' subjects, oldest first, and the build. */
|
|
69
|
+
const pushDataSchema = z.object({
|
|
70
|
+
pusher: threadSenderSchema,
|
|
71
|
+
subjects: z.array(z.string()),
|
|
72
|
+
outcome: pushOutcomeSchema
|
|
73
|
+
});
|
|
56
74
|
/**
|
|
57
75
|
* What an editor's message entry records: who sent it, the operation id it was sent with, and for
|
|
58
76
|
* a message sent on Live as the agent handed the request off, the draft it went to with it.
|
|
@@ -134,8 +152,7 @@ const threadClientMessageSchema = z.discriminatedUnion("type", [
|
|
|
134
152
|
]);
|
|
135
153
|
/**
|
|
136
154
|
* The code a thread closes its sockets with once it ended with its draft, and for good: it's
|
|
137
|
-
* deleted, so reconnecting reaches nothing.
|
|
138
|
-
* thread the next time the studio connects.
|
|
155
|
+
* deleted, so reconnecting reaches nothing.
|
|
139
156
|
*/
|
|
140
157
|
const THREAD_ENDED_CLOSE_CODE = 4e3;
|
|
141
158
|
/** The text of a message's content: its text parts, joined. */
|
|
@@ -184,6 +201,14 @@ function threadStepOf(entry) {
|
|
|
184
201
|
};
|
|
185
202
|
}
|
|
186
203
|
if (entry.kind === "camox.draft-ended") return void 0;
|
|
204
|
+
if (entry.kind === "camox.push") {
|
|
205
|
+
const push = pushDataSchema.safeParse(entry.data).data;
|
|
206
|
+
return push && {
|
|
207
|
+
id,
|
|
208
|
+
type: "push",
|
|
209
|
+
...push
|
|
210
|
+
};
|
|
211
|
+
}
|
|
187
212
|
const message = entry.model?.find((candidate) => candidate.role !== "system");
|
|
188
213
|
if (!message) return void 0;
|
|
189
214
|
if (message.role === "user") {
|
|
@@ -338,6 +363,15 @@ function threadViewOf({ steps, running, toolCalls = [], callingTools = false, dr
|
|
|
338
363
|
case "build":
|
|
339
364
|
status = step.status;
|
|
340
365
|
break;
|
|
366
|
+
case "push":
|
|
367
|
+
messages.push({
|
|
368
|
+
id: step.id,
|
|
369
|
+
from: "push",
|
|
370
|
+
sender: step.pusher,
|
|
371
|
+
subjects: step.subjects,
|
|
372
|
+
outcome: step.outcome
|
|
373
|
+
});
|
|
374
|
+
break;
|
|
341
375
|
case "tools":
|
|
342
376
|
unfinished = false;
|
|
343
377
|
break;
|
|
@@ -418,4 +452,4 @@ function reduceThreadFrame(state, frame) {
|
|
|
418
452
|
}
|
|
419
453
|
|
|
420
454
|
//#endregion
|
|
421
|
-
export { BRIEF_ENTRY, BUILD_STATUS_ENTRY, DRAFT_ENDED_ENTRY, EDITOR_MESSAGE_ENTRY, EMPTY_THREAD_STATE, EMPTY_THREAD_VIEW, RECONCILE_ENTRY, RUN_STOPPED_ENTRY, START_DRAFT_TOOL, THREAD_ENDED_CLOSE_CODE, buildStatusDataSchema, buildStatusSchema, editorMessageDataSchema, isSender, reconcileDataSchema, reduceThreadEvents, reduceThreadFrame, reduceThreadState, startedDraftCardSchema, startedDraftSchema, textOf, threadClientMessageSchema, threadSenderSchema, threadViewOf, touchKindSchema, touchSchema, touchedBatchSchema };
|
|
455
|
+
export { BRIEF_ENTRY, BUILD_STATUS_ENTRY, DRAFT_ENDED_ENTRY, EDITOR_MESSAGE_ENTRY, EMPTY_THREAD_STATE, EMPTY_THREAD_VIEW, PUSH_ENTRY, RECONCILE_ENTRY, RUN_STOPPED_ENTRY, START_DRAFT_TOOL, THREAD_ENDED_CLOSE_CODE, buildStatusDataSchema, buildStatusSchema, editorMessageDataSchema, isSender, pushDataSchema, pushOutcomeSchema, reconcileDataSchema, reduceThreadEvents, reduceThreadFrame, reduceThreadState, startedDraftCardSchema, startedDraftSchema, textOf, threadClientMessageSchema, threadSenderSchema, threadViewOf, touchKindSchema, touchSchema, touchedBatchSchema };
|
package/package.json
CHANGED
package/src/drafts.ts
CHANGED
|
@@ -31,25 +31,10 @@ export const PUBLISHING_DRAFT_VAR = "CAMOX_PUBLISHING_DRAFT";
|
|
|
31
31
|
*/
|
|
32
32
|
export const DRAFT_CREATE_HEADER = "x-camox-draft-create";
|
|
33
33
|
|
|
34
|
-
/**
|
|
35
|
-
* The `x-camox-draft` value naming the caller's own development draft in the project a request
|
|
36
|
-
* acts on (ADR 0006, ADR 0011). Dev mode and the CLI always send it.
|
|
37
|
-
*/
|
|
38
|
-
export const DEVELOPMENT_DRAFT = "development";
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* oRPC error code for a request naming the development draft before dev mode created it: the
|
|
42
|
-
* first dev-mode sync after login does, so the site has to run locally once first.
|
|
43
|
-
*/
|
|
44
|
-
export const NO_DEVELOPMENT_DRAFT_ERROR = "NO_DEVELOPMENT_DRAFT";
|
|
45
|
-
|
|
46
34
|
/** URL search param carrying the current draft's id in the studio and the rendered site. */
|
|
47
35
|
export const DRAFT_SEARCH_PARAM = "camox-draft";
|
|
48
36
|
|
|
49
|
-
/**
|
|
50
|
-
export type DraftKind = "regular" | "development";
|
|
51
|
-
|
|
52
|
-
/** How a regular draft ended. */
|
|
37
|
+
/** How a draft ended. */
|
|
53
38
|
export type DraftOutcome = "published" | "deleted";
|
|
54
39
|
|
|
55
40
|
/** Who ended a draft, how and when, from its ended-drafts record (ADR 0009, ADR 0011). */
|
|
@@ -140,7 +125,7 @@ export const LIVE_READ_ONLY_ERROR = "LIVE_READ_ONLY";
|
|
|
140
125
|
// for one on Live. Every procedure is listed, so a new one fails the type check until it's
|
|
141
126
|
// classified and can't be forgotten. Procedures that only fill a generated value (ADR 0012),
|
|
142
127
|
// like `generateSummary`, write no content. A synced block's shared content is written through
|
|
143
|
-
// `blocks` and `repeatableItems`. Releases
|
|
128
|
+
// `blocks` and `repeatableItems`. Releases aren't listed.
|
|
144
129
|
const BLOCK_WRITES: Record<keyof Router["blocks"], boolean> = {
|
|
145
130
|
get: false,
|
|
146
131
|
getPageMarkdown: false,
|
|
@@ -223,7 +208,7 @@ const LOCALE_WRITES: Record<keyof Router["locales"], boolean> = {
|
|
|
223
208
|
addBack: true,
|
|
224
209
|
};
|
|
225
210
|
|
|
226
|
-
// `definitions` is absent: its sync is a release
|
|
211
|
+
// `definitions` is absent: its sync is a release, never a studio content write.
|
|
227
212
|
const CONTENT_WRITES: Partial<Record<keyof Router, Record<string, boolean>>> = {
|
|
228
213
|
blocks: BLOCK_WRITES,
|
|
229
214
|
locales: LOCALE_WRITES,
|
package/src/projects.ts
CHANGED
|
@@ -42,8 +42,12 @@ export const projectSlugSchema = /* @__PURE__ */ z
|
|
|
42
42
|
"Use lowercase letters, digits and hyphens, without a hyphen at either end",
|
|
43
43
|
);
|
|
44
44
|
|
|
45
|
-
/**
|
|
46
|
-
|
|
45
|
+
/**
|
|
46
|
+
* The address a project's website is served at: its Custom Domain when it has one, else its
|
|
47
|
+
* Project Slug's `camox.site` subdomain, which then redirects to it (ADR 0028).
|
|
48
|
+
*/
|
|
49
|
+
export const projectWebsiteUrl = (project: { slug: string; customDomain: string | null }) =>
|
|
50
|
+
`https://${project.customDomain ?? `${project.slug}.camox.site`}`;
|
|
47
51
|
|
|
48
52
|
/** Why a slug can't be given to a new project. */
|
|
49
53
|
export type UnavailableSlugReason = "invalid" | "reserved" | "taken";
|
package/src/threads.ts
CHANGED
|
@@ -45,6 +45,17 @@ export const BRIEF_ENTRY = "camox.brief";
|
|
|
45
45
|
*/
|
|
46
46
|
export const DRAFT_ENDED_ENTRY = "camox.draft-ended";
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* The kind of the transcript entry recording a member's push to the draft's code from their own
|
|
50
|
+
* checkout (ADR 0026), with a `pushDataSchema` as data. The model reads it as context, never
|
|
51
|
+
* answering it, and editors see who pushed, their commits, and whether they built.
|
|
52
|
+
*/
|
|
53
|
+
export const PUSH_ENTRY = "camox.push";
|
|
54
|
+
|
|
55
|
+
/** How a pushed head's build ended: built, built with type errors, or built but not previewed. */
|
|
56
|
+
export const pushOutcomeSchema = z.enum(["built", "typeErrors", "notPreviewed"]);
|
|
57
|
+
export type PushOutcome = z.infer<typeof pushOutcomeSchema>;
|
|
58
|
+
|
|
48
59
|
/**
|
|
49
60
|
* The agent's tool on Live handing a request off to a draft it starts (ADR 0025). A run whose
|
|
50
61
|
* call of it went through ends on the draft's card.
|
|
@@ -85,6 +96,14 @@ export type ThreadSender = z.infer<typeof threadSenderSchema>;
|
|
|
85
96
|
export const isSender = (data: unknown): data is ThreadSender =>
|
|
86
97
|
threadSenderSchema.safeParse(data).success;
|
|
87
98
|
|
|
99
|
+
/** What a push's entry records: who pushed, their commits' subjects, oldest first, and the build. */
|
|
100
|
+
export const pushDataSchema = z.object({
|
|
101
|
+
pusher: threadSenderSchema,
|
|
102
|
+
subjects: z.array(z.string()),
|
|
103
|
+
outcome: pushOutcomeSchema,
|
|
104
|
+
});
|
|
105
|
+
export type PushData = z.infer<typeof pushDataSchema>;
|
|
106
|
+
|
|
88
107
|
/**
|
|
89
108
|
* What an editor's message entry records: who sent it, the operation id it was sent with, and for
|
|
90
109
|
* a message sent on Live as the agent handed the request off, the draft it went to with it.
|
|
@@ -166,7 +185,13 @@ export type ThreadMessage =
|
|
|
166
185
|
* the draft's card, with its current name, which opens it. Once the draft ended, it has its
|
|
167
186
|
* last name and how it ended, and opens nothing. The turn is finished.
|
|
168
187
|
*/
|
|
169
|
-
| ({ id: string; from: "draft"; ended?: DraftOutcome } & StartedDraftCard)
|
|
188
|
+
| ({ id: string; from: "draft"; ended?: DraftOutcome } & StartedDraftCard)
|
|
189
|
+
/**
|
|
190
|
+
* A member's push to the draft's code from their own checkout: who pushed, their commits'
|
|
191
|
+
* subjects, oldest first, and how the pushed head built. It's no turn: the agent doesn't
|
|
192
|
+
* answer it.
|
|
193
|
+
*/
|
|
194
|
+
| { id: string; from: "push"; sender: ThreadSender; subjects: string[]; outcome: PushOutcome };
|
|
170
195
|
|
|
171
196
|
/** Everything the studio shows for a thread. */
|
|
172
197
|
export type ThreadView = {
|
|
@@ -226,6 +251,8 @@ type ThreadStep = { id: string } & (
|
|
|
226
251
|
| ({ type: "draft" } & StartedDraftCard)
|
|
227
252
|
/** Where the build of the turn's code stands, as the turn ends. */
|
|
228
253
|
| { type: "build"; status: BuildStatus }
|
|
254
|
+
/** A member's push, between turns. */
|
|
255
|
+
| ({ type: "push" } & PushData)
|
|
229
256
|
/**
|
|
230
257
|
* The end of the turn sent the agent back to work, after its answer: the answer wasn't the
|
|
231
258
|
* turn's last, and what the agent was told is never shown.
|
|
@@ -275,8 +302,7 @@ export type ThreadServerMessage =
|
|
|
275
302
|
|
|
276
303
|
/**
|
|
277
304
|
* The code a thread closes its sockets with once it ended with its draft, and for good: it's
|
|
278
|
-
* deleted, so reconnecting reaches nothing.
|
|
279
|
-
* thread the next time the studio connects.
|
|
305
|
+
* deleted, so reconnecting reaches nothing.
|
|
280
306
|
*/
|
|
281
307
|
export const THREAD_ENDED_CLOSE_CODE = 4000;
|
|
282
308
|
|
|
@@ -315,6 +341,10 @@ function threadStepOf(entry: EntryRecord): ThreadStep | undefined {
|
|
|
315
341
|
}
|
|
316
342
|
// Only the model reads it: as a user message, it would otherwise read as Pi continuing a run.
|
|
317
343
|
if (entry.kind === DRAFT_ENDED_ENTRY) return undefined;
|
|
344
|
+
if (entry.kind === PUSH_ENTRY) {
|
|
345
|
+
const push = pushDataSchema.safeParse(entry.data).data;
|
|
346
|
+
return push && { id, type: "push", ...push };
|
|
347
|
+
}
|
|
318
348
|
const message = entry.model?.find((candidate) => candidate.role !== "system");
|
|
319
349
|
if (!message) return undefined;
|
|
320
350
|
if (message.role === "user") {
|
|
@@ -462,6 +492,16 @@ export function threadViewOf({
|
|
|
462
492
|
case "build":
|
|
463
493
|
status = step.status;
|
|
464
494
|
break;
|
|
495
|
+
case "push":
|
|
496
|
+
// Pushes land between turns: one doesn't end a turn, nor start one.
|
|
497
|
+
messages.push({
|
|
498
|
+
id: step.id,
|
|
499
|
+
from: "push",
|
|
500
|
+
sender: step.pusher,
|
|
501
|
+
subjects: step.subjects,
|
|
502
|
+
outcome: step.outcome,
|
|
503
|
+
});
|
|
504
|
+
break;
|
|
465
505
|
case "tools":
|
|
466
506
|
unfinished = false;
|
|
467
507
|
break;
|