@ccmsg/protocol 1.20.0 → 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/README.md +2 -2
- package/package.json +1 -1
- package/src/attributes.ts +77 -52
- package/src/common/auth.ts +28 -28
- package/src/common/hello.ts +72 -34
- package/src/common/ping.ts +2 -2
- package/src/common/shutdown.ts +4 -4
- package/src/common/topics.ts +24 -19
- package/src/control/dump.ts +73 -66
- package/src/control/files.ts +24 -24
- package/src/control/kv.ts +6 -6
- package/src/control/launcher.ts +4 -4
- package/src/control/llm.ts +8 -8
- package/src/control/sandbox.ts +4 -4
- package/src/control/session-errors.ts +3 -3
- package/src/control/session-status.ts +2 -2
- package/src/control/session.ts +36 -35
- package/src/control/transcript.ts +6 -6
- package/src/control/translate.ts +2 -2
- package/src/envelope.ts +2 -2
- package/src/errors.ts +1 -1
- package/src/fixtures/common.ts +45 -32
- package/src/fixtures/control.ts +67 -67
- package/src/fixtures/index.ts +77 -63
- package/src/fixtures/messaging.ts +9 -9
- package/src/fixtures/topics.ts +9 -9
- package/src/identifiers.ts +8 -6
- package/src/messaging/message.ts +3 -3
- package/src/messaging/notify.ts +3 -3
- package/src/messaging/say.ts +9 -9
- package/src/schemas.ts +79 -67
- package/src/session-meta.ts +2 -1
package/src/control/files.ts
CHANGED
|
@@ -70,8 +70,8 @@ export const DirListResult = Type.Object({
|
|
|
70
70
|
});
|
|
71
71
|
export type DirListResult = Static<typeof DirListResult>;
|
|
72
72
|
|
|
73
|
-
export const DirListRequest = request("
|
|
74
|
-
export const DirListResponse = response("
|
|
73
|
+
export const DirListRequest = request("dir.list", DirListArgs);
|
|
74
|
+
export const DirListResponse = response("dir.list", DirListResult);
|
|
75
75
|
|
|
76
76
|
export const FileReadArgs = Type.Object({
|
|
77
77
|
sid: Sid,
|
|
@@ -97,14 +97,14 @@ export const FileReadResult = Type.Object({
|
|
|
97
97
|
});
|
|
98
98
|
export type FileReadResult = Static<typeof FileReadResult>;
|
|
99
99
|
|
|
100
|
-
export const FileReadRequest = request("
|
|
101
|
-
export const FileReadResponse = response("
|
|
100
|
+
export const FileReadRequest = request("file.read", FileReadArgs);
|
|
101
|
+
export const FileReadResponse = response("file.read", FileReadResult);
|
|
102
102
|
|
|
103
103
|
/** Writes a new file into the session's inbox directory.
|
|
104
104
|
*
|
|
105
105
|
* The one place a client may put a file without the user having opened it
|
|
106
106
|
* first, which is why it takes no `kind`: the destination is fixed and only the
|
|
107
|
-
* name within it is the caller's. `
|
|
107
|
+
* name within it is the caller's. `file.create` is the general form. */
|
|
108
108
|
export const FileWriteArgs = Type.Object({
|
|
109
109
|
sid: Sid,
|
|
110
110
|
/** Relative to the session's working directory. */
|
|
@@ -119,12 +119,12 @@ export const FileWriteResult = Type.Object({
|
|
|
119
119
|
});
|
|
120
120
|
export type FileWriteResult = Static<typeof FileWriteResult>;
|
|
121
121
|
|
|
122
|
-
export const FileWriteRequest = request("
|
|
123
|
-
export const FileWriteResponse = response("
|
|
122
|
+
export const FileWriteRequest = request("file.write", FileWriteArgs);
|
|
123
|
+
export const FileWriteResponse = response("file.write", FileWriteResult);
|
|
124
124
|
|
|
125
125
|
/** Creates a file that does not exist yet.
|
|
126
126
|
*
|
|
127
|
-
* The symmetric partner of `
|
|
127
|
+
* The symmetric partner of `file.edit`: create versus overwrite. It never
|
|
128
128
|
* replaces an existing path, and it does not make parent directories. There is
|
|
129
129
|
* no `external` kind — that allowlist names single files, so it holds no
|
|
130
130
|
* directory to create in. */
|
|
@@ -143,8 +143,8 @@ export const FileCreateResult = Type.Object({
|
|
|
143
143
|
});
|
|
144
144
|
export type FileCreateResult = Static<typeof FileCreateResult>;
|
|
145
145
|
|
|
146
|
-
export const FileCreateRequest = request("
|
|
147
|
-
export const FileCreateResponse = response("
|
|
146
|
+
export const FileCreateRequest = request("file.create", FileCreateArgs);
|
|
147
|
+
export const FileCreateResponse = response("file.create", FileCreateResult);
|
|
148
148
|
|
|
149
149
|
/** Overwrites an existing text file in place.
|
|
150
150
|
*
|
|
@@ -175,8 +175,8 @@ export const FileEditResult = Type.Object({
|
|
|
175
175
|
});
|
|
176
176
|
export type FileEditResult = Static<typeof FileEditResult>;
|
|
177
177
|
|
|
178
|
-
export const FileEditRequest = request("
|
|
179
|
-
export const FileEditResponse = response("
|
|
178
|
+
export const FileEditRequest = request("file.edit", FileEditArgs);
|
|
179
|
+
export const FileEditResponse = response("file.edit", FileEditResult);
|
|
180
180
|
|
|
181
181
|
/** Deletes one regular file. Never a directory, never a symlink, never
|
|
182
182
|
* recursive: this only unlinks files a person could see as a leaf. `external`
|
|
@@ -195,8 +195,8 @@ export const FileDeleteResult = Type.Object({
|
|
|
195
195
|
});
|
|
196
196
|
export type FileDeleteResult = Static<typeof FileDeleteResult>;
|
|
197
197
|
|
|
198
|
-
export const FileDeleteRequest = request("
|
|
199
|
-
export const FileDeleteResponse = response("
|
|
198
|
+
export const FileDeleteRequest = request("file.delete", FileDeleteArgs);
|
|
199
|
+
export const FileDeleteResponse = response("file.delete", FileDeleteResult);
|
|
200
200
|
|
|
201
201
|
/** Searches for files by name under one browsable root.
|
|
202
202
|
*
|
|
@@ -241,20 +241,20 @@ export const FileFindResult = Type.Object({
|
|
|
241
241
|
});
|
|
242
242
|
export type FileFindResult = Static<typeof FileFindResult>;
|
|
243
243
|
|
|
244
|
-
export const FileFindRequest = request("
|
|
245
|
-
export const FileFindResponse = response("
|
|
244
|
+
export const FileFindRequest = request("file.find", FileFindArgs);
|
|
245
|
+
export const FileFindResponse = response("file.find", FileFindResult);
|
|
246
246
|
|
|
247
247
|
/** Asks which of a batch of paths the instance is willing to serve as files.
|
|
248
248
|
*
|
|
249
249
|
* A client that has found path-shaped text in a message uses this to decide
|
|
250
250
|
* which of them to turn into links. Each path is tried against the three
|
|
251
251
|
* surfaces in turn and the first that admits it and finds a regular file wins. */
|
|
252
|
-
export const
|
|
252
|
+
export const FileStatArgs = Type.Object({
|
|
253
253
|
sid: Sid,
|
|
254
254
|
/** Absolute paths, resolved by the caller. */
|
|
255
255
|
paths: Type.Array(Type.String()),
|
|
256
256
|
});
|
|
257
|
-
export type
|
|
257
|
+
export type FileStatArgs = Static<typeof FileStatArgs>;
|
|
258
258
|
|
|
259
259
|
export const FileStatEntry = Type.Object(
|
|
260
260
|
{
|
|
@@ -266,7 +266,7 @@ export const FileStatEntry = Type.Object(
|
|
|
266
266
|
);
|
|
267
267
|
export type FileStatEntry = Static<typeof FileStatEntry>;
|
|
268
268
|
|
|
269
|
-
export const
|
|
269
|
+
export const FileStatResult = Type.Object({
|
|
270
270
|
/** One slot per requested path, in the same order.
|
|
271
271
|
*
|
|
272
272
|
* Design rationale: an unresolved path is `null` rather than being left out,
|
|
@@ -278,10 +278,10 @@ export const FileStatBatchResult = Type.Object({
|
|
|
278
278
|
* path the caller may not read exists. */
|
|
279
279
|
results: Type.Array(Type.Union([FileStatEntry, Type.Null()])),
|
|
280
280
|
});
|
|
281
|
-
export type
|
|
281
|
+
export type FileStatResult = Static<typeof FileStatResult>;
|
|
282
282
|
|
|
283
|
-
export const
|
|
284
|
-
export const
|
|
283
|
+
export const FileStatRequest = request("file.stat", FileStatArgs);
|
|
284
|
+
export const FileStatResponse = response("file.stat", FileStatResult);
|
|
285
285
|
|
|
286
286
|
/** Reads the directory tree the launcher may start a session in.
|
|
287
287
|
*
|
|
@@ -319,5 +319,5 @@ export const DirTreeResult = Type.Object({
|
|
|
319
319
|
});
|
|
320
320
|
export type DirTreeResult = Static<typeof DirTreeResult>;
|
|
321
321
|
|
|
322
|
-
export const DirTreeRequest = request("
|
|
323
|
-
export const DirTreeResponse = response("
|
|
322
|
+
export const DirTreeRequest = request("dir.tree", DirTreeArgs);
|
|
323
|
+
export const DirTreeResponse = response("dir.tree", DirTreeResult);
|
package/src/control/kv.ts
CHANGED
|
@@ -45,8 +45,8 @@ export const KvReadResult = Type.Object({
|
|
|
45
45
|
});
|
|
46
46
|
export type KvReadResult = Static<typeof KvReadResult>;
|
|
47
47
|
|
|
48
|
-
export const KvReadRequest = request("
|
|
49
|
-
export const KvReadResponse = response("
|
|
48
|
+
export const KvReadRequest = request("kv.read", KvReadArgs);
|
|
49
|
+
export const KvReadResponse = response("kv.read", KvReadResult);
|
|
50
50
|
|
|
51
51
|
/** Writes one value, replacing whatever the key held. */
|
|
52
52
|
export const KvWriteArgs = Type.Object({
|
|
@@ -68,8 +68,8 @@ export const KvWriteResult = Type.Object({
|
|
|
68
68
|
});
|
|
69
69
|
export type KvWriteResult = Static<typeof KvWriteResult>;
|
|
70
70
|
|
|
71
|
-
export const KvWriteRequest = request("
|
|
72
|
-
export const KvWriteResponse = response("
|
|
71
|
+
export const KvWriteRequest = request("kv.write", KvWriteArgs);
|
|
72
|
+
export const KvWriteResponse = response("kv.write", KvWriteResult);
|
|
73
73
|
|
|
74
74
|
/** Removes one key. A key that was not there is no error: the caller wanted the
|
|
75
75
|
* namespace to be without it, and it is. */
|
|
@@ -79,8 +79,8 @@ export type KvDeleteArgs = Static<typeof KvDeleteArgs>;
|
|
|
79
79
|
export const KvDeleteResult = Type.Object({});
|
|
80
80
|
export type KvDeleteResult = Static<typeof KvDeleteResult>;
|
|
81
81
|
|
|
82
|
-
export const KvDeleteRequest = request("
|
|
83
|
-
export const KvDeleteResponse = response("
|
|
82
|
+
export const KvDeleteRequest = request("kv.delete", KvDeleteArgs);
|
|
83
|
+
export const KvDeleteResponse = response("kv.delete", KvDeleteResult);
|
|
84
84
|
|
|
85
85
|
/** One entry, in a snapshot or in the change that produced it. */
|
|
86
86
|
export const KvEntry = Type.Object(
|
package/src/control/launcher.ts
CHANGED
|
@@ -53,9 +53,9 @@ export const LauncherConfigReadResult = Type.Object({
|
|
|
53
53
|
});
|
|
54
54
|
export type LauncherConfigReadResult = Static<typeof LauncherConfigReadResult>;
|
|
55
55
|
|
|
56
|
-
export const LauncherConfigReadRequest = request("
|
|
56
|
+
export const LauncherConfigReadRequest = request("launcher.config.read", LauncherConfigReadArgs);
|
|
57
57
|
export const LauncherConfigReadResponse = response(
|
|
58
|
-
"
|
|
58
|
+
"launcher.config.read",
|
|
59
59
|
LauncherConfigReadResult,
|
|
60
60
|
);
|
|
61
61
|
|
|
@@ -96,5 +96,5 @@ export const LauncherRunResult = Type.Object({
|
|
|
96
96
|
});
|
|
97
97
|
export type LauncherRunResult = Static<typeof LauncherRunResult>;
|
|
98
98
|
|
|
99
|
-
export const LauncherRunRequest = request("
|
|
100
|
-
export const LauncherRunResponse = response("
|
|
99
|
+
export const LauncherRunRequest = request("launcher.run", LauncherRunArgs);
|
|
100
|
+
export const LauncherRunResponse = response("launcher.run", LauncherRunResult);
|
package/src/control/llm.ts
CHANGED
|
@@ -159,8 +159,8 @@ export const LlmUsageReadResult = Type.Object({
|
|
|
159
159
|
});
|
|
160
160
|
export type LlmUsageReadResult = Static<typeof LlmUsageReadResult>;
|
|
161
161
|
|
|
162
|
-
export const LlmUsageReadRequest = request("
|
|
163
|
-
export const LlmUsageReadResponse = response("
|
|
162
|
+
export const LlmUsageReadRequest = request("llm.usage.read", LlmUsageReadArgs);
|
|
163
|
+
export const LlmUsageReadResponse = response("llm.usage.read", LlmUsageReadResult);
|
|
164
164
|
|
|
165
165
|
// ---------------------------------------------------------------------------
|
|
166
166
|
// spend
|
|
@@ -214,8 +214,8 @@ export const LlmStatsReadResult = Type.Object({
|
|
|
214
214
|
});
|
|
215
215
|
export type LlmStatsReadResult = Static<typeof LlmStatsReadResult>;
|
|
216
216
|
|
|
217
|
-
export const LlmStatsReadRequest = request("
|
|
218
|
-
export const LlmStatsReadResponse = response("
|
|
217
|
+
export const LlmStatsReadRequest = request("llm.stats.read", LlmStatsReadArgs);
|
|
218
|
+
export const LlmStatsReadResponse = response("llm.stats.read", LlmStatsReadResult);
|
|
219
219
|
|
|
220
220
|
// ---------------------------------------------------------------------------
|
|
221
221
|
// live requests
|
|
@@ -328,12 +328,12 @@ export function llmCacheWindowEndAt(info: {
|
|
|
328
328
|
return info.received_at + LLM_PROMPT_CACHE_TTL_MS;
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
-
/** The `
|
|
331
|
+
/** The `llm.requests` topic: the newest request per conversation series, always
|
|
332
332
|
* the whole unexpired set rather than the one that just arrived. A client that
|
|
333
333
|
* starts listening mid-window still needs the countdown that began before it
|
|
334
334
|
* was there, and one shape serves both that and the live update. An empty set
|
|
335
335
|
* is a legitimate "no session has a warm cache". */
|
|
336
|
-
export const LlmRequestsFrame = topicFrame("
|
|
336
|
+
export const LlmRequestsFrame = topicFrame("llm.requests", Type.Array(LlmRequestInfo));
|
|
337
337
|
|
|
338
338
|
// ---------------------------------------------------------------------------
|
|
339
339
|
// upstream health
|
|
@@ -503,5 +503,5 @@ export const LlmStatusReport = Type.Object(
|
|
|
503
503
|
);
|
|
504
504
|
export type LlmStatusReport = Static<typeof LlmStatusReport>;
|
|
505
505
|
|
|
506
|
-
/** The `
|
|
507
|
-
export const LlmStatusFrame = topicFrame("
|
|
506
|
+
/** The `llm.status` topic. Whole-value: each frame replaces the last. */
|
|
507
|
+
export const LlmStatusFrame = topicFrame("llm.status", LlmStatusReport);
|
package/src/control/sandbox.ts
CHANGED
|
@@ -37,8 +37,8 @@ export const SandboxGrantResult = Type.Object({
|
|
|
37
37
|
});
|
|
38
38
|
export type SandboxGrantResult = Static<typeof SandboxGrantResult>;
|
|
39
39
|
|
|
40
|
-
export const SandboxGrantRequest = request("
|
|
41
|
-
export const SandboxGrantResponse = response("
|
|
40
|
+
export const SandboxGrantRequest = request("sandbox.grant", SandboxGrantArgs);
|
|
41
|
+
export const SandboxGrantResponse = response("sandbox.grant", SandboxGrantResult);
|
|
42
42
|
|
|
43
43
|
/** Ends a grant early, as when a preview is closed.
|
|
44
44
|
*
|
|
@@ -54,5 +54,5 @@ export type SandboxRevokeArgs = Static<typeof SandboxRevokeArgs>;
|
|
|
54
54
|
export const SandboxRevokeResult = Type.Object({});
|
|
55
55
|
export type SandboxRevokeResult = Static<typeof SandboxRevokeResult>;
|
|
56
56
|
|
|
57
|
-
export const SandboxRevokeRequest = request("
|
|
58
|
-
export const SandboxRevokeResponse = response("
|
|
57
|
+
export const SandboxRevokeRequest = request("sandbox.revoke", SandboxRevokeArgs);
|
|
58
|
+
export const SandboxRevokeResponse = response("sandbox.revoke", SandboxRevokeResult);
|
|
@@ -10,10 +10,10 @@ export const SessionErrorEntry = Type.Intersect(
|
|
|
10
10
|
);
|
|
11
11
|
export type SessionErrorEntry = Static<typeof SessionErrorEntry>;
|
|
12
12
|
|
|
13
|
-
/** The `
|
|
13
|
+
/** The `session.errors` topic: every connected session currently stopped on a
|
|
14
14
|
* harness error.
|
|
15
15
|
*
|
|
16
|
-
* Not per session, unlike `
|
|
16
|
+
* Not per session, unlike `session.status`. A client showing a list of sessions
|
|
17
17
|
* has to mark the stopped ones, and subscribing to a whole status fold for each
|
|
18
18
|
* visible session is the cost this exists to avoid: the instance folds the one
|
|
19
19
|
* error pattern over every connected session instead.
|
|
@@ -22,6 +22,6 @@ export type SessionErrorEntry = Static<typeof SessionErrorEntry>;
|
|
|
22
22
|
* rather than appearing with an empty error, so a client that missed a frame
|
|
23
23
|
* still converges on the next one. */
|
|
24
24
|
export const SessionErrorsFrame = topicFrame(
|
|
25
|
-
"
|
|
25
|
+
"session.errors",
|
|
26
26
|
Type.Object({ errors: Type.Array(SessionErrorEntry) }),
|
|
27
27
|
);
|
|
@@ -303,9 +303,9 @@ export const SessionStatusSnapshot = Type.Object(
|
|
|
303
303
|
);
|
|
304
304
|
export type SessionStatusSnapshot = Static<typeof SessionStatusSnapshot>;
|
|
305
305
|
|
|
306
|
-
/** The `
|
|
306
|
+
/** The `session.status:<sid>` topic. Whole-value: the fold is recomputed and
|
|
307
307
|
* sent entire whenever something in the transcript changes it. */
|
|
308
308
|
export const SessionStatusFrame = topicFrame(
|
|
309
|
-
"
|
|
309
|
+
"session.status",
|
|
310
310
|
Type.Intersect([Type.Object({ sid: Sid }), SessionStatusSnapshot]),
|
|
311
311
|
);
|
package/src/control/session.ts
CHANGED
|
@@ -25,8 +25,8 @@ export const SessionKillResult = Type.Object({
|
|
|
25
25
|
});
|
|
26
26
|
export type SessionKillResult = Static<typeof SessionKillResult>;
|
|
27
27
|
|
|
28
|
-
export const SessionKillRequest = request("
|
|
29
|
-
export const SessionKillResponse = response("
|
|
28
|
+
export const SessionKillRequest = request("session.kill", SessionKillArgs);
|
|
29
|
+
export const SessionKillResponse = response("session.kill", SessionKillResult);
|
|
30
30
|
|
|
31
31
|
/** How long a title may be. A title is typed into a terminal and shown as a
|
|
32
32
|
* session's first line, where anything longer is unreadable whatever the
|
|
@@ -63,8 +63,8 @@ export const SessionRenameResult = Type.Object({
|
|
|
63
63
|
});
|
|
64
64
|
export type SessionRenameResult = Static<typeof SessionRenameResult>;
|
|
65
65
|
|
|
66
|
-
export const SessionRenameRequest = request("
|
|
67
|
-
export const SessionRenameResponse = response("
|
|
66
|
+
export const SessionRenameRequest = request("session.rename", SessionRenameArgs);
|
|
67
|
+
export const SessionRenameResponse = response("session.rename", SessionRenameResult);
|
|
68
68
|
|
|
69
69
|
/** Reads the environment of a session's own process.
|
|
70
70
|
*
|
|
@@ -84,8 +84,8 @@ export const SessionEnvReadResult = Type.Object({
|
|
|
84
84
|
});
|
|
85
85
|
export type SessionEnvReadResult = Static<typeof SessionEnvReadResult>;
|
|
86
86
|
|
|
87
|
-
export const SessionEnvReadRequest = request("
|
|
88
|
-
export const SessionEnvReadResponse = response("
|
|
87
|
+
export const SessionEnvReadRequest = request("session.env.read", SessionEnvReadArgs);
|
|
88
|
+
export const SessionEnvReadResponse = response("session.env.read", SessionEnvReadResult);
|
|
89
89
|
|
|
90
90
|
/** Searches the transcripts of sessions that have run on this instance,
|
|
91
91
|
* including ones long finished. */
|
|
@@ -162,8 +162,8 @@ export const SessionSearchResult = Type.Object({
|
|
|
162
162
|
});
|
|
163
163
|
export type SessionSearchResult = Static<typeof SessionSearchResult>;
|
|
164
164
|
|
|
165
|
-
export const SessionSearchRequest = request("
|
|
166
|
-
export const SessionSearchResponse = response("
|
|
165
|
+
export const SessionSearchRequest = request("session.search", SessionSearchArgs);
|
|
166
|
+
export const SessionSearchResponse = response("session.search", SessionSearchResult);
|
|
167
167
|
|
|
168
168
|
/** Writes a session's dump to a file on the instance's host and answers with
|
|
169
169
|
* its path.
|
|
@@ -201,7 +201,7 @@ export const SessionDumpWriteArgs = Type.Object({
|
|
|
201
201
|
* thing in the vocabulary the rest of the selection is written in. */
|
|
202
202
|
no_thinking: Type.Optional(Type.Boolean()),
|
|
203
203
|
/** Leave out the machinery of in-process agents, which
|
|
204
|
-
* `["-message
|
|
204
|
+
* `["-message.sub", "-tool.Agent"]` also says. */
|
|
205
205
|
no_agent: Type.Optional(Type.Boolean()),
|
|
206
206
|
});
|
|
207
207
|
export type SessionDumpWriteArgs = Static<typeof SessionDumpWriteArgs>;
|
|
@@ -221,16 +221,16 @@ export const SessionDumpWriteResult = Type.Object({
|
|
|
221
221
|
});
|
|
222
222
|
export type SessionDumpWriteResult = Static<typeof SessionDumpWriteResult>;
|
|
223
223
|
|
|
224
|
-
export const SessionDumpWriteRequest = request("
|
|
225
|
-
export const SessionDumpWriteResponse = response("
|
|
224
|
+
export const SessionDumpWriteRequest = request("session.dump.write", SessionDumpWriteArgs);
|
|
225
|
+
export const SessionDumpWriteResponse = response("session.dump.write", SessionDumpWriteResult);
|
|
226
226
|
|
|
227
227
|
/** Asks where a forked session stopped being a copy of its ancestor.
|
|
228
228
|
*
|
|
229
229
|
* Forking duplicates the ancestor's records keeping each record id, so nothing
|
|
230
230
|
* inside the file marks the seam; finding it means comparing against the
|
|
231
231
|
* sibling transcripts the instance can already enumerate. */
|
|
232
|
-
export const
|
|
233
|
-
export type
|
|
232
|
+
export const SessionForkOriginReadArgs = Type.Object({ sid: Sid });
|
|
233
|
+
export type SessionForkOriginReadArgs = Static<typeof SessionForkOriginReadArgs>;
|
|
234
234
|
|
|
235
235
|
export const ForkOrigin = Type.Object(
|
|
236
236
|
{
|
|
@@ -245,38 +245,39 @@ export const ForkOrigin = Type.Object(
|
|
|
245
245
|
);
|
|
246
246
|
export type ForkOrigin = Static<typeof ForkOrigin>;
|
|
247
247
|
|
|
248
|
-
export const
|
|
248
|
+
export const SessionForkOriginReadResult = Type.Object({
|
|
249
249
|
/** Absent both when the session is no fork and when it is one whose ancestor
|
|
250
250
|
* file is gone. Nothing left on disk tells those two apart, and neither has a
|
|
251
251
|
* seam to place. */
|
|
252
252
|
origin: Type.Optional(ForkOrigin),
|
|
253
253
|
});
|
|
254
|
-
export type
|
|
254
|
+
export type SessionForkOriginReadResult = Static<typeof SessionForkOriginReadResult>;
|
|
255
255
|
|
|
256
|
-
export const
|
|
257
|
-
|
|
256
|
+
export const SessionForkOriginReadRequest = request(
|
|
257
|
+
"session.fork.origin.read",
|
|
258
|
+
SessionForkOriginReadArgs,
|
|
259
|
+
);
|
|
260
|
+
export const SessionForkOriginReadResponse = response(
|
|
261
|
+
"session.fork.origin.read",
|
|
262
|
+
SessionForkOriginReadResult,
|
|
263
|
+
);
|
|
258
264
|
|
|
259
|
-
/**
|
|
260
|
-
*
|
|
265
|
+
/** A person dropping one session an instance still holds a row for, which is
|
|
266
|
+
* the other way a row reaches `peers` as a `PeerRemoved` — the one that does
|
|
267
|
+
* not wait for the retention window.
|
|
261
268
|
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
export const
|
|
267
|
-
export type
|
|
269
|
+
* Forgetting touches the row alone: the session stays resumable by every other
|
|
270
|
+
* route, and an instance that later sees it connected records it again. An
|
|
271
|
+
* unknown session is not an error — two clients pressing the same button is the
|
|
272
|
+
* ordinary case, and the caller's goal holds either way. */
|
|
273
|
+
export const SessionForgetArgs = Type.Object({ sid: Sid });
|
|
274
|
+
export type SessionForgetArgs = Static<typeof SessionForgetArgs>;
|
|
268
275
|
|
|
269
|
-
export const
|
|
276
|
+
export const SessionForgetResult = Type.Object({
|
|
270
277
|
/** Whether the entry was there to remove. */
|
|
271
278
|
removed: Type.Boolean(),
|
|
272
279
|
});
|
|
273
|
-
export type
|
|
280
|
+
export type SessionForgetResult = Static<typeof SessionForgetResult>;
|
|
274
281
|
|
|
275
|
-
export const
|
|
276
|
-
|
|
277
|
-
SessionLastLiveRemoveArgs,
|
|
278
|
-
);
|
|
279
|
-
export const SessionLastLiveRemoveResponse = response(
|
|
280
|
-
"session_last_live_remove",
|
|
281
|
-
SessionLastLiveRemoveResult,
|
|
282
|
-
);
|
|
282
|
+
export const SessionForgetRequest = request("session.forget", SessionForgetArgs);
|
|
283
|
+
export const SessionForgetResponse = response("session.forget", SessionForgetResult);
|
|
@@ -48,8 +48,8 @@ export const TranscriptReadResult = Type.Object({
|
|
|
48
48
|
});
|
|
49
49
|
export type TranscriptReadResult = Static<typeof TranscriptReadResult>;
|
|
50
50
|
|
|
51
|
-
export const TranscriptReadRequest = request("
|
|
52
|
-
export const TranscriptReadResponse = response("
|
|
51
|
+
export const TranscriptReadRequest = request("transcript.read", TranscriptReadArgs);
|
|
52
|
+
export const TranscriptReadResponse = response("transcript.read", TranscriptReadResult);
|
|
53
53
|
|
|
54
54
|
/** Reads a slice of a transcript as the items it was read into.
|
|
55
55
|
*
|
|
@@ -115,13 +115,13 @@ export const TranscriptItemsReadResult = Type.Object({
|
|
|
115
115
|
});
|
|
116
116
|
export type TranscriptItemsReadResult = Static<typeof TranscriptItemsReadResult>;
|
|
117
117
|
|
|
118
|
-
export const TranscriptItemsReadRequest = request("
|
|
118
|
+
export const TranscriptItemsReadRequest = request("transcript.items.read", TranscriptItemsReadArgs);
|
|
119
119
|
export const TranscriptItemsReadResponse = response(
|
|
120
|
-
"
|
|
120
|
+
"transcript.items.read",
|
|
121
121
|
TranscriptItemsReadResult,
|
|
122
122
|
);
|
|
123
123
|
|
|
124
|
-
/** The `
|
|
124
|
+
/** The `transcript.items:<sid>` topic.
|
|
125
125
|
*
|
|
126
126
|
* What `transcript:<sid>` carries as appended bytes, carried as the items those
|
|
127
127
|
* bytes were read as. A subscriber holds a list it only ever appends to, so the
|
|
@@ -133,7 +133,7 @@ export const TranscriptItemsReadResponse = response(
|
|
|
133
133
|
* A record still being written is not classified until its line ends, which is
|
|
134
134
|
* the same rule the raw topic sends whole lines under. */
|
|
135
135
|
export const TranscriptItemsFrame = topicFrame(
|
|
136
|
-
"
|
|
136
|
+
"transcript.items",
|
|
137
137
|
Type.Object({
|
|
138
138
|
sid: Sid,
|
|
139
139
|
items: Type.Array(TranscriptItem),
|
package/src/control/translate.ts
CHANGED
|
@@ -29,5 +29,5 @@ export const TranslateRunResult = Type.Object({
|
|
|
29
29
|
});
|
|
30
30
|
export type TranslateRunResult = Static<typeof TranslateRunResult>;
|
|
31
31
|
|
|
32
|
-
export const TranslateRunRequest = request("
|
|
33
|
-
export const TranslateRunResponse = response("
|
|
32
|
+
export const TranslateRunRequest = request("translate.run", TranslateRunArgs);
|
|
33
|
+
export const TranslateRunResponse = response("translate.run", TranslateRunResult);
|
package/src/envelope.ts
CHANGED
|
@@ -24,7 +24,7 @@ export const MAX_FRAME_BYTES = 1_048_576;
|
|
|
24
24
|
export const CallerIdentity = Type.Object(
|
|
25
25
|
{
|
|
26
26
|
role: Role,
|
|
27
|
-
/** Present exactly when the role is `session`, as in `hello`. */
|
|
27
|
+
/** Present exactly when the role is `session`, as in `hello.session`. */
|
|
28
28
|
sid: Type.Optional(Sid),
|
|
29
29
|
},
|
|
30
30
|
{ $id: "CallerIdentity" },
|
|
@@ -102,7 +102,7 @@ export type ErrorResponse = Static<typeof ErrorResponse>;
|
|
|
102
102
|
|
|
103
103
|
/** A frame pushed on a topic the connection subscribed to.
|
|
104
104
|
*
|
|
105
|
-
* Snapshot and delta share one shape: the first frame after `
|
|
105
|
+
* Snapshot and delta share one shape: the first frame after `topic.subscribe`
|
|
106
106
|
* carries `snapshot: true` and the whole current value, and later frames carry
|
|
107
107
|
* the same payload type as a change. `instance` names where the frame came
|
|
108
108
|
* from, which is what keeps whole-value topics from several instances out of
|
package/src/errors.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { type Static, Type } from "@sinclair/typebox";
|
|
|
5
5
|
export const ERROR_CODES = [
|
|
6
6
|
// --- connection level (no single op owns these) ---
|
|
7
7
|
/** The request could not be dispatched at all: unparseable JSON, no `op`, no
|
|
8
|
-
* `request_id`, or a
|
|
8
|
+
* `request_id`, or a greeting announcing another protocol generation. */
|
|
9
9
|
"bad_request",
|
|
10
10
|
/** The op name is not in the op attribute table. */
|
|
11
11
|
"unknown_op",
|