holosphere 2.0.0-alpha1 → 2.0.0-alpha2

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 (87) hide show
  1. package/dist/cjs/holosphere.cjs +2 -0
  2. package/dist/cjs/holosphere.cjs.map +1 -0
  3. package/dist/esm/holosphere.js +56 -0
  4. package/dist/esm/holosphere.js.map +1 -0
  5. package/dist/index-CDfIuXew.js +15974 -0
  6. package/dist/index-CDfIuXew.js.map +1 -0
  7. package/dist/index-ifOgtDvd.cjs +3 -0
  8. package/dist/index-ifOgtDvd.cjs.map +1 -0
  9. package/dist/indexeddb-storage-CMW4qRQS.js +96 -0
  10. package/dist/indexeddb-storage-CMW4qRQS.js.map +1 -0
  11. package/dist/indexeddb-storage-DLZOgetM.cjs +2 -0
  12. package/dist/indexeddb-storage-DLZOgetM.cjs.map +1 -0
  13. package/dist/memory-storage-DQzcAZlf.js +47 -0
  14. package/dist/memory-storage-DQzcAZlf.js.map +1 -0
  15. package/dist/memory-storage-DmePEP2q.cjs +2 -0
  16. package/dist/memory-storage-DmePEP2q.cjs.map +1 -0
  17. package/dist/secp256k1-CP0ZkpAx.cjs +13 -0
  18. package/dist/secp256k1-CP0ZkpAx.cjs.map +1 -0
  19. package/dist/secp256k1-vOXp40Fx.js +2281 -0
  20. package/dist/secp256k1-vOXp40Fx.js.map +1 -0
  21. package/docs/FOSDEM_PROPOSAL.md +388 -0
  22. package/docs/LOCALFIRST.md +266 -0
  23. package/docs/contracts/api-interface.md +793 -0
  24. package/docs/data-model.md +476 -0
  25. package/docs/gun-async-usage.md +338 -0
  26. package/docs/plan.md +349 -0
  27. package/docs/quickstart.md +674 -0
  28. package/docs/research.md +362 -0
  29. package/docs/spec.md +244 -0
  30. package/docs/storage-backends.md +326 -0
  31. package/docs/tasks.md +947 -0
  32. package/package.json +1 -1
  33. package/tests/unit/ai/aggregation.test.js +0 -295
  34. package/tests/unit/ai/breakdown.test.js +0 -446
  35. package/tests/unit/ai/classifier.test.js +0 -294
  36. package/tests/unit/ai/council.test.js +0 -262
  37. package/tests/unit/ai/embeddings.test.js +0 -384
  38. package/tests/unit/ai/federation-ai.test.js +0 -344
  39. package/tests/unit/ai/h3-ai.test.js +0 -458
  40. package/tests/unit/ai/index.test.js +0 -304
  41. package/tests/unit/ai/json-ops.test.js +0 -307
  42. package/tests/unit/ai/llm-service.test.js +0 -390
  43. package/tests/unit/ai/nl-query.test.js +0 -383
  44. package/tests/unit/ai/relationships.test.js +0 -311
  45. package/tests/unit/ai/schema-extractor.test.js +0 -384
  46. package/tests/unit/ai/spatial.test.js +0 -279
  47. package/tests/unit/ai/tts.test.js +0 -279
  48. package/tests/unit/content.test.js +0 -332
  49. package/tests/unit/contract/core.test.js +0 -88
  50. package/tests/unit/contract/crypto.test.js +0 -198
  51. package/tests/unit/contract/data.test.js +0 -223
  52. package/tests/unit/contract/federation.test.js +0 -181
  53. package/tests/unit/contract/hierarchical.test.js +0 -113
  54. package/tests/unit/contract/schema.test.js +0 -114
  55. package/tests/unit/contract/social.test.js +0 -217
  56. package/tests/unit/contract/spatial.test.js +0 -110
  57. package/tests/unit/contract/subscriptions.test.js +0 -128
  58. package/tests/unit/contract/utils.test.js +0 -159
  59. package/tests/unit/core.test.js +0 -152
  60. package/tests/unit/crypto.test.js +0 -328
  61. package/tests/unit/federation.test.js +0 -234
  62. package/tests/unit/gun-async.test.js +0 -252
  63. package/tests/unit/hierarchical.test.js +0 -399
  64. package/tests/unit/integration/scenario-01-geographic-storage.test.js +0 -74
  65. package/tests/unit/integration/scenario-02-federation.test.js +0 -76
  66. package/tests/unit/integration/scenario-03-subscriptions.test.js +0 -102
  67. package/tests/unit/integration/scenario-04-validation.test.js +0 -129
  68. package/tests/unit/integration/scenario-05-hierarchy.test.js +0 -125
  69. package/tests/unit/integration/scenario-06-social.test.js +0 -135
  70. package/tests/unit/integration/scenario-07-persistence.test.js +0 -130
  71. package/tests/unit/integration/scenario-08-authorization.test.js +0 -161
  72. package/tests/unit/integration/scenario-09-cross-dimensional.test.js +0 -139
  73. package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +0 -357
  74. package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +0 -410
  75. package/tests/unit/integration/scenario-12-capability-federated-read.test.js +0 -719
  76. package/tests/unit/performance/benchmark.test.js +0 -85
  77. package/tests/unit/schema.test.js +0 -213
  78. package/tests/unit/spatial.test.js +0 -158
  79. package/tests/unit/storage.test.js +0 -195
  80. package/tests/unit/subscriptions.test.js +0 -328
  81. package/tests/unit/test-data-permanence-debug.js +0 -197
  82. package/tests/unit/test-data-permanence.js +0 -340
  83. package/tests/unit/test-key-persistence-fixed.js +0 -148
  84. package/tests/unit/test-key-persistence.js +0 -172
  85. package/tests/unit/test-relay-permanence.js +0 -376
  86. package/tests/unit/test-second-node.js +0 -95
  87. package/tests/unit/test-simple-write.js +0 -89
@@ -1,446 +0,0 @@
1
- import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import { TaskBreakdown } from '../../../src/ai/breakdown.js';
3
-
4
- describe('Unit: TaskBreakdown', () => {
5
- let breakdown;
6
- let mockLLM;
7
- let mockHolosphere;
8
-
9
- beforeEach(() => {
10
- vi.clearAllMocks();
11
-
12
- mockLLM = {
13
- getJSON: vi.fn()
14
- };
15
-
16
- mockHolosphere = {
17
- getAll: vi.fn().mockResolvedValue([]),
18
- getSchema: vi.fn().mockResolvedValue(null),
19
- write: vi.fn().mockResolvedValue({ success: true }),
20
- update: vi.fn().mockResolvedValue({ success: true })
21
- };
22
-
23
- breakdown = new TaskBreakdown(mockLLM, mockHolosphere);
24
- });
25
-
26
- describe('Constructor', () => {
27
- it('should initialize with LLM service', () => {
28
- const b = new TaskBreakdown(mockLLM);
29
- expect(b.llm).toBe(mockLLM);
30
- expect(b.holosphere).toBeNull();
31
- });
32
-
33
- it('should accept optional HoloSphere instance', () => {
34
- expect(breakdown.holosphere).toBe(mockHolosphere);
35
- });
36
- });
37
-
38
- describe('setHoloSphere', () => {
39
- it('should set HoloSphere instance', () => {
40
- const b = new TaskBreakdown(mockLLM);
41
- b.setHoloSphere(mockHolosphere);
42
- expect(b.holosphere).toBe(mockHolosphere);
43
- });
44
- });
45
-
46
- describe('breakdown', () => {
47
- it('should break down item into subtasks', async () => {
48
- mockLLM.getJSON.mockResolvedValue([
49
- { id: 'task1-1', title: 'Subtask 1', description: 'First step', parent: 'task1', dependencies: [], status: 'pending' },
50
- { id: 'task1-2', title: 'Subtask 2', description: 'Second step', parent: 'task1', dependencies: ['task1-1'], status: 'pending' }
51
- ]);
52
-
53
- const item = { id: 'task1', title: 'Main Task', description: 'Build something' };
54
- const result = await breakdown.breakdown(item, 'holon1', 'tasks');
55
-
56
- expect(result.original).toBe(item);
57
- expect(result.holonId).toBe('holon1');
58
- expect(result.lensName).toBe('tasks');
59
- expect(result.breakdown).toBeDefined();
60
- expect(result.totalSubtasks).toBeGreaterThan(0);
61
- });
62
-
63
- it('should throw error if item has no id', async () => {
64
- await expect(breakdown.breakdown({ title: 'No ID' }, 'holon', 'lens'))
65
- .rejects.toThrow('Item must have an id property');
66
-
67
- await expect(breakdown.breakdown(null, 'holon', 'lens'))
68
- .rejects.toThrow('Item must have an id property');
69
- });
70
-
71
- it('should respect depth option', async () => {
72
- mockLLM.getJSON.mockResolvedValue([
73
- { id: 'task1-1', title: 'Subtask', status: 'pending' }
74
- ]);
75
-
76
- const result = await breakdown.breakdown(
77
- { id: 'task1' },
78
- 'holon',
79
- 'lens',
80
- { depth: 1 }
81
- );
82
-
83
- expect(result.maxDepth).toBe(1);
84
- });
85
-
86
- it('should store subtasks when storeResults is true', async () => {
87
- mockLLM.getJSON.mockResolvedValue([
88
- { id: 'task1-1', title: 'Subtask', status: 'pending' }
89
- ]);
90
-
91
- await breakdown.breakdown(
92
- { id: 'task1' },
93
- 'holon',
94
- 'lens',
95
- { storeResults: true, depth: 1 }
96
- );
97
-
98
- expect(mockHolosphere.write).toHaveBeenCalled();
99
- });
100
-
101
- it('should use context from other items', async () => {
102
- mockHolosphere.getAll.mockResolvedValue([
103
- { id: 'other1', title: 'Other Task' },
104
- { id: 'other2', title: 'Another Task' }
105
- ]);
106
-
107
- mockLLM.getJSON.mockResolvedValue([]);
108
-
109
- await breakdown.breakdown(
110
- { id: 'task1' },
111
- 'holon',
112
- 'lens',
113
- { useContext: true, depth: 1 }
114
- );
115
-
116
- const call = mockLLM.getJSON.mock.calls[0];
117
- expect(call[0]).toContain('context');
118
- });
119
-
120
- it('should normalize stepsPerLevel number to object', async () => {
121
- mockLLM.getJSON.mockResolvedValue([]);
122
-
123
- await breakdown.breakdown(
124
- { id: 'task1' },
125
- 'holon',
126
- 'lens',
127
- { stepsPerLevel: 5, depth: 1 }
128
- );
129
-
130
- const call = mockLLM.getJSON.mock.calls[0];
131
- expect(call[0]).toContain('5');
132
- });
133
- });
134
-
135
- describe('_generateSubtasks', () => {
136
- it('should generate subtasks with proper structure', async () => {
137
- mockLLM.getJSON.mockResolvedValue([
138
- { id: 'p-1', title: 'Step 1', description: 'Do step 1', parent: 'parent', dependencies: [], status: 'pending' },
139
- { id: 'p-2', title: 'Step 2', description: 'Do step 2', parent: 'parent', dependencies: ['p-1'], status: 'pending' }
140
- ]);
141
-
142
- const parent = { id: 'parent', title: 'Parent Task' };
143
- const result = await breakdown._generateSubtasks(
144
- parent,
145
- [],
146
- null,
147
- { min: 2, max: 4 },
148
- 'dependencies',
149
- 'parent'
150
- );
151
-
152
- expect(result).toHaveLength(2);
153
- expect(result[0].parent).toBe('parent');
154
- expect(result[0]._meta.generatedFrom).toBe('parent');
155
- });
156
-
157
- it('should handle LLM errors gracefully', async () => {
158
- mockLLM.getJSON.mockRejectedValue(new Error('API Error'));
159
-
160
- const result = await breakdown._generateSubtasks(
161
- { id: 'parent' },
162
- [],
163
- null,
164
- { min: 3, max: 5 },
165
- 'dependencies',
166
- 'parent'
167
- );
168
-
169
- expect(result).toEqual([]);
170
- });
171
-
172
- it('should ensure all subtasks have required fields', async () => {
173
- mockLLM.getJSON.mockResolvedValue([
174
- { title: 'Missing ID and status' }
175
- ]);
176
-
177
- const result = await breakdown._generateSubtasks(
178
- { id: 'parent' },
179
- [],
180
- null,
181
- { min: 1, max: 1 },
182
- 'dependencies',
183
- 'parent'
184
- );
185
-
186
- expect(result[0].id).toBeDefined();
187
- expect(result[0].parent).toBe('parent');
188
- expect(result[0].status).toBe('pending');
189
- });
190
- });
191
-
192
- describe('_countSubtasks', () => {
193
- it('should count all subtasks in tree', () => {
194
- const tree = {
195
- item: { id: 'root' },
196
- children: [
197
- {
198
- item: { id: 'c1' },
199
- children: [
200
- { item: { id: 'c1-1' }, children: [] },
201
- { item: { id: 'c1-2' }, children: [] }
202
- ]
203
- },
204
- {
205
- item: { id: 'c2' },
206
- children: []
207
- }
208
- ]
209
- };
210
-
211
- expect(breakdown._countSubtasks(tree)).toBe(4);
212
- });
213
-
214
- it('should return 0 for node without children', () => {
215
- const tree = { item: { id: 'leaf' }, children: [] };
216
- expect(breakdown._countSubtasks(tree)).toBe(0);
217
- });
218
- });
219
-
220
- describe('flatten', () => {
221
- it('should flatten breakdown tree into list', () => {
222
- const breakdownResult = {
223
- breakdown: {
224
- item: { id: 'root' },
225
- children: [
226
- { item: { id: 'c1' }, children: [] },
227
- { item: { id: 'c2' }, children: [] }
228
- ]
229
- }
230
- };
231
-
232
- const flat = breakdown.flatten(breakdownResult);
233
-
234
- expect(flat).toHaveLength(3);
235
- expect(flat.map(i => i.id)).toContain('root');
236
- expect(flat.map(i => i.id)).toContain('c1');
237
- expect(flat.map(i => i.id)).toContain('c2');
238
- });
239
-
240
- it('should handle empty breakdown', () => {
241
- const flat = breakdown.flatten({});
242
- expect(flat).toEqual([]);
243
- });
244
- });
245
-
246
- describe('getDependencyOrder', () => {
247
- it('should order items by depth and dependencies', () => {
248
- const breakdownResult = {
249
- breakdown: {
250
- item: { id: 'root', _meta: { depth: 0 } },
251
- children: [
252
- { item: { id: 'c1', _meta: { depth: 1 }, dependencies: [] }, children: [] },
253
- { item: { id: 'c2', _meta: { depth: 1 }, dependencies: ['c1'] }, children: [] }
254
- ]
255
- }
256
- };
257
-
258
- const ordered = breakdown.getDependencyOrder(breakdownResult);
259
-
260
- const c1Index = ordered.findIndex(i => i.id === 'c1');
261
- const c2Index = ordered.findIndex(i => i.id === 'c2');
262
- expect(c1Index).toBeLessThan(c2Index);
263
- });
264
- });
265
-
266
- describe('suggestStrategy', () => {
267
- it('should suggest breakdown strategy', async () => {
268
- mockLLM.getJSON.mockResolvedValue({
269
- complexity: 'complex',
270
- recommendedDepth: 3,
271
- recommendedStepsPerLevel: { min: 3, max: 5 },
272
- focusAreas: ['Planning', 'Implementation'],
273
- potentialChallenges: ['Resource constraints'],
274
- estimatedTotalSubtasks: 15,
275
- reasoning: 'Complex project needs thorough breakdown'
276
- });
277
-
278
- const item = { id: 'project1', title: 'Big Project', description: 'Complex undertaking' };
279
- const result = await breakdown.suggestStrategy(item);
280
-
281
- expect(result.complexity).toBe('complex');
282
- expect(result.recommendedDepth).toBe(3);
283
- expect(result.focusAreas).toContain('Planning');
284
- });
285
- });
286
-
287
- describe('rebalance', () => {
288
- it('should rebalance breakdown tree', async () => {
289
- mockLLM.getJSON.mockResolvedValue({
290
- tasks: [
291
- { id: 'new1', title: 'Merged Task' },
292
- { id: 'new2', title: 'Split Task A' },
293
- { id: 'new3', title: 'Split Task B' }
294
- ],
295
- changes: [
296
- { type: 'merge', description: 'Merged granular tasks' },
297
- { type: 'split', description: 'Split large task' }
298
- ],
299
- summary: 'Rebalanced for 3-5 items per level'
300
- });
301
-
302
- const breakdownResult = {
303
- breakdown: {
304
- item: { id: 'root' },
305
- children: [
306
- { item: { id: 'c1' }, children: [] }
307
- ]
308
- }
309
- };
310
-
311
- const result = await breakdown.rebalance(breakdownResult);
312
-
313
- expect(result.tasks).toHaveLength(3);
314
- expect(result.changes).toHaveLength(2);
315
- });
316
- });
317
-
318
- describe('getProgress', () => {
319
- it('should calculate progress on breakdown tree', async () => {
320
- mockHolosphere.getAll.mockResolvedValue([
321
- { id: 'root', title: 'Main Task', status: 'in_progress' },
322
- { id: 'c1', title: 'Subtask 1', parent: 'root', status: 'completed' },
323
- { id: 'c2', title: 'Subtask 2', parent: 'root', status: 'pending' },
324
- { id: 'c3', title: 'Subtask 3', parent: 'root', status: 'in_progress', dependencies: ['c1'] }
325
- ]);
326
-
327
- const result = await breakdown.getProgress('holon', 'lens', 'root');
328
-
329
- expect(result.itemId).toBe('root');
330
- expect(result.total).toBe(3);
331
- expect(result.completed).toBe(1);
332
- expect(result.inProgress).toBe(1);
333
- expect(result.pending).toBe(1);
334
- expect(result.percentComplete).toBe(33);
335
- });
336
-
337
- it('should throw error if HoloSphere not available', async () => {
338
- const b = new TaskBreakdown(mockLLM);
339
-
340
- await expect(b.getProgress('holon', 'lens', 'id'))
341
- .rejects.toThrow('HoloSphere instance required');
342
- });
343
-
344
- it('should throw error if item not found', async () => {
345
- mockHolosphere.getAll.mockResolvedValue([]);
346
-
347
- await expect(breakdown.getProgress('holon', 'lens', 'nonexistent'))
348
- .rejects.toThrow('Item nonexistent not found');
349
- });
350
-
351
- it('should find blockers', async () => {
352
- mockHolosphere.getAll.mockResolvedValue([
353
- { id: 'root', title: 'Main', status: 'pending' },
354
- { id: 'c1', title: 'Blocker', parent: 'root', status: 'pending' },
355
- { id: 'c2', title: 'Blocked', parent: 'root', status: 'pending', dependencies: ['c1'] }
356
- ]);
357
-
358
- const result = await breakdown.getProgress('holon', 'lens', 'root');
359
-
360
- expect(result.blockers).toHaveLength(1);
361
- expect(result.blockers[0].id).toBe('c2');
362
- });
363
-
364
- it('should find next tasks ready to work on', async () => {
365
- mockHolosphere.getAll.mockResolvedValue([
366
- { id: 'root', title: 'Main', status: 'pending' },
367
- { id: 'c1', title: 'Ready', parent: 'root', status: 'pending', dependencies: [] },
368
- { id: 'c2', title: 'Also Ready', parent: 'root', status: 'pending' }
369
- ]);
370
-
371
- const result = await breakdown.getProgress('holon', 'lens', 'root');
372
-
373
- expect(result.nextUp.length).toBeGreaterThan(0);
374
- expect(result.nextUp.map(t => t.id)).toContain('c1');
375
- });
376
- });
377
-
378
- describe('_findDescendants', () => {
379
- it('should find all descendants', () => {
380
- const items = [
381
- { id: 'c1', parent: 'root' },
382
- { id: 'c2', parent: 'root' },
383
- { id: 'c1-1', parent: 'c1' },
384
- { id: 'other', parent: 'different' }
385
- ];
386
-
387
- const descendants = breakdown._findDescendants('root', items);
388
-
389
- expect(descendants).toHaveLength(3);
390
- expect(descendants.map(d => d.id)).toContain('c1');
391
- expect(descendants.map(d => d.id)).toContain('c1-1');
392
- });
393
- });
394
-
395
- describe('_findBlockers', () => {
396
- it('should find blocked tasks', () => {
397
- const items = [
398
- { id: 'c1', status: 'pending' },
399
- { id: 'c2', status: 'pending', dependencies: ['c1'] }
400
- ];
401
-
402
- const blockers = breakdown._findBlockers(items);
403
-
404
- expect(blockers).toHaveLength(1);
405
- expect(blockers[0].id).toBe('c2');
406
- });
407
-
408
- it('should not include tasks with completed dependencies', () => {
409
- const items = [
410
- { id: 'c1', status: 'completed' },
411
- { id: 'c2', status: 'pending', dependencies: ['c1'] }
412
- ];
413
-
414
- const blockers = breakdown._findBlockers(items);
415
-
416
- expect(blockers).toHaveLength(0);
417
- });
418
- });
419
-
420
- describe('_findNextTasks', () => {
421
- it('should find tasks ready to start', () => {
422
- const items = [
423
- { id: 'c1', status: 'pending' },
424
- { id: 'c2', status: 'pending', dependencies: ['c1'] }
425
- ];
426
-
427
- const next = breakdown._findNextTasks(items);
428
-
429
- expect(next).toHaveLength(1);
430
- expect(next[0].id).toBe('c1');
431
- });
432
-
433
- it('should exclude completed and in-progress tasks', () => {
434
- const items = [
435
- { id: 'c1', status: 'completed' },
436
- { id: 'c2', status: 'in_progress' },
437
- { id: 'c3', status: 'pending' }
438
- ];
439
-
440
- const next = breakdown._findNextTasks(items);
441
-
442
- expect(next.map(t => t.id)).not.toContain('c1');
443
- expect(next.map(t => t.id)).not.toContain('c2');
444
- });
445
- });
446
- });