busy-cli 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +50 -30
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +12 -8
- package/dist/types/schema.d.ts +1650 -76
- package/dist/types/schema.d.ts.map +1 -1
- package/dist/types/schema.js +12 -2
- package/package.json +1 -1
- package/src/__tests__/view-config.test.ts +277 -0
- package/src/index.ts +3 -0
- package/src/loader.ts +66 -38
- package/src/parser.ts +12 -8
- package/src/types/schema.ts +17 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/types/schema.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/types/schema.ts"],"names":[],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcrB,CAAC;AAGH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS/B,CAAC;AAUH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAChD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC1E,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAC9C,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACxD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAC9C,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAC9C,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAC9C,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAGlE,MAAM,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAC9C,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC;AAOxC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;EA2B5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|
package/dist/types/schema.js
CHANGED
|
@@ -126,7 +126,7 @@ export const SectionSchema = z.lazy(() => z.object({
|
|
|
126
126
|
}));
|
|
127
127
|
// ConceptBase schema - need to keep as regular object schema to allow .extend()
|
|
128
128
|
const ConceptBaseSchemaObject = z.object({
|
|
129
|
-
kind: z.enum(['concept', 'document', 'operation', 'checklist', 'tool', 'playbook', 'localdef', 'importdef', 'setup']),
|
|
129
|
+
kind: z.enum(['concept', 'document', 'operation', 'checklist', 'tool', 'playbook', 'view', 'config', 'localdef', 'importdef', 'setup']),
|
|
130
130
|
id: ConceptIdSchema,
|
|
131
131
|
docId: DocIdSchema,
|
|
132
132
|
slug: z.string(),
|
|
@@ -178,6 +178,16 @@ export const PlaybookSchema = LegacyBusyDocumentSchema.extend({
|
|
|
178
178
|
kind: z.literal('playbook'),
|
|
179
179
|
sequence: z.array(ConceptIdSchema), // Ordered array of operation references
|
|
180
180
|
});
|
|
181
|
+
// View schema - extends LegacyBusyDocument with display section
|
|
182
|
+
// Views follow MVC: imports=Model, localDefs=ViewModel, template=View, operations=Controller
|
|
183
|
+
export const ViewSchema = LegacyBusyDocumentSchema.extend({
|
|
184
|
+
kind: z.literal('view'),
|
|
185
|
+
display: z.string().optional(), // Markdown template (optional — LORE can generate)
|
|
186
|
+
});
|
|
187
|
+
// Config schema - extends LegacyBusyDocument, semantically a singleton Model
|
|
188
|
+
export const ConfigSchema = LegacyBusyDocumentSchema.extend({
|
|
189
|
+
kind: z.literal('config'),
|
|
190
|
+
});
|
|
181
191
|
// Edge schema
|
|
182
192
|
export const EdgeRoleSchema = z.enum(['ref', 'calls', 'extends', 'imports']);
|
|
183
193
|
export const EdgeSchema = z.object({
|
|
@@ -202,7 +212,7 @@ export const RepoSchema = z.object({
|
|
|
202
212
|
byId: z.record(z.union([SectionSchema, LocalDefSchema, LegacyOperationSchema, ConceptBaseSchema])),
|
|
203
213
|
byFile: z.record(// Renamed from byDoc for clarity
|
|
204
214
|
z.object({
|
|
205
|
-
concept: z.union([LegacyBusyDocumentSchema, PlaybookSchema]), // The concept defined in this file
|
|
215
|
+
concept: z.union([LegacyBusyDocumentSchema, PlaybookSchema, ViewSchema, ConfigSchema]), // The concept defined in this file
|
|
206
216
|
bySlug: z.record(SectionSchema),
|
|
207
217
|
})),
|
|
208
218
|
edges: z.array(EdgeSchema),
|
package/package.json
CHANGED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
2
|
+
import { loadRepo } from '../loader.js';
|
|
3
|
+
import { join, dirname } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { writeFileSync, mkdirSync, rmSync } from 'node:fs';
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const FIXTURES_DIR = join(__dirname, '__fixtures__', 'view-config');
|
|
9
|
+
|
|
10
|
+
// ── Fixtures ────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
const MODEL_DOC = `---
|
|
13
|
+
Name: Prospect
|
|
14
|
+
Type: [Model]
|
|
15
|
+
Description: An agent who has initiated contact
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Imports
|
|
19
|
+
|
|
20
|
+
# Local Definitions
|
|
21
|
+
|
|
22
|
+
## ProspectFields
|
|
23
|
+
- \`agent_name\` — Full name
|
|
24
|
+
- \`stage\` — discovery | trial | subscriber
|
|
25
|
+
- \`health_status\` — healthy | at_risk | churned
|
|
26
|
+
|
|
27
|
+
# Setup
|
|
28
|
+
|
|
29
|
+
A Prospect represents an agent in the early funnel.
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
const VIEW_DOC = `---
|
|
33
|
+
Name: Prospect Pipeline
|
|
34
|
+
Type: [View]
|
|
35
|
+
Description: Dashboard view of all prospects in the conversion funnel
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
# Imports
|
|
39
|
+
[Prospect]:./prospect.busy.md
|
|
40
|
+
|
|
41
|
+
# Local Definitions
|
|
42
|
+
|
|
43
|
+
## ProspectRow
|
|
44
|
+
A summary row combining Prospect data.
|
|
45
|
+
- \`name\` — from [Prospect].agent_name
|
|
46
|
+
- \`stage\` — from [Prospect].stage
|
|
47
|
+
- \`health\` — from [Prospect].health_status
|
|
48
|
+
|
|
49
|
+
# Display
|
|
50
|
+
|
|
51
|
+
## Pipeline Summary
|
|
52
|
+
| Stage | Count |
|
|
53
|
+
|-------|-------|
|
|
54
|
+
{{#each stageSummary}}
|
|
55
|
+
| {{stage}} | {{count}} |
|
|
56
|
+
{{/each}}
|
|
57
|
+
|
|
58
|
+
## All Prospects
|
|
59
|
+
{{#each prospects}}
|
|
60
|
+
- **{{name}}** — {{stage}} ({{health}})
|
|
61
|
+
{{/each}}
|
|
62
|
+
|
|
63
|
+
# Operations
|
|
64
|
+
|
|
65
|
+
## refreshView
|
|
66
|
+
Reload prospect data from the database.
|
|
67
|
+
|
|
68
|
+
### Steps
|
|
69
|
+
1. Query all active prospects
|
|
70
|
+
2. Compute stage summary counts
|
|
71
|
+
3. Sort by days in stage descending
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
const VIEW_NO_TEMPLATE = `---
|
|
75
|
+
Name: Simple View
|
|
76
|
+
Type: [View]
|
|
77
|
+
Description: A view without an explicit display section
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
# Imports
|
|
81
|
+
[Prospect]:./prospect.busy.md
|
|
82
|
+
|
|
83
|
+
# Local Definitions
|
|
84
|
+
|
|
85
|
+
## SimpleRow
|
|
86
|
+
- \`name\` — from [Prospect].agent_name
|
|
87
|
+
|
|
88
|
+
# Operations
|
|
89
|
+
|
|
90
|
+
## refresh
|
|
91
|
+
Reload data.
|
|
92
|
+
`;
|
|
93
|
+
|
|
94
|
+
const CONFIG_DOC = `---
|
|
95
|
+
Name: Canon SDLC
|
|
96
|
+
Type: [Config]
|
|
97
|
+
Description: Process configuration for the Canon SDLC wizard
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
# Imports
|
|
101
|
+
|
|
102
|
+
# Local Definitions
|
|
103
|
+
|
|
104
|
+
## PhaseDefinition
|
|
105
|
+
- \`id\` — Phase identifier
|
|
106
|
+
- \`title\` — Display title
|
|
107
|
+
- \`steps\` — Array of step definitions
|
|
108
|
+
|
|
109
|
+
## StepDefinition
|
|
110
|
+
- \`id\` — Step identifier
|
|
111
|
+
- \`title\` — Display title
|
|
112
|
+
- \`content\` — Instructions markdown
|
|
113
|
+
- \`actions\` — Array of action definitions
|
|
114
|
+
|
|
115
|
+
# Setup
|
|
116
|
+
|
|
117
|
+
The Canon SDLC defines a 6-phase software development lifecycle.
|
|
118
|
+
Phases: Intake, Shape, Spec, Implement, Review, Ship.
|
|
119
|
+
`;
|
|
120
|
+
|
|
121
|
+
// ── Setup / Teardown ────────────────────────────────────────────────
|
|
122
|
+
|
|
123
|
+
function setupFixtures() {
|
|
124
|
+
mkdirSync(FIXTURES_DIR, { recursive: true });
|
|
125
|
+
writeFileSync(join(FIXTURES_DIR, 'prospect.busy.md'), MODEL_DOC);
|
|
126
|
+
writeFileSync(join(FIXTURES_DIR, 'prospect-pipeline.busy.md'), VIEW_DOC);
|
|
127
|
+
writeFileSync(join(FIXTURES_DIR, 'simple-view.busy.md'), VIEW_NO_TEMPLATE);
|
|
128
|
+
writeFileSync(join(FIXTURES_DIR, 'canon-sdlc.busy.md'), CONFIG_DOC);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function cleanFixtures() {
|
|
132
|
+
rmSync(FIXTURES_DIR, { recursive: true, force: true });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ── Tests ───────────────────────────────────────────────────────────
|
|
136
|
+
|
|
137
|
+
describe('View and Config Types', () => {
|
|
138
|
+
let repo: Awaited<ReturnType<typeof loadRepo>>;
|
|
139
|
+
|
|
140
|
+
beforeAll(async () => {
|
|
141
|
+
setupFixtures();
|
|
142
|
+
repo = await loadRepo([join(FIXTURES_DIR, '*.busy.md')]);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
afterAll(() => {
|
|
146
|
+
cleanFixtures();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
describe('Loading', () => {
|
|
150
|
+
it('loads all 4 fixture documents', () => {
|
|
151
|
+
expect(repo.concepts.length).toBe(4);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('classifies Model as document', () => {
|
|
155
|
+
const prospect = repo.concepts.find(c => c.name === 'Prospect');
|
|
156
|
+
expect(prospect).toBeDefined();
|
|
157
|
+
expect(prospect!.kind).toBe('document');
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('classifies View as view', () => {
|
|
161
|
+
const pipeline = repo.concepts.find(c => c.name === 'Prospect Pipeline');
|
|
162
|
+
expect(pipeline).toBeDefined();
|
|
163
|
+
expect(pipeline!.kind).toBe('view');
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('classifies Config as config', () => {
|
|
167
|
+
const config = repo.concepts.find(c => c.name === 'Canon SDLC');
|
|
168
|
+
expect(config).toBeDefined();
|
|
169
|
+
expect(config!.kind).toBe('config');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
describe('View Document', () => {
|
|
174
|
+
it('has display content when Display section exists', () => {
|
|
175
|
+
const viewDocId = Object.keys(repo.byFile).find(id =>
|
|
176
|
+
repo.byFile[id].concept.name === 'Prospect Pipeline'
|
|
177
|
+
)!;
|
|
178
|
+
const viewDoc = repo.byFile[viewDocId].concept;
|
|
179
|
+
expect(viewDoc.kind).toBe('view');
|
|
180
|
+
if (viewDoc.kind === 'view') {
|
|
181
|
+
expect(viewDoc.display).toBeDefined();
|
|
182
|
+
expect(viewDoc.display).toContain('{{#each stageSummary}}');
|
|
183
|
+
expect(viewDoc.display).toContain('{{#each prospects}}');
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('has undefined display when no Display section', () => {
|
|
188
|
+
const viewDocId = Object.keys(repo.byFile).find(id =>
|
|
189
|
+
repo.byFile[id].concept.name === 'Simple View'
|
|
190
|
+
)!;
|
|
191
|
+
const viewDoc = repo.byFile[viewDocId].concept;
|
|
192
|
+
expect(viewDoc.kind).toBe('view');
|
|
193
|
+
if (viewDoc.kind === 'view') {
|
|
194
|
+
expect(viewDoc.display).toBeUndefined();
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('has imports resolved', () => {
|
|
199
|
+
const viewDocId = Object.keys(repo.byFile).find(id =>
|
|
200
|
+
repo.byFile[id].concept.name === 'Prospect Pipeline'
|
|
201
|
+
)!;
|
|
202
|
+
const viewDoc = repo.byFile[viewDocId].concept;
|
|
203
|
+
expect(viewDoc.imports.length).toBeGreaterThan(0);
|
|
204
|
+
expect(viewDoc.imports[0].label).toBe('Prospect');
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('has local definitions (ViewModel)', () => {
|
|
208
|
+
const viewDocId = Object.keys(repo.byFile).find(id =>
|
|
209
|
+
repo.byFile[id].concept.name === 'Prospect Pipeline'
|
|
210
|
+
)!;
|
|
211
|
+
const viewDoc = repo.byFile[viewDocId].concept;
|
|
212
|
+
expect(viewDoc.localdefs.length).toBeGreaterThan(0);
|
|
213
|
+
expect(viewDoc.localdefs[0].name).toBe('ProspectRow');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('has operations (Controller)', () => {
|
|
217
|
+
const viewDocId = Object.keys(repo.byFile).find(id =>
|
|
218
|
+
repo.byFile[id].concept.name === 'Prospect Pipeline'
|
|
219
|
+
)!;
|
|
220
|
+
const viewDoc = repo.byFile[viewDocId].concept;
|
|
221
|
+
expect(viewDoc.operations.length).toBeGreaterThan(0);
|
|
222
|
+
expect(viewDoc.operations[0].name).toBe('refreshView');
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('creates import edges', () => {
|
|
226
|
+
const viewDocId = Object.keys(repo.byFile).find(id =>
|
|
227
|
+
repo.byFile[id].concept.name === 'Prospect Pipeline'
|
|
228
|
+
)!;
|
|
229
|
+
const importEdges = repo.edges.filter(
|
|
230
|
+
e => e.from === viewDocId && e.role === 'imports'
|
|
231
|
+
);
|
|
232
|
+
expect(importEdges.length).toBeGreaterThan(0);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
describe('Config Document', () => {
|
|
237
|
+
it('has local definitions', () => {
|
|
238
|
+
const configDocId = Object.keys(repo.byFile).find(id =>
|
|
239
|
+
repo.byFile[id].concept.name === 'Canon SDLC'
|
|
240
|
+
)!;
|
|
241
|
+
const configDoc = repo.byFile[configDocId].concept;
|
|
242
|
+
expect(configDoc.localdefs.length).toBe(2);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('has setup section', () => {
|
|
246
|
+
const configDocId = Object.keys(repo.byFile).find(id =>
|
|
247
|
+
repo.byFile[id].concept.name === 'Canon SDLC'
|
|
248
|
+
)!;
|
|
249
|
+
const configDoc = repo.byFile[configDocId].concept;
|
|
250
|
+
expect(configDoc.setup).toBeDefined();
|
|
251
|
+
expect(configDoc.setup.content).toContain('6-phase');
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('is distinct from regular document', () => {
|
|
255
|
+
const configConcept = repo.concepts.find(c => c.name === 'Canon SDLC');
|
|
256
|
+
const modelConcept = repo.concepts.find(c => c.name === 'Prospect');
|
|
257
|
+
expect(configConcept!.kind).toBe('config');
|
|
258
|
+
expect(modelConcept!.kind).toBe('document');
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
describe('Graph Integrity', () => {
|
|
263
|
+
it('view and config appear in byId', () => {
|
|
264
|
+
const viewConcept = repo.concepts.find(c => c.name === 'Prospect Pipeline');
|
|
265
|
+
const configConcept = repo.concepts.find(c => c.name === 'Canon SDLC');
|
|
266
|
+
expect(repo.byId[viewConcept!.id]).toBeDefined();
|
|
267
|
+
expect(repo.byId[configConcept!.id]).toBeDefined();
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('all four document types coexist', () => {
|
|
271
|
+
const kinds = new Set(repo.concepts.map(c => c.kind));
|
|
272
|
+
expect(kinds.has('document')).toBe(true);
|
|
273
|
+
expect(kinds.has('view')).toBe(true);
|
|
274
|
+
expect(kinds.has('config')).toBe(true);
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
});
|
package/src/index.ts
CHANGED
package/src/loader.ts
CHANGED
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
Repo,
|
|
6
6
|
BusyDocument,
|
|
7
7
|
Playbook,
|
|
8
|
+
View,
|
|
9
|
+
Config,
|
|
8
10
|
ConceptBase,
|
|
9
11
|
LocalDef,
|
|
10
12
|
Operation,
|
|
@@ -13,6 +15,13 @@ import {
|
|
|
13
15
|
Section,
|
|
14
16
|
File,
|
|
15
17
|
} from './types/schema.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Union of all top-level document variants the loader produces.
|
|
21
|
+
* Note: BusyDocument covers the generic `document` kind, including plain
|
|
22
|
+
* Document/Model-style docs that don't get a more specific classifier.
|
|
23
|
+
*/
|
|
24
|
+
type AnyDocument = BusyDocument | Playbook | View | Config;
|
|
16
25
|
import { parseFrontMatter } from './parsers/frontmatter.js';
|
|
17
26
|
import { parseSections, getAllSections, findSection } from './parsers/sections.js';
|
|
18
27
|
import { extractLocalDefs } from './parsers/localdefs.js';
|
|
@@ -67,7 +76,7 @@ export async function loadRepo(globs: string[]): Promise<Repo> {
|
|
|
67
76
|
|
|
68
77
|
// Second pass: parse documents
|
|
69
78
|
const files: File[] = []; // Lightweight file representations
|
|
70
|
-
const docs:
|
|
79
|
+
const docs: AnyDocument[] = []; // Full concept definitions
|
|
71
80
|
const allLocaldefs = new Map<string, LocalDef>();
|
|
72
81
|
const allOperations = new Map<string, Operation>();
|
|
73
82
|
const allImports: ImportDef[] = [];
|
|
@@ -215,51 +224,57 @@ export async function loadRepo(globs: string[]): Promise<Repo> {
|
|
|
215
224
|
|
|
216
225
|
// Build final document structures with inline arrays
|
|
217
226
|
for (const [docId, parts] of docParts) {
|
|
218
|
-
const
|
|
227
|
+
const typesLower = parts.types.map((t) => t.toLowerCase());
|
|
228
|
+
const isPlaybook = typesLower.includes('playbook');
|
|
229
|
+
const isView = typesLower.includes('view');
|
|
230
|
+
const isConfig = typesLower.includes('config');
|
|
231
|
+
|
|
232
|
+
// Base fields shared across all document kinds
|
|
233
|
+
const baseFields = {
|
|
234
|
+
id: parts.docId,
|
|
235
|
+
docId: parts.docId,
|
|
236
|
+
slug: parts.docId.toLowerCase(),
|
|
237
|
+
name: parts.frontmatter.Name,
|
|
238
|
+
content: parts.content,
|
|
239
|
+
types: parts.types,
|
|
240
|
+
extends: parts.extends,
|
|
241
|
+
sectionRef: `${parts.docId}#`, // Root reference
|
|
242
|
+
imports: parts.imports,
|
|
243
|
+
localdefs: parts.localdefs,
|
|
244
|
+
setup: parts.setup!,
|
|
245
|
+
operations: parts.operations,
|
|
246
|
+
};
|
|
219
247
|
|
|
220
248
|
if (isPlaybook) {
|
|
221
249
|
// Extract sequence from ExecutePlaybook operation
|
|
222
250
|
const sequence = extractPlaybookSequence(parts.sections);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
operations: parts.operations,
|
|
238
|
-
sequence,
|
|
251
|
+
const doc: Playbook = { ...baseFields, kind: 'playbook', sequence };
|
|
252
|
+
docs.push(doc);
|
|
253
|
+
} else if (isView) {
|
|
254
|
+
// Extract template section with full content (including children)
|
|
255
|
+
const displaySection = findSection(parts.sections, 'display');
|
|
256
|
+
let displayContent: string | undefined;
|
|
257
|
+
if (displaySection) {
|
|
258
|
+
// Reconstruct full template from section + children content
|
|
259
|
+
displayContent = getSectionFullContent(displaySection);
|
|
260
|
+
}
|
|
261
|
+
const doc: View = {
|
|
262
|
+
...baseFields,
|
|
263
|
+
kind: 'view',
|
|
264
|
+
display: displayContent,
|
|
239
265
|
};
|
|
240
266
|
docs.push(doc);
|
|
267
|
+
} else if (isConfig) {
|
|
268
|
+
const doc: Config = { ...baseFields, kind: 'config' };
|
|
269
|
+
docs.push(doc);
|
|
241
270
|
} else {
|
|
242
|
-
const doc: BusyDocument = {
|
|
243
|
-
kind: 'document',
|
|
244
|
-
id: parts.docId,
|
|
245
|
-
docId: parts.docId,
|
|
246
|
-
slug: parts.docId.toLowerCase(),
|
|
247
|
-
name: parts.frontmatter.Name,
|
|
248
|
-
content: parts.content,
|
|
249
|
-
types: parts.types,
|
|
250
|
-
extends: parts.extends,
|
|
251
|
-
sectionRef: `${parts.docId}#`, // Root reference
|
|
252
|
-
imports: parts.imports,
|
|
253
|
-
localdefs: parts.localdefs,
|
|
254
|
-
setup: parts.setup!,
|
|
255
|
-
operations: parts.operations,
|
|
256
|
-
};
|
|
271
|
+
const doc: BusyDocument = { ...baseFields, kind: 'document' };
|
|
257
272
|
docs.push(doc);
|
|
258
273
|
}
|
|
259
274
|
}
|
|
260
275
|
|
|
261
276
|
// Inherit operations from parent documents
|
|
262
|
-
inheritOperations(docs, allOperations);
|
|
277
|
+
inheritOperations(docs as (BusyDocument | Playbook)[], allOperations);
|
|
263
278
|
|
|
264
279
|
// Build concepts array (includes all documents as ConceptBase)
|
|
265
280
|
const concepts: ConceptBase[] = docs.map((doc) => ({
|
|
@@ -306,7 +321,7 @@ export async function loadRepo(globs: string[]): Promise<Repo> {
|
|
|
306
321
|
}
|
|
307
322
|
|
|
308
323
|
// Build byFile index
|
|
309
|
-
const byFile: Record<string, { concept:
|
|
324
|
+
const byFile: Record<string, { concept: AnyDocument; bySlug: Record<string, Section> }> = {};
|
|
310
325
|
|
|
311
326
|
for (const doc of docs) {
|
|
312
327
|
const bySlug: Record<string, Section> = {};
|
|
@@ -352,11 +367,11 @@ export async function loadRepo(globs: string[]): Promise<Repo> {
|
|
|
352
367
|
* 2. Documents in the 'types' array (implicit type-based inheritance)
|
|
353
368
|
*/
|
|
354
369
|
function inheritOperations(
|
|
355
|
-
docs:
|
|
370
|
+
docs: AnyDocument[],
|
|
356
371
|
allOperations: Map<string, Operation>
|
|
357
372
|
): void {
|
|
358
373
|
// Build doc lookup by name
|
|
359
|
-
const docByName = new Map<string, BusyDocument | Playbook>();
|
|
374
|
+
const docByName = new Map<string, BusyDocument | Playbook | View | Config>();
|
|
360
375
|
for (const doc of docs) {
|
|
361
376
|
docByName.set(doc.name, doc);
|
|
362
377
|
}
|
|
@@ -416,7 +431,7 @@ function resolveSymbol(
|
|
|
416
431
|
nameOrLabel: string,
|
|
417
432
|
currentDocId: string,
|
|
418
433
|
localdefs: Map<string, LocalDef>,
|
|
419
|
-
docs:
|
|
434
|
+
docs: AnyDocument[],
|
|
420
435
|
symbols: Record<string, { docId?: string; slug?: string }>
|
|
421
436
|
): string | undefined {
|
|
422
437
|
// 1. Check for LocalDef in same doc
|
|
@@ -440,6 +455,19 @@ function resolveSymbol(
|
|
|
440
455
|
return undefined;
|
|
441
456
|
}
|
|
442
457
|
|
|
458
|
+
/**
|
|
459
|
+
* Get the full content of a section including all nested children.
|
|
460
|
+
* Reconstructs the original markdown by walking the section tree.
|
|
461
|
+
*/
|
|
462
|
+
function getSectionFullContent(section: Section): string {
|
|
463
|
+
let content = section.content;
|
|
464
|
+
for (const child of section.children) {
|
|
465
|
+
const prefix = '#'.repeat(child.depth);
|
|
466
|
+
content += `\n${prefix} ${child.title}\n${getSectionFullContent(child)}`;
|
|
467
|
+
}
|
|
468
|
+
return content.trim();
|
|
469
|
+
}
|
|
470
|
+
|
|
443
471
|
/**
|
|
444
472
|
* Extract sequence of operations from a playbook's ExecutePlaybook operation
|
|
445
473
|
* Looks for sections with "Step" in the title and extracts Target metadata
|
package/src/parser.ts
CHANGED
|
@@ -217,14 +217,16 @@ export function resolveImports(
|
|
|
217
217
|
// Resolve the import path
|
|
218
218
|
const importPath = resolve(dirname(basePath), imp.path);
|
|
219
219
|
|
|
220
|
-
// Check for circular imports
|
|
220
|
+
// Check for circular imports — warn and skip instead of crashing
|
|
221
221
|
if (visited.has(importPath)) {
|
|
222
|
-
|
|
222
|
+
console.warn(`⚠ Circular import skipped: ${imp.path} (from ${basePath})`);
|
|
223
|
+
continue;
|
|
223
224
|
}
|
|
224
225
|
|
|
225
|
-
// Check if file exists
|
|
226
|
+
// Check if file exists — warn and skip instead of crashing
|
|
226
227
|
if (!existsSync(importPath)) {
|
|
227
|
-
|
|
228
|
+
console.warn(`⚠ Import not found: ${imp.path} (resolved to ${importPath})`);
|
|
229
|
+
continue;
|
|
228
230
|
}
|
|
229
231
|
|
|
230
232
|
// Mark as visited
|
|
@@ -248,7 +250,7 @@ export function resolveImports(
|
|
|
248
250
|
);
|
|
249
251
|
|
|
250
252
|
if (!hasOperation && !hasDefinition) {
|
|
251
|
-
|
|
253
|
+
console.warn(`⚠ Anchor '${imp.anchor}' not found in ${imp.path}`);
|
|
252
254
|
}
|
|
253
255
|
}
|
|
254
256
|
|
|
@@ -258,10 +260,12 @@ export function resolveImports(
|
|
|
258
260
|
// Recursively resolve imports in the imported document
|
|
259
261
|
const nestedResolved = resolveImports(importedDoc, importPath, visited);
|
|
260
262
|
Object.assign(resolved, nestedResolved);
|
|
261
|
-
}
|
|
262
|
-
//
|
|
263
|
-
|
|
263
|
+
} catch (e) {
|
|
264
|
+
// Don't crash on nested resolution failures
|
|
265
|
+
console.warn(`⚠ Failed to resolve nested imports in ${imp.path}: ${e}`);
|
|
264
266
|
}
|
|
267
|
+
// NOTE: we intentionally keep importPath in `visited` — once resolved,
|
|
268
|
+
// don't re-resolve in other branches (prevents exponential recursion)
|
|
265
269
|
}
|
|
266
270
|
|
|
267
271
|
return resolved;
|
package/src/types/schema.ts
CHANGED
|
@@ -160,7 +160,7 @@ type Section = {
|
|
|
160
160
|
};
|
|
161
161
|
|
|
162
162
|
type ConceptBase = {
|
|
163
|
-
kind: 'concept' | 'document' | 'operation' | 'checklist' | 'tool' | 'playbook' | 'localdef' | 'importdef' | 'setup';
|
|
163
|
+
kind: 'concept' | 'document' | 'operation' | 'checklist' | 'tool' | 'playbook' | 'view' | 'config' | 'localdef' | 'importdef' | 'setup';
|
|
164
164
|
id: string;
|
|
165
165
|
docId: string;
|
|
166
166
|
slug: string;
|
|
@@ -194,7 +194,7 @@ export type { Section };
|
|
|
194
194
|
|
|
195
195
|
// ConceptBase schema - need to keep as regular object schema to allow .extend()
|
|
196
196
|
const ConceptBaseSchemaObject = z.object({
|
|
197
|
-
kind: z.enum(['concept', 'document', 'operation', 'checklist', 'tool', 'playbook', 'localdef', 'importdef', 'setup']),
|
|
197
|
+
kind: z.enum(['concept', 'document', 'operation', 'checklist', 'tool', 'playbook', 'view', 'config', 'localdef', 'importdef', 'setup']),
|
|
198
198
|
id: ConceptIdSchema,
|
|
199
199
|
docId: DocIdSchema,
|
|
200
200
|
slug: z.string(),
|
|
@@ -261,6 +261,18 @@ export const PlaybookSchema = LegacyBusyDocumentSchema.extend({
|
|
|
261
261
|
sequence: z.array(ConceptIdSchema), // Ordered array of operation references
|
|
262
262
|
})
|
|
263
263
|
|
|
264
|
+
// View schema - extends LegacyBusyDocument with display section
|
|
265
|
+
// Views follow MVC: imports=Model, localDefs=ViewModel, template=View, operations=Controller
|
|
266
|
+
export const ViewSchema = LegacyBusyDocumentSchema.extend({
|
|
267
|
+
kind: z.literal('view'),
|
|
268
|
+
display: z.string().optional(), // Markdown template (optional — LORE can generate)
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
// Config schema - extends LegacyBusyDocument, semantically a singleton Model
|
|
272
|
+
export const ConfigSchema = LegacyBusyDocumentSchema.extend({
|
|
273
|
+
kind: z.literal('config'),
|
|
274
|
+
})
|
|
275
|
+
|
|
264
276
|
// Edge schema
|
|
265
277
|
export const EdgeRoleSchema = z.enum(['ref', 'calls', 'extends', 'imports']);
|
|
266
278
|
export const EdgeSchema = z.object({
|
|
@@ -287,7 +299,7 @@ export const RepoSchema = z.object({
|
|
|
287
299
|
byId: z.record(z.union([SectionSchema, LocalDefSchema, LegacyOperationSchema, ConceptBaseSchema])),
|
|
288
300
|
byFile: z.record( // Renamed from byDoc for clarity
|
|
289
301
|
z.object({
|
|
290
|
-
concept: z.union([LegacyBusyDocumentSchema, PlaybookSchema]), // The concept defined in this file
|
|
302
|
+
concept: z.union([LegacyBusyDocumentSchema, PlaybookSchema, ViewSchema, ConfigSchema]), // The concept defined in this file
|
|
291
303
|
bySlug: z.record(SectionSchema),
|
|
292
304
|
})
|
|
293
305
|
),
|
|
@@ -319,6 +331,8 @@ export type Slug = z.infer<typeof SlugSchema>;
|
|
|
319
331
|
// Section and ConceptBase types defined above to avoid circular references
|
|
320
332
|
export type LegacyBusyDocument = z.infer<typeof LegacyBusyDocumentSchema>;
|
|
321
333
|
export type Playbook = z.infer<typeof PlaybookSchema>;
|
|
334
|
+
export type View = z.infer<typeof ViewSchema>;
|
|
335
|
+
export type Config = z.infer<typeof ConfigSchema>;
|
|
322
336
|
export type LocalDef = z.infer<typeof LocalDefSchema>;
|
|
323
337
|
export type LegacyOperation = z.infer<typeof LegacyOperationSchema>;
|
|
324
338
|
export type ImportDef = z.infer<typeof ImportDefSchema>;
|