@dotbep/core 0.2.7 → 0.2.8

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 (77) hide show
  1. package/dist/index.d.ts +7 -5
  2. package/dist/index.js +604 -596
  3. package/package.json +4 -1
  4. package/examples/01-participants.ts +0 -127
  5. package/examples/02-files.ts +0 -100
  6. package/examples/03-workflows.ts +0 -149
  7. package/examples/04-bim-uses.ts +0 -70
  8. package/examples/05-standards.ts +0 -60
  9. package/examples/06-schedule.ts +0 -124
  10. package/examples/07-loin.ts +0 -133
  11. package/examples/08-deliverables.ts +0 -126
  12. package/examples/09-notes.ts +0 -73
  13. package/examples/10-llm.ts +0 -109
  14. package/examples/11-resolved.ts +0 -133
  15. package/examples/12-history.ts +0 -166
  16. package/examples/13-engine.ts +0 -152
  17. package/examples/bep.d.ts +0 -38
  18. package/examples/example.bep +0 -0
  19. package/examples/run-all.ts +0 -38
  20. package/src/base/entity.ts +0 -148
  21. package/src/base/history.ts +0 -497
  22. package/src/base/index.ts +0 -5
  23. package/src/base/singleton.ts +0 -26
  24. package/src/entities/actions.ts +0 -25
  25. package/src/entities/adapters.ts +0 -16
  26. package/src/entities/annexes.ts +0 -17
  27. package/src/entities/assetTypes.ts +0 -30
  28. package/src/entities/automations.ts +0 -24
  29. package/src/entities/bimUses.ts +0 -50
  30. package/src/entities/deliverables.ts +0 -66
  31. package/src/entities/disciplines.ts +0 -21
  32. package/src/entities/effects.ts +0 -28
  33. package/src/entities/env.ts +0 -17
  34. package/src/entities/events.ts +0 -24
  35. package/src/entities/extensions.ts +0 -16
  36. package/src/entities/flags.ts +0 -17
  37. package/src/entities/guides.ts +0 -26
  38. package/src/entities/index.ts +0 -32
  39. package/src/entities/lbsNodes.ts +0 -193
  40. package/src/entities/lods.ts +0 -22
  41. package/src/entities/loin.ts +0 -127
  42. package/src/entities/lois.ts +0 -22
  43. package/src/entities/members.ts +0 -137
  44. package/src/entities/milestones.ts +0 -32
  45. package/src/entities/notes.ts +0 -27
  46. package/src/entities/objectives.ts +0 -17
  47. package/src/entities/phases.ts +0 -17
  48. package/src/entities/remoteData.ts +0 -17
  49. package/src/entities/resolvers.ts +0 -20
  50. package/src/entities/roles.ts +0 -29
  51. package/src/entities/softwares.ts +0 -26
  52. package/src/entities/standards.ts +0 -68
  53. package/src/entities/teams.ts +0 -42
  54. package/src/entities/workflows.ts +0 -256
  55. package/src/index.ts +0 -464
  56. package/src/runtime/Engine.ts +0 -352
  57. package/src/runtime/MemoryStorage.ts +0 -31
  58. package/src/runtime/Runtime.ts +0 -106
  59. package/src/runtime/index.ts +0 -4
  60. package/src/runtime/transitions.ts +0 -456
  61. package/src/runtime/types.ts +0 -279
  62. package/src/types/history.ts +0 -37
  63. package/src/types/index.ts +0 -24
  64. package/src/types/resolved.ts +0 -137
  65. package/src/types/schema.ts +0 -757
  66. package/src/utils/diff.ts +0 -109
  67. package/src/utils/index.ts +0 -9
  68. package/src/utils/integrity.ts +0 -108
  69. package/src/utils/lbs.ts +0 -116
  70. package/src/utils/mermaid.ts +0 -110
  71. package/src/utils/naming.ts +0 -62
  72. package/src/utils/nomenclature.ts +0 -107
  73. package/src/utils/normalize.ts +0 -35
  74. package/src/utils/raci.ts +0 -25
  75. package/src/utils/textFile.ts +0 -24
  76. package/tsconfig.json +0 -12
  77. package/vite.config.ts +0 -24
@@ -1,133 +0,0 @@
1
- // part of: node --experimental-strip-types examples/run-all.ts (use --07 to stop here)
2
- //
3
- // Covers: lods, lois, loin.
4
- //
5
- // The LOIN section defines the Level of Information Need — what must be known
6
- // about each model element at each milestone. It is the core of an ISO 19650
7
- // information requirements framework.
8
- //
9
- // LOD (Level of Development) — geometric completeness of a model element.
10
- // LOI (Level of Information) — richness of the non-geometric data attached to it.
11
- // LOIN — the per-element table that maps (element × milestone) → (LOD, LOI).
12
- //
13
- // LOD and LOI ids are numeric strings ('100', '200', …). They are readable
14
- // codes, not UUIDs — the user chooses them to match the project's convention.
15
-
16
- import { readFileSync, writeFileSync } from 'node:fs'
17
- import { Bep } from '../dist/index.js'
18
-
19
- const bep = await Bep.open(readFileSync('examples/example.bep'))
20
-
21
- const m1Id = bep.milestones.list().find(m => m.name === 'Design Delivery')!.id
22
- const m2Id = bep.milestones.list().find(m => m.name === 'Construction Delivery')!.id
23
-
24
- // ─── LODs ─────────────────────────────────────────────────────────────────────
25
-
26
- // LOD levels are defined once and reused across all LOIN entries. Each level
27
- // can carry a checklist that the frontend renders as acceptance criteria.
28
- // The id is a string (not a number) so that it participates in the same
29
- // get/update/remove API as all other entities.
30
-
31
- console.log('=== lods ===')
32
-
33
- const lodsAdded = bep.lods.add([
34
- { id: '100', name: 'LOD 100', checklist: ['Conceptual massing present' ] },
35
- { id: '200', name: 'LOD 200' },
36
- { id: '300', name: 'LOD 300', checklist: ['All geometry defined', 'Dimensions accurate' ] },
37
- { id: '350', name: 'LOD 350', checklist: ['Connections and interfaces defined' ] },
38
- { id: '100', name: 'Duplicate' }, // fails
39
- ])
40
- console.log('add succeeded:', lodsAdded.succeeded.map(l => l.id))
41
- console.log('add failed: ', lodsAdded.failed)
42
-
43
- const gotLod = bep.lods.get(['100', '999'])
44
- console.log('\nget 100:', gotLod.succeeded[0].name)
45
- console.log('get 999 (failed):', gotLod.failed)
46
-
47
- bep.lods.update([
48
- { id: '100', name: 'LOD 100 — Conceptual' },
49
- { id: '999', name: 'Ghost' }, // fails
50
- ])
51
-
52
- // ─── LOIs ─────────────────────────────────────────────────────────────────────
53
-
54
- // LOI levels follow the same pattern as LODs — numeric string ids, optional
55
- // checklists. LOI 1 might require only a classification code; LOI 3 might
56
- // require a full property set with IFC links. The checklists make those
57
- // expectations explicit and auditable.
58
-
59
- console.log('\n=== lois ===')
60
-
61
- const loisAdded = bep.lois.add([
62
- { id: '1', name: 'LOI 1' },
63
- { id: '2', name: 'LOI 2', checklist: ['Classification assigned', 'Material specified' ] },
64
- { id: '3', name: 'LOI 3', checklist: ['Full property set defined', 'IFC classification linked' ] },
65
- { id: '1', name: 'Duplicate' }, // fails
66
- ])
67
- console.log('add succeeded:', loisAdded.succeeded.map(l => l.id))
68
- console.log('add failed: ', loisAdded.failed)
69
-
70
- // ─── LOIN ─────────────────────────────────────────────────────────────────────
71
-
72
- // A LOIN entry describes one model element type (e.g. "Walls") and its
73
- // information requirements across milestones. Each entry maps a discipline to
74
- // a list of (milestone → LOD + LOI) pairs.
75
- //
76
- // Every reference — discipline, milestone, LOD, LOI — is validated on add.
77
- // A single bad reference fails the entire LOIN entry, not just that milestone.
78
-
79
- console.log('\n=== loin ===')
80
-
81
- const loinAdded = bep.loin.add([
82
- {
83
- element: 'Walls',
84
- disciplineId: 'ARQ',
85
- milestones: [
86
- { milestoneId: m1Id, lodId: '300', loiId: '2' },
87
- { milestoneId: m2Id, lodId: '350', loiId: '3' },
88
- ],
89
- },
90
- {
91
- element: 'Slabs',
92
- disciplineId: 'EST',
93
- milestones: [
94
- { milestoneId: m1Id, lodId: '200', loiId: '1' },
95
- { milestoneId: m2Id, lodId: '300', loiId: '2' },
96
- ],
97
- },
98
- // integrity failures —
99
- { element: 'Bad discipline', disciplineId: 'ghost-disc' }, // fails
100
- { element: 'Bad milestone', disciplineId: 'ARQ', milestones: [{ milestoneId: 'ghost', lodId: '100', loiId: '1' }] }, // fails
101
- { element: 'Bad LOD', disciplineId: 'ARQ', milestones: [{ milestoneId: m1Id, lodId: '999', loiId: '1' }] }, // fails
102
- { element: 'Bad LOI', disciplineId: 'ARQ', milestones: [{ milestoneId: m1Id, lodId: '100', loiId: '99' }] }, // fails
103
- ])
104
- const loinWallsId = loinAdded.succeeded[0].id
105
- const loinSlabsId = loinAdded.succeeded[1].id
106
- console.log('add succeeded:', loinAdded.succeeded.map(l => l.element))
107
- console.log('add failed: ', loinAdded.failed)
108
-
109
- console.log('\n--- integrity: entities referenced by LOIN cannot be removed ---')
110
- console.log('remove ARQ (discipline):', bep.disciplines.remove(['ARQ']).failed)
111
- console.log('remove m1 (milestone): ', bep.milestones.remove([m1Id]).failed)
112
- console.log('remove 300 (lod): ', bep.lods.remove(['300']).failed)
113
- console.log('remove LOI 2: ', bep.lois.remove(['2']).failed)
114
-
115
- // remove works when the LOIN entry itself is deleted first
116
- const loinRemoved = bep.loin.remove([loinSlabsId, 'ghost-loin'])
117
- console.log('\nremove Slabs LOIN succeeded:', loinRemoved.succeeded)
118
- console.log('remove ghost failed: ', loinRemoved.failed)
119
-
120
- // re-add Slabs so the complete BEP carries it forward
121
- bep.loin.add([{
122
- element: 'Slabs',
123
- disciplineId: 'EST',
124
- milestones: [
125
- { milestoneId: m1Id, lodId: '200', loiId: '1' },
126
- { milestoneId: m2Id, lodId: '300', loiId: '2' },
127
- ],
128
- }])
129
-
130
- // ─── Save ─────────────────────────────────────────────────────────────────────
131
-
132
- writeFileSync('examples/example.bep', await bep.save())
133
- console.log('\nSaved → examples/example.bep')
@@ -1,126 +0,0 @@
1
- // part of: node --experimental-strip-types examples/run-all.ts (use --08 to stop here)
2
- //
3
- // Covers: deliverables, nomenclature.
4
- //
5
- // Deliverables are the actual files that teams must produce and exchange.
6
- // They are the most cross-referenced entity in the BEP — each one ties together
7
- // a discipline, a document type, a set of extensions, a responsible team, a
8
- // milestone, and optionally an LBS location and a predecessor deliverable.
9
- //
10
- // Nomenclature derives a human-readable naming code from those references:
11
- // {project.code}-{team.id}-{zoneCode}-{locationCode}-{assetType.id}-{disc.id}-{NNN}
12
- // NNN is a global sequence counter across all deliverables, zero-padded to three digits.
13
-
14
- import { readFileSync, writeFileSync } from 'node:fs'
15
- import { Bep, buildCodeMap } from '../dist/index.js'
16
-
17
- const bep = await Bep.open(readFileSync('examples/example.bep'))
18
-
19
- const m1Id = bep.milestones.list().find(m => m.name === 'Design Delivery')!.id
20
- const m2Id = bep.milestones.list().find(m => m.name === 'Construction Delivery')!.id
21
-
22
- // ─── Deliverables ─────────────────────────────────────────────────────────────
23
-
24
- // Every reference field is validated on add. A deliverable with a ghost
25
- // disciplineId, assetTypeId, extensionId, responsibleId, milestoneId, or
26
- // lbsNodeId fails individually — other deliverables in the same batch proceed.
27
- // predecessorId is set via update() after both IDs are known.
28
-
29
- console.log('=== deliverables ===')
30
-
31
- const delAdded = bep.deliverables.add([
32
- {
33
- description: 'Architectural Model — Floor 1',
34
- disciplineId: 'ARQ',
35
- assetTypeId: 'M3D',
36
- extensionIds: ['ifc', 'rvt'],
37
- responsibleId: 'ARC',
38
- milestoneId: m1Id,
39
- lbsNodeId: 'P01',
40
- },
41
- {
42
- description: 'Architectural Model — Floor 2',
43
- disciplineId: 'ARQ',
44
- assetTypeId: 'M3D',
45
- extensionIds: ['ifc', 'rvt'],
46
- responsibleId: 'ARC',
47
- milestoneId: m1Id,
48
- lbsNodeId: 'P02',
49
- },
50
- {
51
- description: 'Structural Model — Floor 1',
52
- disciplineId: 'EST',
53
- assetTypeId: 'M3D',
54
- responsibleId: 'ARC',
55
- milestoneId: m2Id,
56
- lbsNodeId: 'P01',
57
- // predecessorId set after d1 is known
58
- },
59
- // integrity failures —
60
- { description: 'Bad discipline', disciplineId: 'ghost-disc', assetTypeId: 'M3D', responsibleId: 'ARC', milestoneId: m1Id },
61
- { description: 'Bad assetType', disciplineId: 'ARQ', assetTypeId: 'ghost-dt', responsibleId: 'ARC', milestoneId: m1Id },
62
- { description: 'Bad extension', disciplineId: 'ARQ', assetTypeId: 'M3D', extensionIds: ['ghost-ext'], responsibleId: 'ARC', milestoneId: m1Id },
63
- { description: 'Bad team', disciplineId: 'ARQ', assetTypeId: 'M3D', responsibleId: 'ghost-team', milestoneId: m1Id },
64
- { description: 'Bad milestone', disciplineId: 'ARQ', assetTypeId: 'M3D', responsibleId: 'ARC', milestoneId: 'ghost-ms' },
65
- { description: 'Bad lbsNode', disciplineId: 'ARQ', assetTypeId: 'M3D', responsibleId: 'ARC', milestoneId: m1Id, lbsNodeId: 'ghost-node' },
66
- ])
67
- const d1 = delAdded.succeeded[0].id
68
- const d2 = delAdded.succeeded[1].id
69
- const d3 = delAdded.succeeded[2].id
70
- console.log('add succeeded:', delAdded.succeeded.map(d => d.description))
71
- console.log('add failed: ', delAdded.failed)
72
-
73
- // set predecessor now that both IDs are known
74
- bep.deliverables.update([{ id: d3, predecessorId: d1 }])
75
-
76
- console.log('\n--- integrity: predecessor blocks removal of the referenced deliverable ---')
77
- const d1Blocked = bep.deliverables.remove([d1])
78
- console.log('remove d1 (blocked by d3.predecessorId):', d1Blocked.failed)
79
-
80
- console.log('\n--- integrity: entities referenced by deliverables cannot be removed ---')
81
- console.log('remove ARQ (discipline):', bep.disciplines.remove(['ARQ']).failed)
82
- console.log('remove M3D (assetType): ', bep.assetTypes.remove(['M3D']).failed)
83
- console.log('remove m1 (milestone): ', bep.milestones.remove([m1Id]).failed)
84
- console.log('remove ARC (team): ', bep.teams.remove(['ARC']).failed)
85
- console.log('remove P01 (lbsNode): ', bep.lbsNodes.remove(['P01']).failed)
86
-
87
- // ─── Nomenclature ─────────────────────────────────────────────────────────────
88
-
89
- // buildCodeMap() computes naming codes for all deliverables in one pass.
90
- // LBS resolution: P01 is a child of BLK → zoneCode=BLK, locationCode=P01.
91
- // P02 is also a child of BLK → same zone, different location.
92
- // NNN is a global zero-padded sequence, so d1→001, d2→002, d3→003.
93
- //
94
- // getCode() is a single-deliverable shortcut that internally calls buildCodeMap.
95
- // buildConsecutivoMap() returns the raw integer sequence numbers before zero-padding.
96
- // The standalone buildCodeMap import is useful when BEP data comes from outside
97
- // the Bep class (e.g. from a raw JSON snapshot).
98
- const codeMap = bep.nomenclature.buildCodeMap()
99
- console.log('code map:')
100
- for (const [id, code] of codeMap) {
101
- console.log(' ', id.slice(0, 8), '→', code)
102
- }
103
- // d1 → EXP-ARC-BLK-P01-M3D-ARQ-001
104
- // d2 → EXP-ARC-BLK-P02-M3D-ARQ-001 (different location → new NNN sequence)
105
- // d3 → EXP-ARC-BLK-P01-M3D-EST-001
106
-
107
- // getCode: single deliverable by id
108
- console.log('\nd1 code:', bep.nomenclature.getCode(d1))
109
- console.log('d2 code:', bep.nomenclature.getCode(d2))
110
- console.log('d3 code:', bep.nomenclature.getCode(d3))
111
- console.log('ghost: ', bep.nomenclature.getCode('ghost-id')) // null
112
-
113
- // buildConsecutivoMap: raw sequence numbers per deliverable (before zero-padding)
114
- const seqMap = bep.nomenclature.buildConsecutivoMap()
115
- console.log('seq d1:', seqMap.get(d1)) // 1
116
- console.log('seq d2:', seqMap.get(d2)) // 1 (different location → independent sequence)
117
- console.log('seq d3:', seqMap.get(d3)) // 1
118
-
119
- // standalone buildCodeMap — useful when BEP data comes from an external source
120
- const externalMap = buildCodeMap(bep.data.deliverables, bep.data.project.code, bep.data.lbs)
121
- console.log('\nexternal buildCodeMap matches:', [...externalMap.values()].join(', '))
122
-
123
- // ─── Save ─────────────────────────────────────────────────────────────────────
124
-
125
- writeFileSync('examples/example.bep', await bep.save())
126
- console.log('\nSaved → examples/example.bep')
@@ -1,73 +0,0 @@
1
- // part of: node --experimental-strip-types examples/run-all.ts (use --09 to stop here)
2
- //
3
- // Covers: notes.
4
- //
5
- // Notes are the human layer of the BEP — annotations written by team members
6
- // to record decisions, concerns, or confirmations that do not fit into the
7
- // structured data. They are identified by the author's email, which must
8
- // reference an existing member of the BEP.
9
- //
10
- // Because notes are authored by members, removing a member who has authored
11
- // notes is blocked by referential integrity. The constraint is released only
12
- // when the note itself is deleted first.
13
-
14
- import { readFileSync, writeFileSync } from 'node:fs'
15
- import { Bep } from '../dist/index.js'
16
-
17
- const bep = await Bep.open(readFileSync('examples/example.bep'))
18
-
19
- // ─── Notes ────────────────────────────────────────────────────────────────────
20
-
21
- // Notes are authored by members (identified by email) and carry a free-text
22
- // message and a creation timestamp. The memberEmail must reference a member
23
- // already registered in the BEP — unknown authors are rejected individually.
24
-
25
- console.log('=== notes ===')
26
-
27
- // notes are human annotations authored by BEP members (identified by email)
28
- const notesAdded = bep.notes.add([
29
- {
30
- message: 'LOD 300 definition confirmed with client in meeting of 2026-03-15.',
31
- memberEmail: 'alice@arc.com',
32
- createdAt: '2026-03-15T10:00:00Z',
33
- },
34
- {
35
- message: 'Structure team has not confirmed milestone M2 date yet.',
36
- memberEmail: 'bob@arc.com',
37
- createdAt: '2026-03-16T09:00:00Z',
38
- },
39
- {
40
- message: 'Bad author.',
41
- memberEmail: 'ghost@x.com', // fails — not a registered member
42
- createdAt: '2026-03-16T09:00:00Z',
43
- },
44
- ])
45
- const n1Id = notesAdded.succeeded[0].id
46
- const n2Id = notesAdded.succeeded[1].id
47
- console.log('add succeeded:', notesAdded.succeeded.map(n => n.message.slice(0, 50)))
48
- console.log('add failed: ', notesAdded.failed)
49
-
50
- // sparse update — only message or other fields can be patched
51
- const notesUpdated = bep.notes.update([
52
- { id: n2Id, message: 'Structure team confirmed: M2 date is 2027-03-31.' },
53
- { id: 'ghost-id', message: 'Ghost' }, // fails — id not found
54
- ])
55
- console.log('\nupdate succeeded:', notesUpdated.succeeded.map(n => n.message.slice(0, 50)))
56
- console.log('update failed: ', notesUpdated.failed)
57
-
58
- console.log('\n--- integrity: member with authored notes cannot be removed ---')
59
- const aliceBlocked = bep.members.remove(['alice@arc.com'])
60
- console.log('remove alice (blocked by note.memberEmail):', aliceBlocked.failed)
61
-
62
- // removing the note frees the member constraint for that note
63
- const noteRemoved = bep.notes.remove([n1Id, 'ghost-note'])
64
- console.log('\nremove n1 succeeded:', noteRemoved.succeeded)
65
- console.log('remove ghost failed: ', noteRemoved.failed)
66
-
67
- // alice can now be removed (her only note was n1Id, which was just deleted)
68
- // — not doing it here to keep alice in the BEP for subsequent examples
69
-
70
- // ─── Save ─────────────────────────────────────────────────────────────────────
71
-
72
- writeFileSync('examples/example.bep', await bep.save())
73
- console.log('\nSaved → examples/example.bep')
@@ -1,109 +0,0 @@
1
- // part of: node --experimental-strip-types examples/run-all.ts (use --10 to stop here)
2
- //
3
- // Covers: flags, memory, skill.
4
- //
5
- // These three entities are the LLM's layer of the BEP — they are written by
6
- // the agent, not by the BIM Manager directly.
7
- //
8
- // Flags — observations generated after analyze_bep. Each flag points to an
9
- // entity (or to the whole BEP) and carries a severity level. Flags
10
- // are transient: they are cleared and regenerated on each analysis.
11
- //
12
- // Memory — a single markdown string the LLM writes to persist context across
13
- // sessions: confirmed decisions, acknowledged flags, client constraints.
14
- // The caller owns the full string — there is no append API.
15
- //
16
- // Skill — instructions authored by the BIM Manager that tell the LLM how to
17
- // behave in this specific BEP (terminology, tone, LOD conventions).
18
- // Skill can be copied from a template BEP to seed a new project.
19
-
20
- import { readFileSync, writeFileSync } from 'node:fs'
21
- import { Bep } from '../dist/index.js'
22
-
23
- const bep = await Bep.open(readFileSync('examples/example.bep'))
24
-
25
- const d1 = bep.deliverables.list().find(d => d.description === 'Architectural Model — Floor 1')!.id
26
-
27
- // ─── Flags ────────────────────────────────────────────────────────────────────
28
-
29
- // Flags point to specific entities (or to the whole BEP when entityId is null)
30
- // and communicate issues the LLM detected during analysis. Once a flag is
31
- // knowingly accepted, it should be removed and the decision documented in memory
32
- // so it is not re-reported in a future session.
33
-
34
- console.log('=== flags ===')
35
-
36
- // Flags are generated by the LLM after analyze_bep — not authored by users.
37
- // entity / entityId point to what the flag refers to; null means the whole BEP.
38
- const flagsAdded = bep.flags.add([
39
- {
40
- entity: 'deliverables',
41
- entityId: d1,
42
- severity: 'warning',
43
- message: 'Deliverable has no dueDate and the milestone date is in the past.',
44
- generatedAt: '2026-03-24T08:00:00Z',
45
- },
46
- {
47
- entity: null,
48
- entityId: null,
49
- severity: 'info',
50
- message: 'BEP has no KPIs defined in the indicators section.',
51
- generatedAt: '2026-03-24T08:00:00Z',
52
- },
53
- ])
54
- const f1Id = flagsAdded.succeeded[0].id
55
- const f2Id = flagsAdded.succeeded[1].id
56
- console.log('flags added:', flagsAdded.succeeded.map(f => `[${f.severity}] ${f.message.slice(0, 40)}`))
57
-
58
- // remove a flag once it has been resolved or knowingly accepted
59
- const flagRemoved = bep.flags.remove([f2Id, 'ghost-flag'])
60
- console.log('remove info flag:', flagRemoved.succeeded)
61
- console.log('remove ghost (failed):', flagRemoved.failed)
62
- console.log('flags remaining:', bep.flags.list().length)
63
-
64
- // ─── Memory ───────────────────────────────────────────────────────────────────
65
-
66
- console.log('\n=== memory ===')
67
-
68
- // memory is project-specific context the LLM writes for itself to recall across sessions
69
- console.log('memory (empty):', JSON.stringify(await bep.memory.get()))
70
-
71
- bep.memory.set([
72
- '# Project Memory',
73
- '',
74
- '- LOD 300 confirmed with client on 2026-03-15.',
75
- '- Structure team is responsible for all EST deliverables.',
76
- '- "No KPIs" flag acknowledged — no KPI framework planned for this phase.',
77
- ].join('\n'))
78
-
79
- console.log('memory set (first 60 chars):', (await bep.memory.get()).slice(0, 60))
80
-
81
- // overwrite — no append, the caller owns the full string
82
- const current = await bep.memory.get()
83
- bep.memory.set(current + '\n- Coordination meetings every Monday at 09:00.')
84
- console.log('memory length after update:', (await bep.memory.get()).length)
85
-
86
- // ─── Skill ────────────────────────────────────────────────────────────────────
87
-
88
- console.log('\n=== skill ===')
89
-
90
- // skill is the BIM Manager's instructions for how the LLM should behave in this BEP
91
- console.log('skill (empty):', JSON.stringify(await bep.skill.get()))
92
-
93
- bep.skill.set([
94
- 'Always use ISO 19650 terminology.',
95
- 'Prefer concise descriptions — one sentence per deliverable.',
96
- 'When suggesting LOD levels, reference the project phases in bep.phases.',
97
- ].join('\n'))
98
-
99
- console.log('skill set (first 60 chars):', (await bep.skill.get()).slice(0, 60))
100
-
101
- // key use case: copy skill from a template BEP to a new project
102
- const templateBep = Bep.create({ name: 'New Project', code: 'NEW' })
103
- templateBep.skill.set(await bep.skill.get())
104
- console.log('\nskill copied to new BEP (first 50):', (await templateBep.skill.get()).slice(0, 50))
105
-
106
- // ─── Save ─────────────────────────────────────────────────────────────────────
107
-
108
- writeFileSync('examples/example.bep', await bep.save())
109
- console.log('\nSaved → examples/example.bep')
@@ -1,133 +0,0 @@
1
- // part of: node --experimental-strip-types examples/run-all.ts (use --11 to stop here)
2
- //
3
- // Covers: listResolved() across all entity types. Read-only — no save.
4
- //
5
- // Every list() call returns raw entities with ID references (e.g. roleId: 'uuid').
6
- // listResolved() replaces every ID with the full referenced object, so callers
7
- // get a ready-to-render shape without performing any lookups themselves.
8
- //
9
- // This is particularly useful for the MCP — list_* tools always call
10
- // listResolved() internally and return the enriched objects, so the LLM never
11
- // needs to issue a follow-up call just to resolve a name.
12
- //
13
- // If a reference is broken (the referenced entity was deleted), listResolved()
14
- // returns { id, name: null } instead of throwing, so the rest of the record
15
- // remains usable.
16
-
17
- import { readFileSync } from 'node:fs'
18
- import { Bep } from '../dist/index.js'
19
-
20
- const bep = await Bep.open(readFileSync('examples/example.bep'))
21
-
22
- // ─── members ──────────────────────────────────────────────────────────────────
23
-
24
- console.log('=== members.listResolved() ===')
25
-
26
- const resolvedMembers = bep.members.listResolved()
27
- const alice = resolvedMembers.find(m => m.email === 'alice@arc.com')!
28
- console.log('alice role: ', alice.role) // { id, name, color }
29
- console.log('alice team: ', alice.team) // { id: 'ARC', name: '...' }
30
- console.log('alice isRepresentative:', alice.isRepresentative) // true
31
-
32
- // ─── teams ────────────────────────────────────────────────────────────────────
33
-
34
- console.log('\n=== teams.listResolved() ===')
35
-
36
- const resolvedTeams = bep.teams.listResolved()
37
- const arc = resolvedTeams.find(t => t.id === 'ARC')!
38
- console.log('ARC representative:', arc.representative?.name)
39
- console.log('ARC members: ', arc.members.map(m => m.name))
40
- console.log('ARC disciplines: ', arc.disciplines.map(d => d.id))
41
-
42
- // ─── milestones ───────────────────────────────────────────────────────────────
43
-
44
- console.log('\n=== milestones.listResolved() ===')
45
-
46
- const resolvedMilestones = bep.milestones.listResolved()
47
- for (const m of resolvedMilestones) {
48
- console.log(` ${m.name} (${m.date}) → phase: ${m.phase?.name}`)
49
- }
50
-
51
- // ─── lbsNodes ─────────────────────────────────────────────────────────────────
52
-
53
- console.log('\n=== lbsNodes.listResolved() ===')
54
-
55
- const resolvedLbs = bep.lbsNodes.listResolved()
56
- const site = resolvedLbs.find(n => n.id === 'SIT')!
57
- const blkA = resolvedLbs.find(n => n.id === 'BLK')!
58
- const p01 = resolvedLbs.find(n => n.id === 'P01')!
59
-
60
- console.log('SIT isRoot:', site.isRoot, '| parent:', site.parent, '| children:', site.children.map(c => c.id))
61
- console.log('BLK isRoot:', blkA.isRoot, '| parent:', blkA.parent?.id, '| children:', blkA.children.map(c => c.id))
62
- console.log('P01 isRoot:', p01.isRoot, '| parent:', p01.parent?.id)
63
-
64
- // ─── guides ───────────────────────────────────────────────────────────────────
65
-
66
- console.log('\n=== guides.listResolved() ===')
67
-
68
- const resolvedGuides = bep.guides.listResolved()
69
- for (const g of resolvedGuides) {
70
- console.log(` ${g.name}: annexes=[${g.annexes.map(a => a.name).join(', ')}]`)
71
- }
72
-
73
- // ─── workflows ────────────────────────────────────────────────────────────────
74
-
75
- console.log('\n=== workflows.listResolved() ===')
76
-
77
- const resolvedWorkflows = bep.workflows.listResolved()
78
- const wf = resolvedWorkflows[0]
79
- console.log('workflow:', wf.name)
80
-
81
- const updateNode = wf.diagram.nodes['update']
82
- if (updateNode) {
83
- console.log('update node action: ', updateNode.action?.name)
84
- console.log('update node responsible:', updateNode.responsible.roles.map(r => r.name))
85
- }
86
-
87
- // ─── bimUses ──────────────────────────────────────────────────────────────────
88
-
89
- console.log('\n=== bimUses.listResolved() ===')
90
-
91
- const resolvedBimUses = bep.bimUses.listResolved()
92
- for (const bu of resolvedBimUses) {
93
- console.log(` ${bu.name}:`)
94
- console.log(` objectives: [${bu.objectives.map(o => o.description.slice(0, 35)).join(' | ')}]`)
95
- console.log(` workflows: [${bu.workflows.map(w => w.name).join(', ')}]`)
96
- }
97
-
98
- // ─── loin ─────────────────────────────────────────────────────────────────────
99
-
100
- console.log('\n=== loin.listResolved() ===')
101
-
102
- const resolvedLoin = bep.loin.listResolved()
103
- for (const l of resolvedLoin) {
104
- console.log(` ${l.element} (${l.discipline?.name}):`)
105
- for (const lm of l.milestones) {
106
- console.log(` milestone=${lm.milestone?.name} lod=${lm.lod?.name} loi=${lm.loi?.name}`)
107
- }
108
- }
109
-
110
- // ─── deliverables ─────────────────────────────────────────────────────────────
111
-
112
- console.log('\n=== deliverables.listResolved() ===')
113
-
114
- const resolvedDelivs = bep.deliverables.listResolved()
115
- for (const d of resolvedDelivs) {
116
- console.log(` ${d.nomenclatureCode ?? d.id}`)
117
- console.log(` discipline: ${d.discipline?.name}`)
118
- console.log(` assetType: ${d.assetType?.name}`)
119
- console.log(` responsible: ${d.responsible?.name}`)
120
- console.log(` milestone: ${d.milestone?.name}`)
121
- if (d.predecessor) console.log(` predecessor: ${d.predecessor.id}`)
122
- }
123
-
124
- // ─── notes ────────────────────────────────────────────────────────────────────
125
-
126
- console.log('\n=== notes.listResolved() ===')
127
-
128
- const resolvedNotes = bep.notes.listResolved()
129
- for (const n of resolvedNotes) {
130
- console.log(` [${n.member?.name ?? '(unknown)'}] ${n.message.slice(0, 60)}`)
131
- }
132
-
133
- console.log('\nDone — no save (read-only example).')