holosphere 2.0.0-alpha0 → 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 (88) hide show
  1. package/LICENSE +162 -38
  2. package/dist/cjs/holosphere.cjs +2 -0
  3. package/dist/cjs/holosphere.cjs.map +1 -0
  4. package/dist/esm/holosphere.js +56 -0
  5. package/dist/esm/holosphere.js.map +1 -0
  6. package/dist/index-CDfIuXew.js +15974 -0
  7. package/dist/index-CDfIuXew.js.map +1 -0
  8. package/dist/index-ifOgtDvd.cjs +3 -0
  9. package/dist/index-ifOgtDvd.cjs.map +1 -0
  10. package/dist/indexeddb-storage-CMW4qRQS.js +96 -0
  11. package/dist/indexeddb-storage-CMW4qRQS.js.map +1 -0
  12. package/dist/indexeddb-storage-DLZOgetM.cjs +2 -0
  13. package/dist/indexeddb-storage-DLZOgetM.cjs.map +1 -0
  14. package/dist/memory-storage-DQzcAZlf.js +47 -0
  15. package/dist/memory-storage-DQzcAZlf.js.map +1 -0
  16. package/dist/memory-storage-DmePEP2q.cjs +2 -0
  17. package/dist/memory-storage-DmePEP2q.cjs.map +1 -0
  18. package/dist/secp256k1-CP0ZkpAx.cjs +13 -0
  19. package/dist/secp256k1-CP0ZkpAx.cjs.map +1 -0
  20. package/dist/secp256k1-vOXp40Fx.js +2281 -0
  21. package/dist/secp256k1-vOXp40Fx.js.map +1 -0
  22. package/docs/FOSDEM_PROPOSAL.md +388 -0
  23. package/docs/LOCALFIRST.md +266 -0
  24. package/docs/contracts/api-interface.md +793 -0
  25. package/docs/data-model.md +476 -0
  26. package/docs/gun-async-usage.md +338 -0
  27. package/docs/plan.md +349 -0
  28. package/docs/quickstart.md +674 -0
  29. package/docs/research.md +362 -0
  30. package/docs/spec.md +244 -0
  31. package/docs/storage-backends.md +326 -0
  32. package/docs/tasks.md +947 -0
  33. package/package.json +1 -1
  34. package/tests/unit/ai/aggregation.test.js +0 -295
  35. package/tests/unit/ai/breakdown.test.js +0 -446
  36. package/tests/unit/ai/classifier.test.js +0 -294
  37. package/tests/unit/ai/council.test.js +0 -262
  38. package/tests/unit/ai/embeddings.test.js +0 -384
  39. package/tests/unit/ai/federation-ai.test.js +0 -344
  40. package/tests/unit/ai/h3-ai.test.js +0 -458
  41. package/tests/unit/ai/index.test.js +0 -304
  42. package/tests/unit/ai/json-ops.test.js +0 -307
  43. package/tests/unit/ai/llm-service.test.js +0 -390
  44. package/tests/unit/ai/nl-query.test.js +0 -383
  45. package/tests/unit/ai/relationships.test.js +0 -311
  46. package/tests/unit/ai/schema-extractor.test.js +0 -384
  47. package/tests/unit/ai/spatial.test.js +0 -279
  48. package/tests/unit/ai/tts.test.js +0 -279
  49. package/tests/unit/content.test.js +0 -332
  50. package/tests/unit/contract/core.test.js +0 -88
  51. package/tests/unit/contract/crypto.test.js +0 -198
  52. package/tests/unit/contract/data.test.js +0 -223
  53. package/tests/unit/contract/federation.test.js +0 -181
  54. package/tests/unit/contract/hierarchical.test.js +0 -113
  55. package/tests/unit/contract/schema.test.js +0 -114
  56. package/tests/unit/contract/social.test.js +0 -217
  57. package/tests/unit/contract/spatial.test.js +0 -110
  58. package/tests/unit/contract/subscriptions.test.js +0 -128
  59. package/tests/unit/contract/utils.test.js +0 -159
  60. package/tests/unit/core.test.js +0 -152
  61. package/tests/unit/crypto.test.js +0 -328
  62. package/tests/unit/federation.test.js +0 -234
  63. package/tests/unit/gun-async.test.js +0 -252
  64. package/tests/unit/hierarchical.test.js +0 -399
  65. package/tests/unit/integration/scenario-01-geographic-storage.test.js +0 -74
  66. package/tests/unit/integration/scenario-02-federation.test.js +0 -76
  67. package/tests/unit/integration/scenario-03-subscriptions.test.js +0 -102
  68. package/tests/unit/integration/scenario-04-validation.test.js +0 -129
  69. package/tests/unit/integration/scenario-05-hierarchy.test.js +0 -125
  70. package/tests/unit/integration/scenario-06-social.test.js +0 -135
  71. package/tests/unit/integration/scenario-07-persistence.test.js +0 -130
  72. package/tests/unit/integration/scenario-08-authorization.test.js +0 -161
  73. package/tests/unit/integration/scenario-09-cross-dimensional.test.js +0 -139
  74. package/tests/unit/integration/scenario-10-cross-holosphere-capabilities.test.js +0 -357
  75. package/tests/unit/integration/scenario-11-cross-holosphere-federation.test.js +0 -410
  76. package/tests/unit/integration/scenario-12-capability-federated-read.test.js +0 -719
  77. package/tests/unit/performance/benchmark.test.js +0 -85
  78. package/tests/unit/schema.test.js +0 -213
  79. package/tests/unit/spatial.test.js +0 -158
  80. package/tests/unit/storage.test.js +0 -195
  81. package/tests/unit/subscriptions.test.js +0 -328
  82. package/tests/unit/test-data-permanence-debug.js +0 -197
  83. package/tests/unit/test-data-permanence.js +0 -340
  84. package/tests/unit/test-key-persistence-fixed.js +0 -148
  85. package/tests/unit/test-key-persistence.js +0 -172
  86. package/tests/unit/test-relay-permanence.js +0 -376
  87. package/tests/unit/test-second-node.js +0 -95
  88. 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
- });