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.
@@ -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":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;;GAKG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;EAKhB,CAAC;AAEZ,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;EAIvB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;EAGhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;EAIrB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;EAE1B,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;EAQxB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAM7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUrB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAO9D,eAAO,MAAM,WAAW,aAAa,CAAC;AACtC,eAAO,MAAM,UAAU,aAAa,CAAC;AACrC,eAAO,MAAM,eAAe,aAAa,CAAC;AAC1C,eAAO,MAAM,eAAe,aAAa,CAAC;AAG1C,KAAK,OAAO,GAAG;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;IACxI,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB,CAAC;AAGF,eAAO,MAAM,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAc5C,CAAC;AAGF,YAAY,EAAE,OAAO,EAAE,CAAC;AAexB,eAAO,MAAM,iBAAiB,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAIpD,CAAC;AAGF,YAAY,EAAE,WAAW,EAAE,CAAC;AAG5B,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEzB,CAAC;AAGH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEtB,CAAC;AAIH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIhC,CAAC;AAGH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAwB,CAAC;AAGrD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK1B,CAAC;AAGH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMjC,CAAA;AAGJ,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA2B,CAAC;AAG3D,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGvB,CAAA;AAIJ,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGnB,CAAA;AAGJ,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAErB,CAAA;AAGJ,eAAO,MAAM,cAAc,mDAAiD,CAAC;AAC7E,eAAO,MAAM,UAAU;;;;;;;;;;;;EAIrB,CAAC;AAGH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;EAKrB,CAAC;AAGH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "busy-cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "CLI for BUSY document framework - parse, validate, and manage BUSY workspaces",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -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
@@ -10,6 +10,9 @@ export type {
10
10
  Section,
11
11
  ConceptBase,
12
12
  BusyDocument,
13
+ Playbook,
14
+ View,
15
+ Config,
13
16
  LocalDef,
14
17
  Operation,
15
18
  ImportDef,
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: (BusyDocument | Playbook)[] = []; // Full concept definitions
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 isPlaybook = parts.types.some((t) => t.toLowerCase() === 'playbook');
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
- const doc: Playbook = {
225
- kind: 'playbook',
226
- id: parts.docId,
227
- docId: parts.docId,
228
- slug: parts.docId.toLowerCase(),
229
- name: parts.frontmatter.Name,
230
- content: parts.content,
231
- types: parts.types,
232
- extends: parts.extends,
233
- sectionRef: `${parts.docId}#`, // Root reference
234
- imports: parts.imports,
235
- localdefs: parts.localdefs,
236
- setup: parts.setup!,
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: BusyDocument | Playbook; bySlug: Record<string, Section> }> = {};
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: (BusyDocument | Playbook)[],
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: (BusyDocument | Playbook)[],
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
- throw new Error(`Circular import detected: ${importPath}`);
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
- throw new Error(`Import not found: ${imp.path} (resolved to ${importPath})`);
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
- throw new Error(`Anchor '${imp.anchor}' not found in ${imp.path}`);
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
- } finally {
262
- // Remove from visited after processing (allow same doc in different branches)
263
- visited.delete(importPath);
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;
@@ -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>;