@nestos/kanban 0.5.1 → 0.5.2

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 (147) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +73 -29
  3. package/dist/{activity-C6xDM-cg.d.cts → activity-BbC4sgKL.d.cts} +28 -2
  4. package/dist/{activity-Dw8DOw0L.d.ts → activity-Czlan5xW.d.ts} +28 -2
  5. package/dist/activity-module-DaO1Rry0.d.cts +22 -0
  6. package/dist/activity-module-T22wliZu.d.ts +22 -0
  7. package/dist/activity-ports-Dqxa86zT.d.cts +12 -0
  8. package/dist/activity-ports-cxfrelaL.d.ts +12 -0
  9. package/dist/activity.cjs +10 -282
  10. package/dist/activity.cjs.map +1 -1
  11. package/dist/activity.d.cts +8 -30
  12. package/dist/activity.d.ts +8 -30
  13. package/dist/activity.js +9 -281
  14. package/dist/activity.js.map +1 -1
  15. package/dist/{chunk-O4OGAAV4.js → chunk-3JYLJPE5.js} +29 -5
  16. package/dist/chunk-3JYLJPE5.js.map +1 -0
  17. package/dist/{chunk-ATUFFNLV.js → chunk-3LEIHB7Y.js} +5 -5
  18. package/dist/chunk-4XF6LQSU.cjs.map +1 -1
  19. package/dist/chunk-5Q7WB63A.cjs +282 -0
  20. package/dist/chunk-5Q7WB63A.cjs.map +1 -0
  21. package/dist/{chunk-PSKQAFDF.cjs → chunk-7KDOTBRX.cjs} +1 -1
  22. package/dist/chunk-7KDOTBRX.cjs.map +1 -0
  23. package/dist/{chunk-5DLZWW5Y.js → chunk-AHHEGTUA.js} +3 -3
  24. package/dist/chunk-AOHQCX7K.cjs +95 -0
  25. package/dist/chunk-AOHQCX7K.cjs.map +1 -0
  26. package/dist/{chunk-IUI5CI2S.cjs → chunk-DINLR6E6.cjs} +96 -92
  27. package/dist/chunk-DINLR6E6.cjs.map +1 -0
  28. package/dist/{chunk-L44TM4EE.cjs → chunk-EYTVC2H5.cjs} +568 -454
  29. package/dist/chunk-EYTVC2H5.cjs.map +1 -0
  30. package/dist/chunk-FEE2YBZ7.js +1972 -0
  31. package/dist/chunk-FEE2YBZ7.js.map +1 -0
  32. package/dist/chunk-FNO5K3A7.js +282 -0
  33. package/dist/chunk-FNO5K3A7.js.map +1 -0
  34. package/dist/chunk-IHHDXZPZ.js +382 -0
  35. package/dist/chunk-IHHDXZPZ.js.map +1 -0
  36. package/dist/chunk-J3EAIVA3.js +280 -0
  37. package/dist/chunk-J3EAIVA3.js.map +1 -0
  38. package/dist/{chunk-DFTOTBGF.js → chunk-KH3WF3K4.js} +20 -16
  39. package/dist/chunk-KH3WF3K4.js.map +1 -0
  40. package/dist/{chunk-TB2RZGDV.js → chunk-M35X5PHO.js} +14 -1
  41. package/dist/chunk-M35X5PHO.js.map +1 -0
  42. package/dist/chunk-QRGZD2JU.cjs +1972 -0
  43. package/dist/chunk-QRGZD2JU.cjs.map +1 -0
  44. package/dist/{chunk-4KF7KUAI.cjs → chunk-RBOER6EW.cjs} +6 -6
  45. package/dist/chunk-RBOER6EW.cjs.map +1 -0
  46. package/dist/{chunk-6MN3H3YF.cjs → chunk-RSH6QSEC.cjs} +16 -3
  47. package/dist/chunk-RSH6QSEC.cjs.map +1 -0
  48. package/dist/{chunk-T7P5EIC4.cjs → chunk-VMRDXOLX.cjs} +33 -33
  49. package/dist/chunk-VMRDXOLX.cjs.map +1 -0
  50. package/dist/{chunk-5XKOCKY2.js → chunk-X4UHZX6F.js} +1 -1
  51. package/dist/chunk-XBSGUVCY.cjs +382 -0
  52. package/dist/chunk-XBSGUVCY.cjs.map +1 -0
  53. package/dist/{chunk-OHQTKGQN.js → chunk-XKDZHAUE.js} +242 -128
  54. package/dist/chunk-XKDZHAUE.js.map +1 -0
  55. package/dist/chunk-ZUZGAO6G.cjs +280 -0
  56. package/dist/chunk-ZUZGAO6G.cjs.map +1 -0
  57. package/dist/{content-CAIp1njn.d.cts → content-C5aJZFlw.d.cts} +1 -1
  58. package/dist/{content-CGMJdyH_.d.ts → content-hLH5BNud.d.ts} +1 -1
  59. package/dist/contracts/index.cjs +13 -3
  60. package/dist/contracts/index.cjs.map +1 -1
  61. package/dist/contracts/index.d.cts +5 -4
  62. package/dist/contracts/index.d.ts +5 -4
  63. package/dist/contracts/index.js +14 -4
  64. package/dist/{discovery-DxpirOz3.d.cts → discovery-9E-LfwIw.d.cts} +1 -1
  65. package/dist/{discovery-gSqWpuRm.d.ts → discovery-D60yrjej.d.ts} +1 -1
  66. package/dist/discovery.cjs +63 -65
  67. package/dist/discovery.cjs.map +1 -1
  68. package/dist/discovery.d.cts +4 -4
  69. package/dist/discovery.d.ts +4 -4
  70. package/dist/discovery.js +5 -7
  71. package/dist/discovery.js.map +1 -1
  72. package/dist/execution-bridge-fpCnH6z5.d.cts +52 -0
  73. package/dist/execution-bridge-rk0uVy_n.d.ts +52 -0
  74. package/dist/execution.cjs +6 -356
  75. package/dist/execution.cjs.map +1 -1
  76. package/dist/execution.d.cts +4 -51
  77. package/dist/execution.d.ts +4 -51
  78. package/dist/execution.js +9 -359
  79. package/dist/execution.js.map +1 -1
  80. package/dist/index.cjs +10 -12
  81. package/dist/index.cjs.map +1 -1
  82. package/dist/index.d.cts +9 -16
  83. package/dist/index.d.ts +9 -16
  84. package/dist/index.js +10 -12
  85. package/dist/index.js.map +1 -1
  86. package/dist/{module-CWNK2BMj.d.ts → module-CYfE7YhM.d.ts} +2 -2
  87. package/dist/{module-BbvwdCDF.d.cts → module-Ca9L3qCn.d.cts} +2 -2
  88. package/dist/{planning-CcFZYdIL.d.cts → planning-CHrOqQ6b.d.cts} +45 -10
  89. package/dist/{planning-CcFZYdIL.d.ts → planning-CHrOqQ6b.d.ts} +45 -10
  90. package/dist/{ports-Bn6ro2FB.d.ts → ports-B0McVg7B.d.ts} +4 -3
  91. package/dist/ports-BeGO1VRI.d.cts +49 -0
  92. package/dist/{ports-CaL6geqR.d.cts → ports-GQy0x-RI.d.cts} +4 -3
  93. package/dist/ports-ykGiNUSx.d.ts +49 -0
  94. package/dist/runtime/index.cjs +205 -0
  95. package/dist/runtime/index.cjs.map +1 -0
  96. package/dist/runtime/index.d.cts +75 -0
  97. package/dist/runtime/index.d.ts +75 -0
  98. package/dist/runtime/index.js +205 -0
  99. package/dist/runtime/index.js.map +1 -0
  100. package/dist/runtime/integration.cjs +423 -0
  101. package/dist/runtime/integration.cjs.map +1 -0
  102. package/dist/runtime/integration.d.cts +658 -0
  103. package/dist/runtime/integration.d.ts +658 -0
  104. package/dist/runtime/integration.js +423 -0
  105. package/dist/runtime/integration.js.map +1 -0
  106. package/dist/storage.cjs +9 -277
  107. package/dist/storage.cjs.map +1 -1
  108. package/dist/storage.d.cts +6 -6
  109. package/dist/storage.d.ts +6 -6
  110. package/dist/storage.js +11 -279
  111. package/dist/storage.js.map +1 -1
  112. package/dist/{store-q63eSMoT.d.cts → store-DPwHzGiz.d.cts} +2 -2
  113. package/dist/{store-Ct0gOAAg.d.ts → store-DgdrPCV9.d.ts} +2 -2
  114. package/dist/task-projection-CSorlMws.d.ts +11 -0
  115. package/dist/task-projection-DKKB_ueb.d.cts +11 -0
  116. package/examples/standalone.ts +22 -0
  117. package/package.json +117 -87
  118. package/dist/chunk-2YFPV5GF.cjs +0 -16
  119. package/dist/chunk-2YFPV5GF.cjs.map +0 -1
  120. package/dist/chunk-4KF7KUAI.cjs.map +0 -1
  121. package/dist/chunk-6MN3H3YF.cjs.map +0 -1
  122. package/dist/chunk-DFTOTBGF.js.map +0 -1
  123. package/dist/chunk-G6FCDLDF.js +0 -16
  124. package/dist/chunk-G6FCDLDF.js.map +0 -1
  125. package/dist/chunk-IUI5CI2S.cjs.map +0 -1
  126. package/dist/chunk-KYNYPKKH.cjs +0 -71
  127. package/dist/chunk-KYNYPKKH.cjs.map +0 -1
  128. package/dist/chunk-L44TM4EE.cjs.map +0 -1
  129. package/dist/chunk-LSE6JG5I.cjs +0 -20
  130. package/dist/chunk-LSE6JG5I.cjs.map +0 -1
  131. package/dist/chunk-O4OGAAV4.js.map +0 -1
  132. package/dist/chunk-OHQTKGQN.js.map +0 -1
  133. package/dist/chunk-PSKQAFDF.cjs.map +0 -1
  134. package/dist/chunk-QTMTBEBA.js +0 -20
  135. package/dist/chunk-QTMTBEBA.js.map +0 -1
  136. package/dist/chunk-T7P5EIC4.cjs.map +0 -1
  137. package/dist/chunk-TB2RZGDV.js.map +0 -1
  138. package/dist/ui/index.cjs +0 -1961
  139. package/dist/ui/index.cjs.map +0 -1
  140. package/dist/ui/index.d.cts +0 -209
  141. package/dist/ui/index.d.ts +0 -209
  142. package/dist/ui/index.js +0 -1961
  143. package/dist/ui/index.js.map +0 -1
  144. package/dist/ui/kanban.css +0 -194
  145. /package/dist/{chunk-ATUFFNLV.js.map → chunk-3LEIHB7Y.js.map} +0 -0
  146. /package/dist/{chunk-5DLZWW5Y.js.map → chunk-AHHEGTUA.js.map} +0 -0
  147. /package/dist/{chunk-5XKOCKY2.js.map → chunk-X4UHZX6F.js.map} +0 -0
package/dist/storage.js CHANGED
@@ -1,285 +1,17 @@
1
1
  import {
2
- SeqKanbanStore
3
- } from "./chunk-5DLZWW5Y.js";
2
+ ConditionalKanbanStore,
3
+ inspectKanbanContent,
4
+ installKanbanContent
5
+ } from "./chunk-J3EAIVA3.js";
4
6
  import {
5
- allocateBoardNumber,
6
- archiveKey,
7
- boardCounterKey,
8
- boardKey,
9
- boardNumberKey,
10
- counter,
11
- createBoardState,
12
- decodeRow,
13
- encodeBoard,
14
- encodeRow,
15
- hydrate,
16
- indexedView,
17
- numberEntities,
18
- proposeAmendment,
19
- receiptDigest,
20
- reduce,
21
- rowChanges,
22
- rowKeys,
23
- storedBoardNumber,
24
- verifyReceipt,
25
- viewFromState
26
- } from "./chunk-OHQTKGQN.js";
7
+ SeqKanbanStore
8
+ } from "./chunk-AHHEGTUA.js";
9
+ import "./chunk-XKDZHAUE.js";
27
10
  import "./chunk-RQP77ZTY.js";
28
- import {
29
- identity,
30
- normalizeActor,
31
- requireValue
32
- } from "./chunk-ATUFFNLV.js";
33
- import {
34
- KanbanError
35
- } from "./chunk-G6FCDLDF.js";
36
- import "./chunk-O4OGAAV4.js";
37
- import "./chunk-5XKOCKY2.js";
38
- import {
39
- randomUUID
40
- } from "./chunk-TB2RZGDV.js";
41
- import "./chunk-QTMTBEBA.js";
42
-
43
- // src/conditional-store.ts
44
- var ConditionalKanbanStore = class {
45
- constructor(client, prepareDirectory, path = "kanban/boards.seq", bodies) {
46
- this.client = client;
47
- this.prepareDirectory = prepareDirectory;
48
- this.path = path;
49
- this.bodies = bodies;
50
- if (!bodies && client.readBody && client.writeBody) this.bodies = { read: async (hash) => {
51
- try {
52
- return await client.readBody(path, hash);
53
- } catch (error) {
54
- if (error?.remoteCode === "SEQ_BODY_INTEGRITY") throw new KanbanError("BODY_INTEGRITY");
55
- throw error;
56
- }
57
- }, write: (hash, bytes) => client.writeBody(path, hash, bytes) };
58
- }
59
- async select(keys) {
60
- return this.client.query(this.path, { keys });
61
- }
62
- async boardId(number) {
63
- return entry(await this.select([boardNumberKey(number)]), boardNumberKey(number));
64
- }
65
- async ids() {
66
- return JSON.parse(entry(await this.select(["index"]), "index") ?? "[]");
67
- }
68
- async view(id) {
69
- const raw = entry(await this.select([boardKey(id)]), boardKey(id));
70
- const indexed = indexedView(raw);
71
- if (indexed) return indexed;
72
- const state = await this.read(id);
73
- return state ? viewFromState(state) : null;
74
- }
75
- async read(id) {
76
- const snapshot = await this.select([boardKey(id)]);
77
- return hydrate(await this.loadRows(entry(snapshot, boardKey(id)), snapshot.revision), this.bodies);
78
- }
79
- async loadRows(raw, revision) {
80
- const keys = rowKeys(raw), rows = {};
81
- for (let start = 0; start < keys.length; start += 256) {
82
- requireValue(revision !== null, "INVALID_STORAGE");
83
- const page = await this.queryRevision(keys.slice(start, start + 256), revision);
84
- for (const row of page.entries) {
85
- requireValue(typeof row.value === "string", "INVALID_STORAGE");
86
- rows[row.key] = row.value;
87
- }
88
- }
89
- return { raw, rows };
90
- }
91
- async queryRevision(keys, expectedRevision) {
92
- try {
93
- return await this.client.query(this.path, { keys, expectedRevision });
94
- } catch (error) {
95
- if (error?.code === "ECONFLICT") throw new KanbanError("REVISION_CONFLICT");
96
- throw error;
97
- }
98
- }
99
- async events(id, after, limit, through) {
100
- const end = Math.min(through, after + limit);
101
- const keys = Array.from({ length: Math.max(0, end - after) }, (_, index) => `event/${encodeURIComponent(id)}/${String(after + index + 1).padStart(16, "0")}`);
102
- if (!keys.length) return [];
103
- const events = [];
104
- for (let start = 0; start < keys.length; start += 256) {
105
- const rows = await this.select(keys.slice(start, start + 256));
106
- events.push(...rows.entries.map((e) => JSON.parse(String(e.value))));
107
- }
108
- return events.sort((a, b) => a.sequence - b.sequence);
109
- }
110
- async archived(board, item) {
111
- const raw = entry(await this.select([archiveKey(board, item)]), archiveKey(board, item));
112
- if (!raw) return null;
113
- const record = await decodeRow(raw, this.bodies);
114
- record.item.number ??= (await this.view(board))?.state.archiveIndex?.find((value) => value.id === item)?.number;
115
- return record;
116
- }
117
- async numberBoard(snapshot, raw, id, state) {
118
- const high = counter(entry(snapshot, boardCounterKey)), number = allocateBoardNumber(raw, high);
119
- state.board.number = number;
120
- if (storedBoardNumber(raw) !== void 0) return [];
121
- if (snapshot.revision !== null) {
122
- const lookup = await this.queryRevision([boardNumberKey(number)], snapshot.revision), owner = entry(lookup, boardNumberKey(number));
123
- requireValue(owner === null || owner === id, "INVALID_NUMBERING");
124
- }
125
- return [{ action: "set", key: boardCounterKey, value: String(Math.max(high, number)) }, { action: "set", key: boardNumberKey(number), value: id }];
126
- }
127
- async update(id, operationId, fingerprint, change) {
128
- await this.prepareDirectory();
129
- const receiptKey = `receipt/${encodeURIComponent(id)}/${encodeURIComponent(operationId)}`;
130
- const snapshot = await this.select([boardKey(id), receiptKey, "index", boardCounterKey]);
131
- const raw = entry(snapshot, boardKey(id)), receipt = entry(snapshot, receiptKey);
132
- const before = await this.loadRows(raw, snapshot.revision), current = await hydrate(before, this.bodies);
133
- if (receipt) {
134
- verifyReceipt(receipt, fingerprint);
135
- requireValue(current, "CORRUPT_RECEIPT");
136
- return current;
137
- }
138
- const original = JSON.stringify(current), state = change(current);
139
- numberEntities(state);
140
- if (JSON.stringify(state) === original) return state;
141
- const numbering = await this.numberBoard(snapshot, raw, id, state);
142
- const { changes, encoded } = await prepareChanges(id, before, state, this.bodies);
143
- changes.push(...numbering);
144
- changes.push({ action: "set", key: boardKey(id), value: encoded.raw }, { action: "set", key: receiptKey, value: receiptDigest(fingerprint) });
145
- const ids = JSON.parse(entry(snapshot, "index") ?? "[]");
146
- if (!ids.includes(id)) changes.push({ action: "set", key: "index", value: JSON.stringify([...ids, id]) });
147
- requireValue(changes.length <= 256, "REMOTE_TRANSACTION_LIMIT");
148
- try {
149
- await this.client.transaction(this.path, snapshot.revision, changes);
150
- } catch (error) {
151
- if (error?.outcome === "not-committed" && error?.code === "ECONFLICT") throw new KanbanError("REVISION_CONFLICT");
152
- throw error;
153
- }
154
- return state;
155
- }
156
- };
157
- function entry(snapshot, key) {
158
- const value = snapshot.entries.find((e) => e.key === key)?.value;
159
- if (value === void 0) return null;
160
- if (typeof value !== "string") throw new KanbanError("INVALID_STORAGE");
161
- return value;
162
- }
163
- async function prepareChanges(id, before, state, bodies) {
164
- const changes = state.events.map((event) => ({
165
- action: "set",
166
- key: `event/${encodeURIComponent(id)}/${String(event.sequence).padStart(16, "0")}`,
167
- value: JSON.stringify(event)
168
- }));
169
- for (const write of state.archiveWrites ?? []) changes.push(write.value ? { action: "set", key: archiveKey(id, write.id), value: await encodeRow(write.value, bodies) } : { action: "delete", key: archiveKey(id, write.id) });
170
- delete state.archiveWrites;
171
- state.events = [];
172
- const encoded = await encodeBoard(state, bodies);
173
- for (const row of rowChanges(before, encoded)) changes.push(row.value === null ? { action: "delete", key: row.key } : { action: "set", key: row.key, value: row.value });
174
- return { changes, encoded };
175
- }
176
-
177
- // src/content.ts
178
- async function inspectKanbanContent(store, content) {
179
- const state = await store.read(content.board.id);
180
- const ids = new Set([...state?.board.items ?? [], ...state?.archiveIndex ?? []].map((item) => item.id));
181
- return {
182
- version: state?.presetVersions?.[content.id] ?? 0,
183
- complete: !!state && content.items.every((item) => ids.has(item.command.item.id)) && (content.records ?? []).every((entry2) => state.records?.some((record) => record.id === entry2.record.id))
184
- };
185
- }
186
- async function installKanbanContent(options) {
187
- const started = (options.now ?? Date.now)(), content = structuredClone(options.content);
188
- try {
189
- identity(content.id);
190
- identity(options.operationId);
191
- validateContent(content);
192
- const actor = normalizeActor(options.actor), before = await options.store.read(content.board.id);
193
- const initial = before ?? createBoardState(content.board, actor, started);
194
- await options.authorize({ actor, board: structuredClone(initial.board), action: "install-content" });
195
- const result = { changed: false, created: 0 };
196
- if (before && !options.fillMissing && (before.presetVersions?.[content.id] ?? 1) >= content.version) {
197
- report(options, started, "success");
198
- return result;
199
- }
200
- await options.store.update(content.board.id, options.operationId, JSON.stringify({ content, actor, fillMissing: !!options.fillMissing, missingReferences: options.missingReferences }), (current) => {
201
- requireValue(JSON.stringify(current) === JSON.stringify(before), "REVISION_CONFLICT");
202
- if (current?.board.deletedAt !== void 0) {
203
- requireValue(!options.fillMissing, "BOARD_DELETED");
204
- return current;
205
- }
206
- const installed = current?.presetVersions?.[content.id] ?? (current ? 1 : 0);
207
- if (current && !options.fillMissing && installed >= content.version) return current;
208
- const state = current ?? initial;
209
- result.changed = !current;
210
- applyContent(state, { ...options, content }, actor, installed, started, result);
211
- (state.presetVersions ??= {})[content.id] = content.version;
212
- return state;
213
- });
214
- report(options, started, "success");
215
- return result;
216
- } catch (error) {
217
- const raw = error?.code;
218
- report(options, started, "failure", typeof raw === "string" && /^[A-Z][A-Z0-9_]{0,79}$/.test(raw) ? raw : "CONTENT_INSTALL_FAILED");
219
- throw error;
220
- }
221
- }
222
- function validateContent(content) {
223
- requireValue(Number.isSafeInteger(content.version) && content.version > 0, "INVALID_CONTENT_VERSION");
224
- requireValue(Array.isArray(content.items) && content.items.length <= 1e3, "CONTENT_ITEM_LIMIT");
225
- for (const rows of [content.records, content.amendments]) requireValue(rows === void 0 || Array.isArray(rows) && rows.length <= 1e3, "CONTENT_RECORD_LIMIT");
226
- for (const entry2 of [...content.items, ...content.records ?? [], ...content.amendments ?? []]) {
227
- const version = entry2.introduced ?? 1;
228
- requireValue(Number.isSafeInteger(version) && version > 0 && version <= content.version, "INVALID_CONTENT_VERSION");
229
- }
230
- }
231
- function applyContent(state, options, actor, installed, now, result) {
232
- const content = options.content, version = options.fillMissing ? 0 : installed;
233
- const known = new Set([...state.board.items, ...state.archiveIndex ?? []].map((item) => item.id));
234
- const apply = (command) => reduce(state, command, actor, options.operationId, now, (options.id ?? randomUUID)());
235
- for (const entry2 of content.items) {
236
- if (known.has(entry2.command.item.id) || (entry2.introduced ?? 1) <= version) continue;
237
- insertItem(state, entry2, options.missingReferences === "detach", apply);
238
- known.add(entry2.command.item.id);
239
- result.changed = true;
240
- result.created++;
241
- }
242
- for (const entry2 of content.records ?? []) {
243
- if ((entry2.introduced ?? 1) <= version || state.records?.some((record2) => record2.id === entry2.record.id)) continue;
244
- const record = structuredClone(entry2.record);
245
- if (options.missingReferences === "detach") record.itemIds = record.itemIds.filter((id) => known.has(id));
246
- apply({ type: "append-record", record });
247
- if (entry2.confirmed) apply({ type: "review-record", recordId: record.id, accept: true });
248
- result.changed = true;
249
- }
250
- for (const entry2 of content.amendments ?? []) {
251
- if ((entry2.introduced ?? 1) <= version) continue;
252
- const item = state.board.items.find((item2) => item2.id === entry2.itemId);
253
- if (!item) continue;
254
- const count = item.amendments?.length ?? 0;
255
- proposeAmendment(item, { action: "update", ...entry2, sources: [] }, entry2.proposedBy, now, entry2.runId);
256
- if ((item.amendments?.length ?? 0) > count) {
257
- item.revision++;
258
- state.board.revision++;
259
- result.changed = true;
260
- }
261
- }
262
- }
263
- function insertItem(state, entry2, detach, apply) {
264
- const command = structuredClone(entry2.command), parentId = command.planning?.parentId;
265
- if (detach && parentId) {
266
- const parent = state.board.items.find((item) => item.id === parentId);
267
- if (!parent || ["completed", "cancelled"].includes(parent.status)) delete command.planning.parentId;
268
- }
269
- const itemId = command.item.id;
270
- apply(command);
271
- if (entry2.blocked) apply({ type: "block-item", itemId, reason: entry2.blocked });
272
- if (entry2.completion) {
273
- apply({ type: "close-plan", itemId, resultRef: entry2.completion.resultRef });
274
- if (entry2.completion.archiveReason) apply({ type: "archive-items", itemIds: [itemId], reason: entry2.completion.archiveReason });
275
- }
276
- }
277
- function report(options, start, result, code) {
278
- try {
279
- options.log({ operationId: options.operationId, boardId: options.content.board.id, stage: "content.install", result, code, durationMs: (options.now ?? Date.now)() - start });
280
- } catch {
281
- }
282
- }
11
+ import "./chunk-3LEIHB7Y.js";
12
+ import "./chunk-X4UHZX6F.js";
13
+ import "./chunk-M35X5PHO.js";
14
+ import "./chunk-3JYLJPE5.js";
283
15
  export {
284
16
  ConditionalKanbanStore,
285
17
  SeqKanbanStore,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/conditional-store.ts","../src/content.ts"],"sourcesContent":["import {numberEntities, boardCounterKey, boardNumberKey, counter, allocateBoardNumber, storedBoardNumber} from './numbering';\nimport type {KanbanSeqClient, KanbanSeqChange, KanbanSeqSnapshot} from './storage-ports';\nimport type {KanbanEvent, KanbanArchivedItem} from './contracts';\nimport {KanbanError, type KanbanState, type KanbanStore} from './ports';\nimport {requireValue} from './rules';\nimport {indexedView, viewFromState, archiveKey, boardKey as key, rowKeys, hydrate, encodeBoard, rowChanges, encodeRow, decodeRow, receiptDigest, verifyReceipt, type StoredBoard, type KanbanBodyStore} from './storage-codec';\n\n/** The project export and its authorization are frozen in the injected HTTP client. */\nexport class ConditionalKanbanStore implements KanbanStore {\n constructor(private readonly client: Pick<KanbanSeqClient, 'query' | 'transaction'> & Partial<Pick<KanbanSeqClient, 'readBody' | 'writeBody'>>,\n private readonly prepareDirectory: () => Promise<void>, private readonly path = 'kanban/boards.seq', private readonly bodies?: KanbanBodyStore) {\n if (!bodies && client.readBody && client.writeBody) this.bodies = {read: async hash => {\n try {return await client.readBody!(path, hash);}\n catch (error) {if ((error as {remoteCode?: string})?.remoteCode === 'SEQ_BODY_INTEGRITY') throw new KanbanError('BODY_INTEGRITY'); throw error;}\n }, write: (hash, bytes) => client.writeBody!(path, hash, bytes)};\n }\n private async select(keys: string[]): Promise<KanbanSeqSnapshot> {return this.client.query(this.path, {keys});}\n async boardId(number: number): Promise<string | null> {return entry(await this.select([boardNumberKey(number)]), boardNumberKey(number));}\n async ids(): Promise<string[]> {return JSON.parse(entry(await this.select(['index']), 'index') ?? '[]');}\n async view(id: string) {\n const raw = entry(await this.select([key(id)]), key(id));\n const indexed = indexedView(raw); if (indexed) return indexed;\n const state = await this.read(id); return state ? viewFromState(state) : null;\n }\n async read(id: string): Promise<KanbanState | null> {\n const snapshot = await this.select([key(id)]);\n return hydrate(await this.loadRows(entry(snapshot, key(id)), snapshot.revision), this.bodies);\n }\n private async loadRows(raw: string | null, revision: string | null): Promise<StoredBoard> {\n const keys = rowKeys(raw), rows: Record<string, string> = {};\n for (let start = 0; start < keys.length; start += 256) {\n requireValue(revision !== null, 'INVALID_STORAGE');\n const page = await this.queryRevision(keys.slice(start, start + 256), revision);\n for (const row of page.entries) {requireValue(typeof row.value === 'string', 'INVALID_STORAGE'); rows[row.key] = row.value;}\n }\n return {raw, rows};\n }\n private async queryRevision(keys: string[], expectedRevision: string) {\n try {return await this.client.query(this.path, {keys, expectedRevision});}\n catch (error) {\n if ((error as {code?: string})?.code === 'ECONFLICT') throw new KanbanError('REVISION_CONFLICT');\n throw error;\n }\n }\n async events(id: string, after: number, limit: number, through: number): Promise<KanbanEvent[]> {\n const end = Math.min(through, after + limit);\n const keys = Array.from({length: Math.max(0, end - after)}, (_, index) =>\n `event/${encodeURIComponent(id)}/${String(after + index + 1).padStart(16, '0')}`);\n if (!keys.length) return [];\n const events: KanbanEvent[] = [];\n // Event keys below through are immutable; concurrent appends cannot change this prefix.\n for (let start = 0; start < keys.length; start += 256) {\n const rows = await this.select(keys.slice(start, start + 256));\n events.push(...rows.entries.map(e => JSON.parse(String(e.value)) as KanbanEvent));\n }\n return events.sort((a, b) => a.sequence - b.sequence);\n }\n async archived(board: string, item: string): Promise<KanbanArchivedItem | null> {\n const raw = entry(await this.select([archiveKey(board, item)]), archiveKey(board, item));\n if (!raw) return null; const record = await decodeRow<KanbanArchivedItem>(raw, this.bodies);\n record.item.number ??= (await this.view(board))?.state.archiveIndex?.find(value => value.id === item)?.number; return record;\n }\n private async numberBoard(snapshot: KanbanSeqSnapshot, raw: string | null, id: string, state: KanbanState): Promise<KanbanSeqChange[]> {\n const high = counter(entry(snapshot, boardCounterKey)), number = allocateBoardNumber(raw, high);\n state.board.number = number;\n if (storedBoardNumber(raw) !== undefined) return [];\n if (snapshot.revision !== null) {\n const lookup = await this.queryRevision([boardNumberKey(number)], snapshot.revision), owner = entry(lookup, boardNumberKey(number));\n requireValue(owner === null || owner === id, 'INVALID_NUMBERING');\n }\n return [{action:'set',key:boardCounterKey,value:String(Math.max(high,number))}, {action:'set',key:boardNumberKey(number),value:id}];\n }\n async update(id: string, operationId: string, fingerprint: string,\n change: (state: KanbanState | null) => KanbanState): Promise<KanbanState> {\n await this.prepareDirectory();\n const receiptKey = `receipt/${encodeURIComponent(id)}/${encodeURIComponent(operationId)}`;\n const snapshot = await this.select([key(id), receiptKey, 'index', boardCounterKey]);\n const raw = entry(snapshot, key(id)), receipt = entry(snapshot, receiptKey);\n const before = await this.loadRows(raw, snapshot.revision), current = await hydrate(before, this.bodies);\n if (receipt) {verifyReceipt(receipt, fingerprint); requireValue(current, 'CORRUPT_RECEIPT'); return current;}\n const original = JSON.stringify(current), state = change(current); numberEntities(state); if (JSON.stringify(state) === original) return state;\n const numbering = await this.numberBoard(snapshot, raw, id, state);\n const {changes, encoded} = await prepareChanges(id, before, state, this.bodies);\n changes.push(...numbering);\n changes.push({action: 'set', key: key(id), value: encoded.raw!}, {action: 'set', key: receiptKey, value: receiptDigest(fingerprint)});\n const ids: string[] = JSON.parse(entry(snapshot, 'index') ?? '[]');\n if (!ids.includes(id)) changes.push({action: 'set', key: 'index', value: JSON.stringify([...ids, id])});\n requireValue(changes.length <= 256, 'REMOTE_TRANSACTION_LIMIT');\n // The transport owns unknown-write reconciliation. Never retry a mutation here.\n try {await this.client.transaction(this.path, snapshot.revision, changes);}\n catch (error) {\n if ((error as {outcome?: string})?.outcome === 'not-committed' && (error as {code?: string})?.code === 'ECONFLICT') throw new KanbanError('REVISION_CONFLICT');\n throw error;\n }\n return state;\n }\n}\nfunction entry(snapshot: KanbanSeqSnapshot, key: string): string | null {\n const value = snapshot.entries.find(e => e.key === key)?.value;\n if (value === undefined) return null;\n if (typeof value !== 'string') throw new KanbanError('INVALID_STORAGE'); return value;\n}\n\nasync function prepareChanges(id: string, before: StoredBoard, state: KanbanState, bodies?: KanbanBodyStore) {\n const changes: KanbanSeqChange[] = state.events.map(event => ({action: 'set',\n key: `event/${encodeURIComponent(id)}/${String(event.sequence).padStart(16, '0')}`, value: JSON.stringify(event)}));\n for (const write of state.archiveWrites ?? []) changes.push(write.value\n ? {action: 'set', key: archiveKey(id, write.id), value: await encodeRow(write.value, bodies)}\n : {action: 'delete', key: archiveKey(id, write.id)});\n delete state.archiveWrites; state.events = [];\n const encoded = await encodeBoard(state, bodies);\n for (const row of rowChanges(before, encoded)) changes.push(row.value === null ? {action: 'delete', key: row.key} : {action: 'set', key: row.key, value: row.value});\n return {changes, encoded};\n}\n","import type {KanbanActor, KanbanCommand, KanbanContent, KanbanContentItem} from './contracts';\nimport type {KanbanModuleOptions, KanbanState, KanbanStore} from './ports';\nimport {createBoardState} from './board';\nimport {normalizeActor} from './identity';\nimport {identity, requireValue} from './rules';\nimport {reduce} from './reducer';\nimport {proposeAmendment} from './amendments';\nimport {randomUUID} from './utils';\n\nexport interface KanbanContentOptions extends KanbanModuleOptions {\n content: KanbanContent;\n operationId: string;\n fillMissing?: boolean;\n missingReferences?: 'reject' | 'detach';\n}\nexport async function inspectKanbanContent(store: KanbanStore, content: KanbanContent) {\n const state = await store.read(content.board.id);\n const ids = new Set([...state?.board.items ?? [], ...state?.archiveIndex ?? []].map(item => item.id));\n return {version: state?.presetVersions?.[content.id] ?? 0,\n complete: !!state && content.items.every(item => ids.has(item.command.item.id)) && (content.records ?? []).every(entry => state.records?.some(record => record.id === entry.record.id))};\n}\n\n/** Authorized bootstrap/import: domain changes and the installed version commit together. */\nexport async function installKanbanContent(options: KanbanContentOptions): Promise<{changed: boolean; created: number}> {\n const started = (options.now ?? Date.now)(), content = structuredClone(options.content);\n try {\n identity(content.id); identity(options.operationId);\n validateContent(content);\n const actor = normalizeActor(options.actor), before = await options.store.read(content.board.id);\n const initial = before ?? createBoardState(content.board, actor, started);\n await options.authorize({actor, board: structuredClone(initial.board), action: 'install-content'});\n const result = {changed: false, created: 0};\n if (before && !options.fillMissing && (before.presetVersions?.[content.id] ?? 1) >= content.version) {report(options, started, 'success'); return result;}\n await options.store.update(content.board.id, options.operationId, JSON.stringify({content, actor, fillMissing: !!options.fillMissing, missingReferences: options.missingReferences}), current => {\n requireValue(JSON.stringify(current) === JSON.stringify(before), 'REVISION_CONFLICT');\n if (current?.board.deletedAt !== undefined) {requireValue(!options.fillMissing, 'BOARD_DELETED'); return current;}\n const installed = current?.presetVersions?.[content.id] ?? (current ? 1 : 0);\n if (current && !options.fillMissing && installed >= content.version) return current;\n const state = current ?? initial; result.changed = !current;\n applyContent(state, {...options, content}, actor, installed, started, result);\n (state.presetVersions ??= {})[content.id] = content.version;\n return state;\n });\n report(options, started, 'success'); return result;\n } catch (error) {\n const raw = (error as {code?: unknown})?.code;\n report(options, started, 'failure', typeof raw === 'string' && /^[A-Z][A-Z0-9_]{0,79}$/.test(raw) ? raw : 'CONTENT_INSTALL_FAILED');\n throw error;\n }\n}\nfunction validateContent(content: KanbanContent): void {\n requireValue(Number.isSafeInteger(content.version) && content.version > 0, 'INVALID_CONTENT_VERSION');\n requireValue(Array.isArray(content.items) && content.items.length <= 1000, 'CONTENT_ITEM_LIMIT');\n for (const rows of [content.records, content.amendments]) requireValue(rows === undefined || Array.isArray(rows) && rows.length <= 1000, 'CONTENT_RECORD_LIMIT');\n for (const entry of [...content.items, ...content.records ?? [], ...content.amendments ?? []]) {\n const version = entry.introduced ?? 1;\n requireValue(Number.isSafeInteger(version) && version > 0 && version <= content.version, 'INVALID_CONTENT_VERSION');\n }\n}\nfunction applyContent(state: KanbanState, options: KanbanContentOptions, actor: KanbanActor, installed: number, now: number, result: {changed: boolean; created: number}): void {\n const content = options.content, version = options.fillMissing ? 0 : installed;\n const known = new Set([...state.board.items, ...state.archiveIndex ?? []].map(item => item.id));\n const apply = (command: KanbanCommand) => reduce(state, command, actor, options.operationId, now, (options.id ?? randomUUID)());\n for (const entry of content.items) {\n if (known.has(entry.command.item.id) || (entry.introduced ?? 1) <= version) continue;\n insertItem(state, entry, options.missingReferences === 'detach', apply);\n known.add(entry.command.item.id); result.changed = true; result.created++;\n }\n for (const entry of content.records ?? []) {\n if ((entry.introduced ?? 1) <= version || state.records?.some(record => record.id === entry.record.id)) continue;\n const record = structuredClone(entry.record);\n if (options.missingReferences === 'detach') record.itemIds = record.itemIds.filter(id => known.has(id));\n apply({type: 'append-record', record});\n if (entry.confirmed) apply({type: 'review-record', recordId: record.id, accept: true});\n result.changed = true;\n }\n for (const entry of content.amendments ?? []) {\n if ((entry.introduced ?? 1) <= version) continue;\n const item = state.board.items.find(item => item.id === entry.itemId); if (!item) continue;\n const count = item.amendments?.length ?? 0;\n // Imported attribution grants no authority to execute or review work.\n proposeAmendment(item, {action: 'update', ...entry, sources: []}, entry.proposedBy, now, entry.runId);\n if ((item.amendments?.length ?? 0) > count) {item.revision++; state.board.revision++; result.changed = true;}\n }\n}\nfunction insertItem(state: KanbanState, entry: KanbanContentItem, detach: boolean, apply: (command: KanbanCommand) => void): void {\n const command = structuredClone(entry.command), parentId = command.planning?.parentId;\n if (detach && parentId) {\n const parent = state.board.items.find(item => item.id === parentId);\n if (!parent || ['completed', 'cancelled'].includes(parent.status)) delete command.planning!.parentId;\n }\n const itemId = command.item.id;\n apply(command);\n if (entry.blocked) apply({type: 'block-item', itemId, reason: entry.blocked});\n if (entry.completion) {\n apply({type: 'close-plan', itemId, resultRef: entry.completion.resultRef});\n if (entry.completion.archiveReason) apply({type: 'archive-items', itemIds: [itemId], reason: entry.completion.archiveReason});\n }\n}\nfunction report(options: KanbanContentOptions, start: number, result: 'success' | 'failure', code?: string): void {\n try {options.log({operationId: options.operationId, boardId: options.content.board.id, stage: 'content.install', result, code, durationMs: (options.now ?? Date.now)() - start});}\n catch { /* Diagnostics cannot undo content installation. */ }\n}\n"],"mappings":"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","names":["entry","record","item"]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,5 +1,5 @@
1
- import { a as KanbanStore, b as KanbanReadView, c as KanbanState } from './ports-CaL6geqR.cjs';
2
- import { t as KanbanEvent, c as KanbanArchivedItem } from './planning-CcFZYdIL.cjs';
1
+ import { e as KanbanStore, b as KanbanReadView, d as KanbanState } from './ports-GQy0x-RI.cjs';
2
+ import { t as KanbanEvent, c as KanbanArchivedItem } from './planning-CHrOqQ6b.cjs';
3
3
  import { IFileSystem } from '@nestos/vfs-core';
4
4
 
5
5
  interface KanbanBodyStore {
@@ -1,5 +1,5 @@
1
- import { a as KanbanStore, b as KanbanReadView, c as KanbanState } from './ports-Bn6ro2FB.js';
2
- import { t as KanbanEvent, c as KanbanArchivedItem } from './planning-CcFZYdIL.js';
1
+ import { e as KanbanStore, b as KanbanReadView, d as KanbanState } from './ports-B0McVg7B.js';
2
+ import { t as KanbanEvent, c as KanbanArchivedItem } from './planning-CHrOqQ6b.js';
3
3
  import { IFileSystem } from '@nestos/vfs-core';
4
4
 
5
5
  interface KanbanBodyStore {
@@ -0,0 +1,11 @@
1
+ import { w as KanbanItem, a7 as KanbanWorkflowState, z as KanbanItemSummary, a1 as KanbanTaskProjection } from './planning-CHrOqQ6b.js';
2
+
3
+ type Item = Pick<KanbanItem, 'deletedAt' | 'id' | 'status' | 'createdAt' | 'launch' | 'analysis' | 'control' | 'issues' | 'blocked' | 'externalRefs' | 'planning'>;
4
+ declare const TASK_START_DELAY_MS = 300000;
5
+ declare function taskStartAt(item: Pick<Item, 'createdAt' | 'launch'>): number;
6
+ declare function taskEditing(item: Pick<Item, 'launch'>, now: number): boolean;
7
+ declare function taskDue(item: Item, now: number): boolean;
8
+ /** Ordered evidence projection shared by storage queries, CLI and UI. Session idle never proves acceptance. */
9
+ declare function projectKanbanTask(item: Item, workflow?: KanbanWorkflowState, now?: number, all?: Array<Pick<KanbanItemSummary, 'id' | 'status'>>): KanbanTaskProjection;
10
+
11
+ export { TASK_START_DELAY_MS as T, taskEditing as a, taskStartAt as b, projectKanbanTask as p, taskDue as t };
@@ -0,0 +1,11 @@
1
+ import { w as KanbanItem, a7 as KanbanWorkflowState, z as KanbanItemSummary, a1 as KanbanTaskProjection } from './planning-CHrOqQ6b.cjs';
2
+
3
+ type Item = Pick<KanbanItem, 'deletedAt' | 'id' | 'status' | 'createdAt' | 'launch' | 'analysis' | 'control' | 'issues' | 'blocked' | 'externalRefs' | 'planning'>;
4
+ declare const TASK_START_DELAY_MS = 300000;
5
+ declare function taskStartAt(item: Pick<Item, 'createdAt' | 'launch'>): number;
6
+ declare function taskEditing(item: Pick<Item, 'launch'>, now: number): boolean;
7
+ declare function taskDue(item: Item, now: number): boolean;
8
+ /** Ordered evidence projection shared by storage queries, CLI and UI. Session idle never proves acceptance. */
9
+ declare function projectKanbanTask(item: Item, workflow?: KanbanWorkflowState, now?: number, all?: Array<Pick<KanbanItemSummary, 'id' | 'status'>>): KanbanTaskProjection;
10
+
11
+ export { TASK_START_DELAY_MS as T, taskEditing as a, taskStartAt as b, projectKanbanTask as p, taskDue as t };
@@ -0,0 +1,22 @@
1
+ import {createVFS, MemoryBackend} from '@nestos/vfs-core';
2
+ import {createKanban, SeqKanbanStore} from '@nestos/kanban';
3
+
4
+ const {manager} = await createVFS({rootBackend: new MemoryBackend()});
5
+ const store = await SeqKanbanStore.open(await manager.openFileSystem('/'));
6
+ // The demo trusts its single in-memory user. Production hosts enforce authorization here.
7
+ const api = createKanban({store, actor: {kind: 'human', id: 'owner'}, authorize: async () => {}});
8
+ try {
9
+ await api.boards.create({id: 'research', title: 'Research', scope: {kind: 'system'},
10
+ members: [{kind: 'human', id: 'owner', responsibility: 'Research'}],
11
+ policy: {requireEstimate: false, review: 'assignee'}});
12
+ await api.execute('research', {operationId: 'create', expectedRevision: (await api.boards.get('research')).revision,
13
+ command: {type: 'create-item', stage: 'open', item: {id: 'experiment', title: 'Experiment', responsibility: 'Collect evidence', acceptance: 'Evidence recorded'}}});
14
+ await api.execute('research', {operationId: 'claim', expectedRevision: (await api.boards.get('research')).revision,
15
+ command: {type: 'claim', itemId: 'experiment'}});
16
+ const item = (await api.items.get('research', 'experiment')).item;
17
+ await api.execute('research', {operationId: 'submit', expectedRevision: (await api.boards.get('research')).revision,
18
+ command: {type: 'submit', itemId: item.id, token: item.owner!.token, resultRef: 'lab:evidence'}});
19
+ const delivered = (await api.items.get('research', 'experiment')).item;
20
+ if (delivered.status !== 'completed') throw new Error('Expected a completed item');
21
+ console.log(JSON.stringify({id: delivered.id, status: delivered.status}));
22
+ } finally {await api.dispose(); await manager.dispose();}
package/package.json CHANGED
@@ -1,115 +1,145 @@
1
1
  {
2
2
  "name": "@nestos/kanban",
3
- "version": "0.5.1",
4
- "description": "Portable VFS-backed work coordination and transactional file protocols.",
3
+ "version": "0.5.2",
4
+ "description": "Portable VFS-backed Kanban domain, coordination runtime and contracts.",
5
5
  "type": "module",
6
- "main": "./dist/index.cjs",
7
- "types": "./dist/index.d.ts",
6
+ "main": "./src/index.ts",
7
+ "types": "./src/index.ts",
8
8
  "exports": {
9
- ".": {
10
- "import": {
11
- "types": "./dist/index.d.ts",
12
- "default": "./dist/index.js"
13
- },
14
- "require": {
15
- "types": "./dist/index.d.cts",
16
- "default": "./dist/index.cjs"
17
- }
18
- },
19
- "./contracts": {
20
- "import": {
21
- "types": "./dist/contracts/index.d.ts",
22
- "default": "./dist/contracts/index.js"
23
- },
24
- "require": {
25
- "types": "./dist/contracts/index.d.cts",
26
- "default": "./dist/contracts/index.cjs"
27
- }
28
- },
29
- "./storage": {
30
- "import": {
31
- "types": "./dist/storage.d.ts",
32
- "default": "./dist/storage.js"
33
- },
34
- "require": {
35
- "types": "./dist/storage.d.cts",
36
- "default": "./dist/storage.cjs"
37
- }
38
- },
39
- "./execution": {
40
- "import": {
41
- "types": "./dist/execution.d.ts",
42
- "default": "./dist/execution.js"
43
- },
44
- "require": {
45
- "types": "./dist/execution.d.cts",
46
- "default": "./dist/execution.cjs"
47
- }
48
- },
49
- "./discovery": {
50
- "import": {
51
- "types": "./dist/discovery.d.ts",
52
- "default": "./dist/discovery.js"
53
- },
54
- "require": {
55
- "types": "./dist/discovery.d.cts",
56
- "default": "./dist/discovery.cjs"
57
- }
58
- },
59
- "./ui": {
60
- "import": {
61
- "types": "./dist/ui/index.d.ts",
62
- "default": "./dist/ui/index.js"
63
- },
64
- "require": {
65
- "types": "./dist/ui/index.d.cts",
66
- "default": "./dist/ui/index.cjs"
67
- }
68
- },
69
- "./ui.css": "./dist/ui/kanban.css",
70
- "./activity": {
71
- "import": {
72
- "types": "./dist/activity.d.ts",
73
- "default": "./dist/activity.js"
74
- },
75
- "require": {
76
- "types": "./dist/activity.d.cts",
77
- "default": "./dist/activity.cjs"
78
- }
79
- }
9
+ ".": "./src/index.ts",
10
+ "./contracts": "./src/contracts/index.ts",
11
+ "./storage": "./src/storage.ts",
12
+ "./execution": "./src/execution.ts",
13
+ "./discovery": "./src/discovery-entry.ts",
14
+ "./activity": "./src/activity.ts",
15
+ "./runtime": "./src/runtime/index.ts",
16
+ "./integration": "./src/runtime/integration.ts"
80
17
  },
81
18
  "scripts": {
82
- "build": "tsup",
19
+ "build": "tsup && node scripts/check-package.mjs",
83
20
  "test": "vitest run",
84
21
  "typecheck": "tsc --noEmit",
85
- "example": "tsx examples/standalone.ts"
22
+ "example": "tsx examples/standalone.ts",
23
+ "prepack": "pnpm build",
24
+ "test:package": "node scripts/check-package.mjs"
86
25
  },
87
26
  "peerDependencies": {
88
- "@nestos/vfs-core": "0.5.1"
27
+ "@nestos/vfs-core": "^0.5.1"
89
28
  },
90
29
  "devDependencies": {
91
- "@nestos/vfs-core": "0.5.1",
30
+ "@nestos/vfs-core": "^0.5.1",
92
31
  "typescript": "^5.9.3",
93
32
  "tsup": "^8.5.0",
94
33
  "vitest": "^3.2.4",
95
- "jsdom": "^27.4.0",
96
34
  "tsx": "^4.20.6"
97
35
  },
98
36
  "files": [
99
37
  "dist",
100
38
  "examples"
101
39
  ],
102
- "dependencies": {
103
- "@nestos/ui-common": "0.5.1"
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "main": "./dist/index.cjs",
43
+ "types": "./dist/index.d.ts",
44
+ "exports": {
45
+ ".": {
46
+ "import": {
47
+ "types": "./dist/index.d.ts",
48
+ "default": "./dist/index.js"
49
+ },
50
+ "require": {
51
+ "types": "./dist/index.d.cts",
52
+ "default": "./dist/index.cjs"
53
+ }
54
+ },
55
+ "./contracts": {
56
+ "import": {
57
+ "types": "./dist/contracts/index.d.ts",
58
+ "default": "./dist/contracts/index.js"
59
+ },
60
+ "require": {
61
+ "types": "./dist/contracts/index.d.cts",
62
+ "default": "./dist/contracts/index.cjs"
63
+ }
64
+ },
65
+ "./storage": {
66
+ "import": {
67
+ "types": "./dist/storage.d.ts",
68
+ "default": "./dist/storage.js"
69
+ },
70
+ "require": {
71
+ "types": "./dist/storage.d.cts",
72
+ "default": "./dist/storage.cjs"
73
+ }
74
+ },
75
+ "./execution": {
76
+ "import": {
77
+ "types": "./dist/execution.d.ts",
78
+ "default": "./dist/execution.js"
79
+ },
80
+ "require": {
81
+ "types": "./dist/execution.d.cts",
82
+ "default": "./dist/execution.cjs"
83
+ }
84
+ },
85
+ "./discovery": {
86
+ "import": {
87
+ "types": "./dist/discovery.d.ts",
88
+ "default": "./dist/discovery.js"
89
+ },
90
+ "require": {
91
+ "types": "./dist/discovery.d.cts",
92
+ "default": "./dist/discovery.cjs"
93
+ }
94
+ },
95
+ "./activity": {
96
+ "import": {
97
+ "types": "./dist/activity.d.ts",
98
+ "default": "./dist/activity.js"
99
+ },
100
+ "require": {
101
+ "types": "./dist/activity.d.cts",
102
+ "default": "./dist/activity.cjs"
103
+ }
104
+ },
105
+ "./runtime": {
106
+ "import": {
107
+ "types": "./dist/runtime/index.d.ts",
108
+ "default": "./dist/runtime/index.js"
109
+ },
110
+ "require": {
111
+ "types": "./dist/runtime/index.d.cts",
112
+ "default": "./dist/runtime/index.cjs"
113
+ }
114
+ },
115
+ "./integration": {
116
+ "import": {
117
+ "types": "./dist/runtime/integration.d.ts",
118
+ "default": "./dist/runtime/integration.js"
119
+ },
120
+ "require": {
121
+ "types": "./dist/runtime/integration.d.cts",
122
+ "default": "./dist/runtime/integration.cjs"
123
+ }
124
+ }
125
+ }
104
126
  },
105
127
  "repository": {
106
128
  "type": "git",
107
- "url": "git+https://github.com/nest-agentos/NestOS.git",
108
- "directory": "libraries/kanban"
129
+ "url": "git+https://github.com/nest-agentos/kanban.git"
109
130
  },
110
131
  "bugs": {
111
- "url": "https://github.com/nest-agentos/NestOS/issues"
132
+ "url": "https://github.com/nest-agentos/kanban/issues"
133
+ },
134
+ "homepage": "https://github.com/nest-agentos/kanban#readme",
135
+ "packageManager": "pnpm@10.20.0",
136
+ "license": "SEE LICENSE IN LICENSE",
137
+ "engines": {
138
+ "node": ">=20.19.0"
112
139
  },
113
- "homepage": "https://github.com/nest-agentos/NestOS#readme",
114
- "access": "public"
140
+ "peerDependenciesMeta": {
141
+ "@nestos/vfs-core": {
142
+ "optional": true
143
+ }
144
+ }
115
145
  }