borgmcp-shared 0.10.1 → 0.12.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/CONTRIBUTING.md +2 -2
- package/README.md +22 -15
- package/RELEASES.md +14 -0
- package/dist/conformance/adapter.d.ts +3 -0
- package/dist/conformance/adapter.d.ts.map +1 -1
- package/dist/conformance/adapter.js +91 -10
- package/dist/conformance/adapter.js.map +1 -1
- package/dist/conformance/index.d.ts +13 -0
- package/dist/conformance/index.d.ts.map +1 -1
- package/dist/conformance/index.js +83 -14
- package/dist/conformance/index.js.map +1 -1
- package/dist/protocol/contract.d.ts +2 -1
- package/dist/protocol/contract.d.ts.map +1 -1
- package/dist/protocol/contract.js +9 -4
- package/dist/protocol/contract.js.map +1 -1
- package/dist/protocol/coordination.d.ts.map +1 -1
- package/dist/protocol/coordination.js +8 -2
- package/dist/protocol/coordination.js.map +1 -1
- package/dist/protocol/errors.d.ts +1 -0
- package/dist/protocol/errors.d.ts.map +1 -1
- package/dist/protocol/errors.js +1 -0
- package/dist/protocol/errors.js.map +1 -1
- package/dist/protocol/types.d.ts +2 -0
- package/dist/protocol/types.d.ts.map +1 -1
- package/dist/protocol/version.d.ts +1 -1
- package/dist/protocol/version.js +1 -1
- package/dist/templates.d.ts +1 -1
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +178 -53
- package/dist/templates.js.map +1 -1
- package/docs/release-records.json +103 -0
- package/docs/releases/0.12.0.md +7 -0
- package/docs/releasing.md +104 -23
- package/docs/template-lifecycle.md +66 -0
- package/package.json +2 -2
- package/src/conformance/adapter.ts +110 -9
- package/src/conformance/index.ts +101 -15
- package/src/protocol/contract.ts +11 -5
- package/src/protocol/coordination.ts +8 -2
- package/src/protocol/errors.ts +1 -0
- package/src/protocol/types.ts +2 -0
- package/src/protocol/version.ts +2 -2
- package/src/templates.ts +185 -53
package/src/conformance/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
encodeInvitationArtifact,
|
|
12
12
|
type InvitationArtifact,
|
|
13
13
|
} from '../protocol/contract.js';
|
|
14
|
-
import type { EnrichedStreamEntry } from '../protocol/types.js';
|
|
14
|
+
import type { AppendLogRequest, EnrichedStreamEntry } from '../protocol/types.js';
|
|
15
15
|
import { ROLE_IN_USE_DELETE_MESSAGE } from '../protocol/coordination.js';
|
|
16
16
|
|
|
17
17
|
export * from './adapter.js';
|
|
@@ -99,17 +99,53 @@ export interface AppendLogResultConformanceVector {
|
|
|
99
99
|
accepts: boolean;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
export interface AppendLogRequestConformanceVector {
|
|
103
|
+
name: string;
|
|
104
|
+
request: unknown;
|
|
105
|
+
accepts: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface AppendLogIdempotencyConformanceVector {
|
|
109
|
+
name: string;
|
|
110
|
+
actor: 'same' | 'different';
|
|
111
|
+
mutation: 'none' | 'message' | 'visibility' | 'recipient_set' | 'resolved_class_routing';
|
|
112
|
+
expected: 'deduplicated' | 'POST_ID_CONFLICT' | 'created';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Author-scoped post identity and exact resolved-routing retry outcomes. */
|
|
116
|
+
export const APPEND_LOG_IDEMPOTENCY_CONFORMANCE: readonly AppendLogIdempotencyConformanceVector[] = [
|
|
117
|
+
{ name: 'deduplicates an exact same-author retry', actor: 'same', mutation: 'none', expected: 'deduplicated' },
|
|
118
|
+
{ name: 'rejects a same-author message collision', actor: 'same', mutation: 'message', expected: 'POST_ID_CONFLICT' },
|
|
119
|
+
{ name: 'rejects a same-author visibility collision', actor: 'same', mutation: 'visibility', expected: 'POST_ID_CONFLICT' },
|
|
120
|
+
{ name: 'rejects a same-author recipient-set collision', actor: 'same', mutation: 'recipient_set', expected: 'POST_ID_CONFLICT' },
|
|
121
|
+
{ name: 'rejects a same-author resolved class-routing collision', actor: 'same', mutation: 'resolved_class_routing', expected: 'POST_ID_CONFLICT' },
|
|
122
|
+
{ name: 'creates an independent cross-author post', actor: 'different', mutation: 'none', expected: 'created' },
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
const APPEND_LOG_REQUEST = {
|
|
126
|
+
post_id: '00000000-0000-4000-8000-000000000205',
|
|
127
|
+
message: 'REVIEW-READY: example',
|
|
128
|
+
} satisfies AppendLogRequest;
|
|
129
|
+
|
|
130
|
+
export const APPEND_LOG_REQUEST_CONFORMANCE: readonly AppendLogRequestConformanceVector[] = [
|
|
131
|
+
{ name: 'accepts a canonical post UUID', request: APPEND_LOG_REQUEST, accepts: true },
|
|
132
|
+
{ name: 'rejects an omitted post UUID', request: { message: APPEND_LOG_REQUEST.message }, accepts: false },
|
|
133
|
+
{ name: 'rejects an invalid post UUID', request: { ...APPEND_LOG_REQUEST, post_id: 'not-a-uuid' }, accepts: false },
|
|
134
|
+
{ name: 'rejects unknown request fields', request: { ...APPEND_LOG_REQUEST, extra: true }, accepts: false },
|
|
135
|
+
];
|
|
136
|
+
|
|
102
137
|
/** Runtime response vectors keep the append-log decoder aligned with its public type. */
|
|
103
138
|
export const APPEND_LOG_RESULT_CONFORMANCE: readonly AppendLogResultConformanceVector[] = [
|
|
104
139
|
{
|
|
105
140
|
name: 'accepts a response without optional routing metadata',
|
|
106
|
-
response: { entry: APPEND_LOG_ENTRY },
|
|
141
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false },
|
|
107
142
|
accepts: true,
|
|
108
143
|
},
|
|
109
144
|
{
|
|
110
145
|
name: 'accepts exact routing metadata and unreachable recipients',
|
|
111
146
|
response: {
|
|
112
147
|
entry: APPEND_LOG_ENTRY,
|
|
148
|
+
deduplicated: false,
|
|
113
149
|
routing: APPEND_LOG_ROUTING,
|
|
114
150
|
unreachableRecipients: [{ id: 'missing-reviewer', label: 'Missing Reviewer' }],
|
|
115
151
|
},
|
|
@@ -117,73 +153,84 @@ export const APPEND_LOG_RESULT_CONFORMANCE: readonly AppendLogResultConformanceV
|
|
|
117
153
|
},
|
|
118
154
|
{
|
|
119
155
|
name: 'accepts a null routing echo and an empty unreachable-recipient list',
|
|
120
|
-
response: { entry: APPEND_LOG_ENTRY, routing: null, unreachableRecipients: [] },
|
|
156
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: true, routing: null, unreachableRecipients: [] },
|
|
121
157
|
accepts: true,
|
|
122
158
|
},
|
|
159
|
+
{
|
|
160
|
+
name: 'rejects an omitted deduplication result',
|
|
161
|
+
response: { entry: APPEND_LOG_ENTRY },
|
|
162
|
+
accepts: false,
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
name: 'rejects a non-boolean deduplication result',
|
|
166
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: 'false' },
|
|
167
|
+
accepts: false,
|
|
168
|
+
},
|
|
123
169
|
{
|
|
124
170
|
name: 'rejects unknown top-level response fields',
|
|
125
|
-
response: { entry: APPEND_LOG_ENTRY, routing: APPEND_LOG_ROUTING, extra: true },
|
|
171
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, routing: APPEND_LOG_ROUTING, extra: true },
|
|
126
172
|
accepts: false,
|
|
127
173
|
},
|
|
128
174
|
{
|
|
129
175
|
name: 'rejects a non-object routing echo',
|
|
130
|
-
response: { entry: APPEND_LOG_ENTRY, routing: 'review' },
|
|
176
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, routing: 'review' },
|
|
131
177
|
accepts: false,
|
|
132
178
|
},
|
|
133
179
|
{
|
|
134
180
|
name: 'rejects missing routing fields',
|
|
135
|
-
response: { entry: APPEND_LOG_ENTRY, routing: { class: 'review' } },
|
|
181
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, routing: { class: 'review' } },
|
|
136
182
|
accepts: false,
|
|
137
183
|
},
|
|
138
184
|
{
|
|
139
185
|
name: 'rejects unknown routing fields',
|
|
140
|
-
response: { entry: APPEND_LOG_ENTRY, routing: { ...APPEND_LOG_ROUTING, extra: true } },
|
|
186
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, routing: { ...APPEND_LOG_ROUTING, extra: true } },
|
|
141
187
|
accepts: false,
|
|
142
188
|
},
|
|
143
189
|
{
|
|
144
190
|
name: 'rejects an invalid routing class',
|
|
145
|
-
response: { entry: APPEND_LOG_ENTRY, routing: { ...APPEND_LOG_ROUTING, class: 7 } },
|
|
191
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, routing: { ...APPEND_LOG_ROUTING, class: 7 } },
|
|
146
192
|
accepts: false,
|
|
147
193
|
},
|
|
148
194
|
{
|
|
149
195
|
name: 'rejects an invalid routing recipient collection',
|
|
150
|
-
response: { entry: APPEND_LOG_ENTRY, routing: { ...APPEND_LOG_ROUTING, recipients: 'reviewer' } },
|
|
196
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, routing: { ...APPEND_LOG_ROUTING, recipients: 'reviewer' } },
|
|
151
197
|
accepts: false,
|
|
152
198
|
},
|
|
153
199
|
{
|
|
154
200
|
name: 'rejects invalid routing recipient members',
|
|
155
|
-
response: { entry: APPEND_LOG_ENTRY, routing: { ...APPEND_LOG_ROUTING, recipients: [7] } },
|
|
201
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, routing: { ...APPEND_LOG_ROUTING, recipients: [7] } },
|
|
156
202
|
accepts: false,
|
|
157
203
|
},
|
|
158
204
|
{
|
|
159
205
|
name: 'rejects an invalid routing fell-open flag',
|
|
160
|
-
response: { entry: APPEND_LOG_ENTRY, routing: { ...APPEND_LOG_ROUTING, fellOpen: 'false' } },
|
|
206
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, routing: { ...APPEND_LOG_ROUTING, fellOpen: 'false' } },
|
|
161
207
|
accepts: false,
|
|
162
208
|
},
|
|
163
209
|
{
|
|
164
210
|
name: 'rejects an invalid routing message',
|
|
165
|
-
response: { entry: APPEND_LOG_ENTRY, routing: { ...APPEND_LOG_ROUTING, message: 7 } },
|
|
211
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, routing: { ...APPEND_LOG_ROUTING, message: 7 } },
|
|
166
212
|
accepts: false,
|
|
167
213
|
},
|
|
168
214
|
{
|
|
169
215
|
name: 'rejects a non-array unreachable-recipient list',
|
|
170
|
-
response: { entry: APPEND_LOG_ENTRY, unreachableRecipients: {} },
|
|
216
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, unreachableRecipients: {} },
|
|
171
217
|
accepts: false,
|
|
172
218
|
},
|
|
173
219
|
{
|
|
174
220
|
name: 'rejects a non-object unreachable recipient',
|
|
175
|
-
response: { entry: APPEND_LOG_ENTRY, unreachableRecipients: ['missing-reviewer'] },
|
|
221
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, unreachableRecipients: ['missing-reviewer'] },
|
|
176
222
|
accepts: false,
|
|
177
223
|
},
|
|
178
224
|
{
|
|
179
225
|
name: 'rejects missing unreachable-recipient fields',
|
|
180
|
-
response: { entry: APPEND_LOG_ENTRY, unreachableRecipients: [{ id: 'missing-reviewer' }] },
|
|
226
|
+
response: { entry: APPEND_LOG_ENTRY, deduplicated: false, unreachableRecipients: [{ id: 'missing-reviewer' }] },
|
|
181
227
|
accepts: false,
|
|
182
228
|
},
|
|
183
229
|
{
|
|
184
230
|
name: 'rejects unknown unreachable-recipient fields',
|
|
185
231
|
response: {
|
|
186
232
|
entry: APPEND_LOG_ENTRY,
|
|
233
|
+
deduplicated: false,
|
|
187
234
|
unreachableRecipients: [{ id: 'missing-reviewer', label: 'Missing Reviewer', extra: true }],
|
|
188
235
|
},
|
|
189
236
|
accepts: false,
|
|
@@ -192,6 +239,7 @@ export const APPEND_LOG_RESULT_CONFORMANCE: readonly AppendLogResultConformanceV
|
|
|
192
239
|
name: 'rejects an invalid unreachable-recipient id',
|
|
193
240
|
response: {
|
|
194
241
|
entry: APPEND_LOG_ENTRY,
|
|
242
|
+
deduplicated: false,
|
|
195
243
|
unreachableRecipients: [{ id: 7, label: 'Missing Reviewer' }],
|
|
196
244
|
},
|
|
197
245
|
accepts: false,
|
|
@@ -200,6 +248,7 @@ export const APPEND_LOG_RESULT_CONFORMANCE: readonly AppendLogResultConformanceV
|
|
|
200
248
|
name: 'rejects an invalid unreachable-recipient label',
|
|
201
249
|
response: {
|
|
202
250
|
entry: APPEND_LOG_ENTRY,
|
|
251
|
+
deduplicated: false,
|
|
203
252
|
unreachableRecipients: [{ id: 'missing-reviewer', label: null }],
|
|
204
253
|
},
|
|
205
254
|
accepts: false,
|
|
@@ -750,11 +799,48 @@ const ATTACH_RESPONSE = {
|
|
|
750
799
|
runtime_metadata_reported: false,
|
|
751
800
|
},
|
|
752
801
|
session: { id: '40000000-0000-4000-8000-000000000001' },
|
|
802
|
+
initial_log_cursor: null,
|
|
753
803
|
} satisfies AttachResponse;
|
|
754
804
|
|
|
755
805
|
/** Wire vectors for the v3 non-expiring attach-session response. */
|
|
756
806
|
export const ATTACH_SESSION_CONFORMANCE: readonly AttachSessionConformanceVector[] = [
|
|
757
807
|
{ name: 'accepts exact non-expiring session id', response: ATTACH_RESPONSE, accepts: true },
|
|
808
|
+
{
|
|
809
|
+
name: 'accepts a canonical initial log cursor',
|
|
810
|
+
response: {
|
|
811
|
+
...ATTACH_RESPONSE,
|
|
812
|
+
initial_log_cursor: {
|
|
813
|
+
id: '50000000-0000-4000-8000-000000000001',
|
|
814
|
+
created_at: '2026-07-14T10:00:00.000Z',
|
|
815
|
+
},
|
|
816
|
+
},
|
|
817
|
+
accepts: true,
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
name: 'rejects an omitted initial log cursor',
|
|
821
|
+
response: (({ initial_log_cursor: _, ...response }) => response)(ATTACH_RESPONSE),
|
|
822
|
+
accepts: false,
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
name: 'rejects an invalid initial log cursor UUID',
|
|
826
|
+
response: {
|
|
827
|
+
...ATTACH_RESPONSE,
|
|
828
|
+
initial_log_cursor: { id: 'not-a-uuid', created_at: '2026-07-14T10:00:00.000Z' },
|
|
829
|
+
},
|
|
830
|
+
accepts: false,
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
name: 'rejects unknown initial log cursor fields',
|
|
834
|
+
response: {
|
|
835
|
+
...ATTACH_RESPONSE,
|
|
836
|
+
initial_log_cursor: {
|
|
837
|
+
id: '50000000-0000-4000-8000-000000000001',
|
|
838
|
+
created_at: '2026-07-14T10:00:00.000Z',
|
|
839
|
+
extra: true,
|
|
840
|
+
},
|
|
841
|
+
},
|
|
842
|
+
accepts: false,
|
|
843
|
+
},
|
|
758
844
|
{
|
|
759
845
|
name: 'rejects retired expires_at field',
|
|
760
846
|
response: {
|
package/src/protocol/contract.ts
CHANGED
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
} from './types.js';
|
|
14
14
|
|
|
15
15
|
export const SHARED_PACKAGE_NAME = 'borgmcp-shared' as const;
|
|
16
|
-
export const SHARED_PACKAGE_VERSION = '0.
|
|
16
|
+
export const SHARED_PACKAGE_VERSION = '0.12.0' as const;
|
|
17
17
|
/** Maximum UTF-8 payload for each newly recorded decision text field. */
|
|
18
18
|
export const DECISION_TEXT_MAX_BYTES = 512 as const;
|
|
19
19
|
/** Maximum UTF-8 size of role detailed-description text and any returned section slice. */
|
|
@@ -580,7 +580,7 @@ export function decodeProtocolTagPreflight(value: unknown): ProtocolTagPreflight
|
|
|
580
580
|
exactKeys(input, ['protocol_version'], ['protocol_version']);
|
|
581
581
|
if (input.protocol_version !== PROTOCOL_VERSION) {
|
|
582
582
|
throw new ProtocolContractError(
|
|
583
|
-
'This client requires protocol
|
|
583
|
+
'This client requires protocol v9. The peer presents a different version. Update `borgmcp-server` and `borgmcp` to matching releases — server first, then client.',
|
|
584
584
|
ErrorCode.UNSUPPORTED_PROTOCOL_VERSION,
|
|
585
585
|
['protocol_version'],
|
|
586
586
|
);
|
|
@@ -997,10 +997,11 @@ export function decodeAppendLogRequest(value: unknown): import('./types.js').App
|
|
|
997
997
|
const input = record(value);
|
|
998
998
|
exactKeys(
|
|
999
999
|
input,
|
|
1000
|
-
['message', 'visibility', 'recipientDroneIds', 'class', 'to'],
|
|
1001
|
-
['message'],
|
|
1000
|
+
['post_id', 'message', 'visibility', 'recipientDroneIds', 'class', 'to'],
|
|
1001
|
+
['post_id', 'message'],
|
|
1002
1002
|
);
|
|
1003
1003
|
const output: import('./types.js').AppendLogRequest = {
|
|
1004
|
+
post_id: decodeUuid(input.post_id, ['post_id']),
|
|
1004
1005
|
message: boundedString(input.message, 1, 10_240, ['message']),
|
|
1005
1006
|
};
|
|
1006
1007
|
if (input.visibility !== undefined) {
|
|
@@ -1259,6 +1260,7 @@ export interface AttachResponse {
|
|
|
1259
1260
|
role: AttachRole;
|
|
1260
1261
|
drone: AttachDrone;
|
|
1261
1262
|
session: AttachSession;
|
|
1263
|
+
initial_log_cursor: LogCursor | null;
|
|
1262
1264
|
}
|
|
1263
1265
|
|
|
1264
1266
|
function decodeAttachCube(value: unknown, path: readonly (string | number)[]): AttachCube {
|
|
@@ -1393,12 +1395,13 @@ export function decodeAttachRequestEnvelope(
|
|
|
1393
1395
|
*/
|
|
1394
1396
|
export function decodeAttachResponse(value: unknown): AttachResponse {
|
|
1395
1397
|
const input = record(value);
|
|
1396
|
-
exactKeys(input, ['result', 'cube', 'role', 'drone', 'session'], [
|
|
1398
|
+
exactKeys(input, ['result', 'cube', 'role', 'drone', 'session', 'initial_log_cursor'], [
|
|
1397
1399
|
'result',
|
|
1398
1400
|
'cube',
|
|
1399
1401
|
'role',
|
|
1400
1402
|
'drone',
|
|
1401
1403
|
'session',
|
|
1404
|
+
'initial_log_cursor',
|
|
1402
1405
|
]);
|
|
1403
1406
|
if (input.result !== 'created' && input.result !== 'reused') {
|
|
1404
1407
|
fail('Expected result "created" or "reused".', ['result']);
|
|
@@ -1409,6 +1412,9 @@ export function decodeAttachResponse(value: unknown): AttachResponse {
|
|
|
1409
1412
|
role: decodeAttachRole(input.role, ['role']),
|
|
1410
1413
|
drone: decodeAttachDrone(input.drone, ['drone']),
|
|
1411
1414
|
session: decodeAttachSession(input.session, ['session']),
|
|
1415
|
+
initial_log_cursor: input.initial_log_cursor === null
|
|
1416
|
+
? null
|
|
1417
|
+
: decodeLogCursor(input.initial_log_cursor, ['initial_log_cursor']),
|
|
1412
1418
|
};
|
|
1413
1419
|
}
|
|
1414
1420
|
|
|
@@ -376,8 +376,14 @@ function decodeUnreachableRecipient(
|
|
|
376
376
|
|
|
377
377
|
export function decodeAppendLogResult(value: unknown): AppendLogResult {
|
|
378
378
|
const input = object(value);
|
|
379
|
-
exact(input, ['entry', 'routing', 'unreachableRecipients'], ['entry']);
|
|
380
|
-
|
|
379
|
+
exact(input, ['entry', 'deduplicated', 'routing', 'unreachableRecipients'], ['entry', 'deduplicated']);
|
|
380
|
+
if (typeof input.deduplicated !== 'boolean') {
|
|
381
|
+
throw new ProtocolContractError('Invalid append-log deduplicated flag.');
|
|
382
|
+
}
|
|
383
|
+
const output: AppendLogResult = {
|
|
384
|
+
entry: decodeEnrichedStreamEntry(input.entry),
|
|
385
|
+
deduplicated: input.deduplicated,
|
|
386
|
+
};
|
|
381
387
|
if (input.routing !== undefined) {
|
|
382
388
|
output.routing = input.routing === null ? null : decodeRoutingEcho(input.routing);
|
|
383
389
|
}
|
package/src/protocol/errors.ts
CHANGED
|
@@ -14,6 +14,7 @@ export enum ErrorCode {
|
|
|
14
14
|
NOT_FOUND = 'NOT_FOUND',
|
|
15
15
|
REPOSITORY_ALREADY_ASSOCIATED = 'REPOSITORY_ALREADY_ASSOCIATED',
|
|
16
16
|
CUBE_ALREADY_ASSOCIATED = 'CUBE_ALREADY_ASSOCIATED',
|
|
17
|
+
POST_ID_CONFLICT = 'POST_ID_CONFLICT',
|
|
17
18
|
ROLE_IN_USE = 'ROLE_IN_USE',
|
|
18
19
|
DEFAULT_ROLE_REQUIRED = 'DEFAULT_ROLE_REQUIRED',
|
|
19
20
|
ROLE_REQUIRED = 'ROLE_REQUIRED',
|
package/src/protocol/types.ts
CHANGED
|
@@ -171,6 +171,7 @@ export interface RoutingEcho {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
export interface AppendLogRequest {
|
|
174
|
+
post_id: string;
|
|
174
175
|
message: string;
|
|
175
176
|
visibility?: LogVisibility;
|
|
176
177
|
recipientDroneIds?: string[];
|
|
@@ -180,6 +181,7 @@ export interface AppendLogRequest {
|
|
|
180
181
|
|
|
181
182
|
export interface AppendLogResponse {
|
|
182
183
|
entry: ActivityLogEntry;
|
|
184
|
+
deduplicated: boolean;
|
|
183
185
|
routing?: RoutingEcho | null;
|
|
184
186
|
unreachableRecipients?: Array<{ id: string; label: string }>;
|
|
185
187
|
}
|
package/src/protocol/version.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Current Borg coordination protocol generation. Clean-slate
|
|
2
|
-
export const PROTOCOL_VERSION = '
|
|
1
|
+
/** Current Borg coordination protocol generation. Clean-slate v9. */
|
|
2
|
+
export const PROTOCOL_VERSION = '9' as const;
|
|
3
3
|
|
|
4
4
|
export type ProtocolVersion = typeof PROTOCOL_VERSION;
|