dsh-live-teams 0.1.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.
Files changed (69) hide show
  1. package/LICENSE +176 -0
  2. package/NOTICE +11 -0
  3. package/README.md +85 -0
  4. package/cordis.patch.yml +25 -0
  5. package/lib/binding.d.ts +18 -0
  6. package/lib/binding.js +42 -0
  7. package/lib/changed-paths.d.ts +26 -0
  8. package/lib/changed-paths.js +69 -0
  9. package/lib/client.js +6753 -0
  10. package/lib/command-queue.d.ts +60 -0
  11. package/lib/command-queue.js +185 -0
  12. package/lib/compatibility.js +109 -0
  13. package/lib/context-provider.d.ts +110 -0
  14. package/lib/context-provider.js +249 -0
  15. package/lib/dispatch.d.ts +174 -0
  16. package/lib/dispatch.js +624 -0
  17. package/lib/errors.d.ts +36 -0
  18. package/lib/errors.js +103 -0
  19. package/lib/git-artifacts.d.ts +50 -0
  20. package/lib/git-artifacts.js +242 -0
  21. package/lib/index.d.ts +14 -0
  22. package/lib/index.js +14 -0
  23. package/lib/mailbox.d.ts +274 -0
  24. package/lib/mailbox.js +721 -0
  25. package/lib/member-tools.d.ts +57 -0
  26. package/lib/member-tools.js +1265 -0
  27. package/lib/migrations.d.ts +17 -0
  28. package/lib/migrations.js +47 -0
  29. package/lib/plugin.d.ts +106 -0
  30. package/lib/plugin.js +1003 -0
  31. package/lib/roles.d.ts +35 -0
  32. package/lib/roles.js +284 -0
  33. package/lib/routes.d.ts +586 -0
  34. package/lib/routes.js +2816 -0
  35. package/lib/scope.d.ts +62 -0
  36. package/lib/scope.js +133 -0
  37. package/lib/session-bridge.d.ts +76 -0
  38. package/lib/session-bridge.js +147 -0
  39. package/lib/session-title.js +35 -0
  40. package/lib/storage.d.ts +9 -0
  41. package/lib/storage.js +65 -0
  42. package/lib/task-store.d.ts +729 -0
  43. package/lib/task-store.js +2205 -0
  44. package/lib/team-store.d.ts +216 -0
  45. package/lib/team-store.js +765 -0
  46. package/lib/tree-snapshot.d.ts +28 -0
  47. package/lib/tree-snapshot.js +80 -0
  48. package/lib/types/client/TeamView.d.ts +26 -0
  49. package/lib/types/client/TeamView.dom.test.d.ts +1 -0
  50. package/lib/types/client/api.d.ts +522 -0
  51. package/lib/types/client/api.test.d.ts +1 -0
  52. package/lib/types/client/attention.d.ts +65 -0
  53. package/lib/types/client/attention.test.d.ts +1 -0
  54. package/lib/types/client/index.d.ts +31 -0
  55. package/lib/types/client/locales.d.ts +577 -0
  56. package/lib/types/client/member-name.d.ts +14 -0
  57. package/lib/types/client/member-name.test.d.ts +1 -0
  58. package/lib/types/client/roster.d.ts +26 -0
  59. package/lib/types/client/roster.test.d.ts +1 -0
  60. package/lib/types/client/styles.d.ts +3 -0
  61. package/package.json +104 -0
  62. package/roles/builder.md +40 -0
  63. package/roles/delegate.md +36 -0
  64. package/roles/lead.md +46 -0
  65. package/roles/oracle.md +36 -0
  66. package/roles/researcher.md +37 -0
  67. package/roles/reviewer.md +45 -0
  68. package/roles/scout.md +36 -0
  69. package/roles/verifier.md +36 -0
@@ -0,0 +1,274 @@
1
+ //#region src/mailbox.d.ts
2
+ export type MessageKind = 'message' | 'direction' | 'comment';
3
+ export type MessageWakePolicy = 'never' | 'queue' | 'steer';
4
+ export type MessageAckPolicy = 'delivery' | 'consumption' | 'formal';
5
+ export type MessageDeliveryState = 'stored' | 'leased' | 'delivered' | 'acknowledged' | 'failed';
6
+ export type MessageDeliveryOutcome = 'delivered' | 'inbox' | 'pending' | 'failed';
7
+ /**
8
+ * The one delivery failure the dispatcher may retry on its own: the recipient had
9
+ * no usable binding yet. Every other failure is terminal and stays visible —
10
+ * the reconciler never resurrects a delivery for a reason it cannot name.
11
+ */
12
+ export declare const NO_SESSION_FAILURE = "recipient has no current session binding";
13
+ /** The immutable, frozen B12 message envelope. */
14
+ export interface TeamMessage {
15
+ id: string;
16
+ teamId: string;
17
+ from: string | 'human' | 'scheduler';
18
+ to: string | 'human' | 'team';
19
+ kind: MessageKind;
20
+ content: string;
21
+ threadId?: string;
22
+ createdAt: number;
23
+ }
24
+ /** Recipient-specific mutable delivery state. */
25
+ export interface MessageDelivery {
26
+ id: string;
27
+ messageId: string;
28
+ recipient: string | 'human';
29
+ wakePolicy: MessageWakePolicy;
30
+ ackPolicy: MessageAckPolicy;
31
+ state: MessageDeliveryState;
32
+ claimedAt?: number;
33
+ deliveredAt?: number;
34
+ acknowledgedAt?: number;
35
+ failure?: string;
36
+ revision: number;
37
+ }
38
+ export type MessageDraft = {
39
+ to: string | 'human' | 'team';
40
+ kind: MessageKind;
41
+ content: string;
42
+ threadId?: string;
43
+ };
44
+ /** Identity is an operation context, not a field supplied in MessageDraft. */
45
+ export type MailboxActor = {
46
+ type: 'session';
47
+ sessionId: string;
48
+ } | {
49
+ type: 'human';
50
+ } | {
51
+ type: 'scheduler';
52
+ };
53
+ export type MailboxRecipient = {
54
+ memberId: string;
55
+ displayName?: string;
56
+ sessionId?: string;
57
+ bindingGeneration?: number;
58
+ active?: boolean;
59
+ };
60
+ export type ResolvedMailboxRecipient = {
61
+ readonly recipient: TeamMessage['to'];
62
+ readonly name: string;
63
+ };
64
+ /** Resolve the one addressing vocabulary shared by member and human sends. */
65
+ export declare function resolveMailboxRecipient(value: string, recipients: readonly MailboxRecipient[]): ResolvedMailboxRecipient;
66
+ export type MailboxAuditEvent = {
67
+ kind: 'message/sent';
68
+ teamId: string;
69
+ messageId: string;
70
+ from: TeamMessage['from'];
71
+ /** The sender, which is the actor of this transition. */
72
+ actor: TeamMessage['from'];
73
+ to: TeamMessage['to'];
74
+ messageKind: MessageKind;
75
+ at: number;
76
+ } | {
77
+ kind: 'delivery/leased';
78
+ teamId: string;
79
+ deliveryId: string;
80
+ messageId: string;
81
+ recipient: string;
82
+ at: number;
83
+ revision: number;
84
+ } | {
85
+ kind: 'delivery/delivered';
86
+ teamId: string;
87
+ deliveryId: string;
88
+ messageId: string;
89
+ recipient: string;
90
+ at: number;
91
+ revision: number;
92
+ } | {
93
+ kind: 'delivery/acknowledged';
94
+ teamId: string;
95
+ deliveryId: string;
96
+ messageId: string;
97
+ recipient: string;
98
+ /** The recipient acknowledges its own delivery, so it is the actor. */
99
+ actor: string;
100
+ at: number;
101
+ revision: number;
102
+ } | {
103
+ kind: 'delivery/failed';
104
+ teamId: string;
105
+ deliveryId: string;
106
+ messageId: string;
107
+ recipient: string;
108
+ reason: string;
109
+ at: number;
110
+ revision: number;
111
+ } | {
112
+ /** A direction could not be steered and was queued instead. */
113
+ kind: 'delivery/steer-fallback';
114
+ teamId: string;
115
+ deliveryId: string;
116
+ messageId: string;
117
+ reason: string;
118
+ at: number;
119
+ };
120
+ export type CommandQueueRecord = {
121
+ commandId: string;
122
+ idempotencyKey: string;
123
+ sessionId: string;
124
+ bindingGeneration: number;
125
+ mode: 'queue' | 'steer';
126
+ requestId: string;
127
+ state: 'pending' | 'leased' | 'admitted' | 'applied' | 'failed';
128
+ receipt: string | undefined;
129
+ failureCode: string | undefined;
130
+ failureDetail: string | undefined;
131
+ revision: number;
132
+ };
133
+ type CommandRecordLike = {
134
+ commandId: string;
135
+ idempotencyKey: string;
136
+ sessionId: string;
137
+ bindingGeneration: number;
138
+ mode: 'queue' | 'steer';
139
+ requestId: string;
140
+ state: 'pending' | 'leased' | 'admitted' | 'applied' | 'failed';
141
+ receipt: string | undefined;
142
+ failureCode: string | undefined;
143
+ failureDetail: string | undefined;
144
+ revision: number;
145
+ };
146
+ export type CommandQueueLike = {
147
+ admit(request: {
148
+ idempotencyKey: string;
149
+ sessionId: string;
150
+ bindingGeneration: number;
151
+ mode: 'queue' | 'steer';
152
+ content: readonly unknown[];
153
+ reason?: string;
154
+ causationId?: string;
155
+ }): Promise<{
156
+ record: CommandRecordLike;
157
+ duplicate: boolean;
158
+ }>;
159
+ dispatch(commandId: string): Promise<CommandRecordLike>;
160
+ };
161
+ export type MailboxAuthorizeRequest = {
162
+ from: TeamMessage['from'];
163
+ to: string;
164
+ };
165
+ export type MailboxOptions = {
166
+ workspacePath: string;
167
+ teamId: string;
168
+ queue: CommandQueueLike;
169
+ listRecipients: () => Promise<readonly MailboxRecipient[]>;
170
+ /** Optional policy gate, called before any mailbox row is persisted. */
171
+ authorize?: (request: MailboxAuthorizeRequest) => void | Promise<void>;
172
+ resolveSessionSender?: (sessionId: string) => Promise<string | undefined> | string | undefined;
173
+ appendAudit?: (event: MailboxAuditEvent) => Promise<void>;
174
+ now?: () => number;
175
+ leaseMs?: number;
176
+ /** Defaults to true: send persists before attempting each live delivery. */
177
+ autoDeliver?: boolean;
178
+ };
179
+ export type SendResult = {
180
+ message: TeamMessage;
181
+ deliveries: MessageDelivery[];
182
+ };
183
+ export type AcknowledgeResult = {
184
+ delivery: MessageDelivery;
185
+ duplicate: boolean;
186
+ };
187
+ declare function messagePolicy(kind: MessageKind, recipient: TeamMessage['to']): Pick<MessageDelivery, 'wakePolicy' | 'ackPolicy'>;
188
+ /** Derive the externally reported outcome from a final delivery state and policy. */
189
+ export declare function messageDeliveryOutcome(delivery: Pick<MessageDelivery, 'state' | 'wakePolicy'>): MessageDeliveryOutcome;
190
+ export declare class MailboxService {
191
+ private readonly workspacePath;
192
+ private readonly teamId;
193
+ private readonly queue;
194
+ private readonly listRecipients;
195
+ private readonly authorize;
196
+ private readonly resolveSessionSender;
197
+ private readonly appendAudit;
198
+ private readonly now;
199
+ private readonly leaseMs;
200
+ private readonly autoDeliver;
201
+ private readonly directory;
202
+ private readonly messagesFile;
203
+ private readonly deliveriesFile;
204
+ private readonly lockFile;
205
+ constructor(options: MailboxOptions);
206
+ listMessages(): Promise<TeamMessage[]>;
207
+ listDeliveries(): Promise<MessageDelivery[]>;
208
+ getMessage(messageId: string): Promise<TeamMessage | undefined>;
209
+ getDelivery(deliveryId: string): Promise<MessageDelivery | undefined>;
210
+ deliveriesFor(messageId: string): Promise<MessageDelivery[]>;
211
+ /**
212
+ * Internal send path.
213
+ *
214
+ * Deliberately private: an actor argument that any caller may supply would let
215
+ * a member send as `human` or as another member, which ADR 0004 forbids. The
216
+ * public entries derive the sender instead — from the calling Session binding
217
+ * for member traffic, and from the host itself for human and scheduler paths.
218
+ */
219
+ private send;
220
+ sendFromSession(sessionId: string, draft: MessageDraft): Promise<SendResult>;
221
+ sendFromHuman(draft: MessageDraft): Promise<SendResult>;
222
+ sendFromScheduler(draft: MessageDraft): Promise<SendResult>;
223
+ claimDelivery(deliveryId: string): Promise<MessageDelivery | undefined>;
224
+ deliver(deliveryId: string): Promise<MessageDelivery>;
225
+ /**
226
+ * One transport attempt in one mode.
227
+ *
228
+ * The idempotency key carries the mode, because the key is bound to the first
229
+ * command admitted under it: reusing one key for a queue retry after a steer
230
+ * attempt would return the steer command and change nothing. The mode is part
231
+ * of what makes this attempt distinct, and `(messageId, recipient)` still
232
+ * identifies the delivery itself.
233
+ */
234
+ private attemptDelivery;
235
+ private admitOnce;
236
+ retryExpiredLeases(): Promise<MessageDelivery[]>;
237
+ retryDelivery(deliveryId: string): Promise<MessageDelivery>;
238
+ acknowledge(messageId: string, recipient: string, _formal?: boolean): Promise<AcknowledgeResult>;
239
+ private resolveFrom;
240
+ /**
241
+ * A message persisted without its delivery rows is a message nobody will ever see: the snapshot is
242
+ * two files, and a process that dies between them leaves exactly that. The reconciler calls this,
243
+ * and the orphan becomes a visible failed delivery instead of silence (external review, mailbox
244
+ * atomicity).
245
+ */
246
+ healOrphanMessages(): Promise<{
247
+ messageId: string;
248
+ recipient: string;
249
+ }[]>;
250
+ private markDelivered;
251
+ private fail;
252
+ private snapshot;
253
+ /**
254
+ * Comments this member has not acknowledged, read synchronously.
255
+ *
256
+ * The membership context is assembled synchronously, and a comment is stored with
257
+ * `wakePolicy: never` — nothing wakes the Session for it. Without a sync reader the recipient only
258
+ * ever learns about a comment if it happens to ask (external review, finding 13).
259
+ */
260
+ unreadCommentsForSync(memberId: string): {
261
+ from: string;
262
+ content: string;
263
+ at: number;
264
+ }[];
265
+ private readSnapshot;
266
+ private readMessages;
267
+ private readDeliveries;
268
+ private persist;
269
+ private audit;
270
+ }
271
+ export type CreateMailboxOptions = MailboxOptions;
272
+ export declare function createMailbox(options: MailboxOptions): MailboxService;
273
+ //#endregion
274
+ export { messagePolicy };