@principal-ai/principal-view-cli 0.3.8 → 0.4.1
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":"formats.d.ts","sourceRoot":"","sources":["../../src/commands/formats.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/commands/formats.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+fpC,wBAAgB,oBAAoB,IAAI,OAAO,CA6B9C"}
|
package/dist/commands/formats.js
CHANGED
|
@@ -48,13 +48,18 @@ ${chalk.dim('│')} ${chalk.yellow('"type"')}: "text",
|
|
|
48
48
|
${chalk.dim('│')} ${chalk.yellow('"text"')}: "# Event Name", ${chalk.dim('// Markdown description')} ${chalk.dim('│')}
|
|
49
49
|
${chalk.dim('│')} ${chalk.yellow('"x"')}: 0, ${chalk.yellow('"y"')}: 0, ${chalk.yellow('"width"')}: 200, ${chalk.yellow('"height"')}: 100, ${chalk.dim('│')}
|
|
50
50
|
${chalk.dim('│')} ${chalk.green('"pv"')}: { ${chalk.dim('│')}
|
|
51
|
-
${chalk.dim('│')} ${chalk.cyan('"
|
|
52
|
-
${chalk.dim('│')}
|
|
53
|
-
${chalk.dim('│')}
|
|
54
|
-
${chalk.dim('│')}
|
|
55
|
-
${chalk.dim('│')}
|
|
56
|
-
${chalk.dim('│')}
|
|
57
|
-
${chalk.dim('│')} }
|
|
51
|
+
${chalk.dim('│')} ${chalk.cyan('"event"')}: "feature.event.name", ${chalk.dim('// Event name')} ${chalk.dim('│')}
|
|
52
|
+
${chalk.dim('│')} ${chalk.cyan('"sources"')}: ["src/file.ts"], ${chalk.dim('// Source files')} ${chalk.dim('│')}
|
|
53
|
+
${chalk.dim('│')} ${chalk.cyan('"otel"')}: { ${chalk.dim('// OTEL metadata')} ${chalk.dim('│')}
|
|
54
|
+
${chalk.dim('│')} ${chalk.yellow('"kind"')}: "event", ${chalk.dim('│')}
|
|
55
|
+
${chalk.dim('│')} ${chalk.yellow('"category"')}: "lifecycle" ${chalk.dim('│')}
|
|
56
|
+
${chalk.dim('│')} }, ${chalk.dim('│')}
|
|
57
|
+
${chalk.dim('│')} ${chalk.cyan('"dataSchema"')}: { ${chalk.dim('// Attribute definitions')} ${chalk.dim('│')}
|
|
58
|
+
${chalk.dim('│')} ${chalk.yellow('"attr.name"')}: { ${chalk.dim('│')}
|
|
59
|
+
${chalk.dim('│')} ${chalk.green('"type"')}: "string", ${chalk.dim('│')}
|
|
60
|
+
${chalk.dim('│')} ${chalk.green('"required"')}: true ${chalk.dim('│')}
|
|
61
|
+
${chalk.dim('│')} } ${chalk.dim('│')}
|
|
62
|
+
${chalk.dim('│')} } ${chalk.dim('│')}
|
|
58
63
|
${chalk.dim('│')} } ${chalk.dim('│')}
|
|
59
64
|
${chalk.dim('│')} } ${chalk.dim('│')}
|
|
60
65
|
${chalk.dim('│')} ], ${chalk.dim('│')}
|
|
@@ -161,12 +166,26 @@ ${chalk.cyan('2. Standard scenario set:')}
|
|
|
161
166
|
- ${chalk.yellow('Failure')} (priority 2): Feature encountered error
|
|
162
167
|
- ${chalk.dim('Fallback')} (priority 999): Generic execution captured
|
|
163
168
|
|
|
164
|
-
${chalk.cyan('3. Template
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
- {{
|
|
169
|
-
- {{result.
|
|
169
|
+
${chalk.cyan('3. Template syntax (Handlebars):')}
|
|
170
|
+
Templates use Handlebars syntax for dynamic content:
|
|
171
|
+
|
|
172
|
+
${chalk.bold('Variables:')}
|
|
173
|
+
- {{variable}} Simple variable
|
|
174
|
+
- {{result.count}} Nested property
|
|
175
|
+
- {{error.message}} Deeply nested
|
|
176
|
+
|
|
177
|
+
${chalk.bold('Conditionals:')}
|
|
178
|
+
- {{#if condition}}...{{/if}} If block
|
|
179
|
+
- {{#if condition}}...{{else}}...{{/if}} If-else
|
|
180
|
+
- {{#if (eq status "ok")}}✅{{else}}❌{{/if}} Comparison
|
|
181
|
+
|
|
182
|
+
${chalk.bold('Loops:')}
|
|
183
|
+
- {{#each items}}{{this}}{{/each}} Iterate array
|
|
184
|
+
- {{#each items}}{{@index}}: {{this}}{{/each}} With index
|
|
185
|
+
|
|
186
|
+
${chalk.bold('Comparison helpers:')}
|
|
187
|
+
- eq, ne, lt, gt, lte, gte, and, or, not
|
|
188
|
+
- Example: {{#if (gt count 10)}}Many{{/if}}
|
|
170
189
|
|
|
171
190
|
${chalk.cyan('4. Template style:')}
|
|
172
191
|
- Clear, concise summary line
|
|
@@ -292,11 +311,20 @@ ${chalk.yellow('.principal-views/data-validator.otel.canvas')}
|
|
|
292
311
|
"text": "# validation.started\\n\\nEmitted when validation begins",
|
|
293
312
|
"x": 0, "y": 0, "width": 200, "height": 100,
|
|
294
313
|
"pv": {
|
|
295
|
-
"
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
314
|
+
"event": "validation.started",
|
|
315
|
+
"sources": ["src/validator.ts"],
|
|
316
|
+
"otel": {
|
|
317
|
+
"kind": "event",
|
|
318
|
+
"category": "lifecycle"
|
|
319
|
+
},
|
|
320
|
+
"dataSchema": {
|
|
321
|
+
"input.recordCount": {
|
|
322
|
+
"type": "number",
|
|
323
|
+
"required": true
|
|
324
|
+
},
|
|
325
|
+
"input.source": {
|
|
326
|
+
"type": "string",
|
|
327
|
+
"required": false
|
|
300
328
|
}
|
|
301
329
|
}
|
|
302
330
|
}
|
|
@@ -307,11 +335,24 @@ ${chalk.yellow('.principal-views/data-validator.otel.canvas')}
|
|
|
307
335
|
"text": "# validation.complete\\n\\nEmitted when validation succeeds",
|
|
308
336
|
"x": 250, "y": 0, "width": 200, "height": 100,
|
|
309
337
|
"pv": {
|
|
310
|
-
"
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
338
|
+
"event": "validation.complete",
|
|
339
|
+
"sources": ["src/validator.ts"],
|
|
340
|
+
"otel": {
|
|
341
|
+
"kind": "event",
|
|
342
|
+
"category": "lifecycle"
|
|
343
|
+
},
|
|
344
|
+
"dataSchema": {
|
|
345
|
+
"result.validCount": {
|
|
346
|
+
"type": "number",
|
|
347
|
+
"required": true
|
|
348
|
+
},
|
|
349
|
+
"result.invalidCount": {
|
|
350
|
+
"type": "number",
|
|
351
|
+
"required": true
|
|
352
|
+
},
|
|
353
|
+
"duration.ms": {
|
|
354
|
+
"type": "number",
|
|
355
|
+
"required": false
|
|
315
356
|
}
|
|
316
357
|
}
|
|
317
358
|
}
|
|
@@ -322,11 +363,24 @@ ${chalk.yellow('.principal-views/data-validator.otel.canvas')}
|
|
|
322
363
|
"text": "# validation.error\\n\\nEmitted when validation fails",
|
|
323
364
|
"x": 500, "y": 0, "width": 200, "height": 100,
|
|
324
365
|
"pv": {
|
|
325
|
-
"
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
366
|
+
"event": "validation.error",
|
|
367
|
+
"sources": ["src/validator.ts"],
|
|
368
|
+
"otel": {
|
|
369
|
+
"kind": "event",
|
|
370
|
+
"category": "error"
|
|
371
|
+
},
|
|
372
|
+
"dataSchema": {
|
|
373
|
+
"error.type": {
|
|
374
|
+
"type": "string",
|
|
375
|
+
"required": true
|
|
376
|
+
},
|
|
377
|
+
"error.message": {
|
|
378
|
+
"type": "string",
|
|
379
|
+
"required": true
|
|
380
|
+
},
|
|
381
|
+
"error.stage": {
|
|
382
|
+
"type": "string",
|
|
383
|
+
"required": false
|
|
330
384
|
}
|
|
331
385
|
}
|
|
332
386
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/narrative/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/narrative/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,qBAAqB,IAAI,OAAO,CA6N/C"}
|
|
@@ -2,14 +2,15 @@ import { Command } from 'commander';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { resolve, dirname } from 'node:path';
|
|
4
4
|
import { readFileSync } from 'node:fs';
|
|
5
|
-
import { NarrativeValidator } from '@principal-ai/principal-view-core';
|
|
6
|
-
import { loadNarrative, resolvePath } from './utils.js';
|
|
5
|
+
import { NarrativeValidator, computeAggregates } from '@principal-ai/principal-view-core';
|
|
6
|
+
import { loadNarrative, resolvePath, loadExecution, executionToEvents } from './utils.js';
|
|
7
7
|
export function createValidateCommand() {
|
|
8
8
|
const command = new Command('validate');
|
|
9
9
|
command
|
|
10
10
|
.description('Validate narrative template syntax, schema, and references')
|
|
11
11
|
.argument('<file>', 'Path to .narrative.json file')
|
|
12
12
|
.option('--canvas <path>', 'Override canvas file path for validation')
|
|
13
|
+
.option('--execution <path>', 'Execution file (.otel.json) for validating attribute references')
|
|
13
14
|
.option('--json', 'Output violations as JSON')
|
|
14
15
|
.option('-q, --quiet', 'Only show errors, suppress warnings')
|
|
15
16
|
.option('-d, --dir <path>', 'Project directory (default: cwd)')
|
|
@@ -40,6 +41,33 @@ export function createValidateCommand() {
|
|
|
40
41
|
canvas = undefined;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
44
|
+
// Load execution data if provided
|
|
45
|
+
let executionData;
|
|
46
|
+
if (options.execution) {
|
|
47
|
+
try {
|
|
48
|
+
const executionPath = resolvePath(options.execution, baseDir);
|
|
49
|
+
const execution = await loadExecution(executionPath);
|
|
50
|
+
const events = executionToEvents(execution);
|
|
51
|
+
const aggregates = computeAggregates(events);
|
|
52
|
+
// Build event-specific attribute map
|
|
53
|
+
const eventAttributes = new Map();
|
|
54
|
+
for (const event of events) {
|
|
55
|
+
if (!eventAttributes.has(event.name)) {
|
|
56
|
+
eventAttributes.set(event.name, {});
|
|
57
|
+
}
|
|
58
|
+
const attrs = eventAttributes.get(event.name);
|
|
59
|
+
// Merge attributes from this event occurrence
|
|
60
|
+
if (event.attributes) {
|
|
61
|
+
Object.assign(attrs, event.attributes);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
executionData = { aggregates, eventAttributes };
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error(chalk.yellow('Warning:'), `Failed to load execution file: ${error.message}`);
|
|
68
|
+
console.error(chalk.gray(' Attribute validation will be skipped'));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
43
71
|
// Create validator
|
|
44
72
|
const validator = new NarrativeValidator();
|
|
45
73
|
// Validate
|
|
@@ -49,6 +77,7 @@ export function createValidateCommand() {
|
|
|
49
77
|
canvasPath,
|
|
50
78
|
canvas,
|
|
51
79
|
basePath: baseDir,
|
|
80
|
+
executionData,
|
|
52
81
|
};
|
|
53
82
|
const result = await validator.validate(context);
|
|
54
83
|
// Filter violations if quiet mode
|
|
@@ -77,6 +106,7 @@ export function createValidateCommand() {
|
|
|
77
106
|
warnings: warnings.length,
|
|
78
107
|
scenarioCount: narrative.scenarios.length,
|
|
79
108
|
hasDefault: narrative.scenarios.some((s) => s.condition.default),
|
|
109
|
+
attributeValidation: executionData ? 'enabled' : 'skipped',
|
|
80
110
|
},
|
|
81
111
|
};
|
|
82
112
|
console.log(JSON.stringify(output, null, 2));
|
|
@@ -133,6 +163,12 @@ export function createValidateCommand() {
|
|
|
133
163
|
if (canvasPath) {
|
|
134
164
|
console.log(chalk.gray(` • Canvas: ${narrative.canvas || canvasPath}`));
|
|
135
165
|
}
|
|
166
|
+
if (executionData) {
|
|
167
|
+
console.log(chalk.gray(' • Attribute validation:'), chalk.green('enabled'));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.log(chalk.gray(' • Attribute validation:'), chalk.gray('skipped (use --execution to enable)'));
|
|
171
|
+
}
|
|
136
172
|
console.log();
|
|
137
173
|
}
|
|
138
174
|
// Exit with error code if validation failed
|