@principal-ai/principal-view-cli 0.1.29 → 0.1.31
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/commands/lint.d.ts.map +1 -1
- package/dist/commands/lint.js +160 -34
- package/dist/commands/narrative/eval.d.ts +3 -0
- package/dist/commands/narrative/eval.d.ts.map +1 -0
- package/dist/commands/narrative/eval.js +76 -0
- package/dist/commands/narrative/index.d.ts +3 -0
- package/dist/commands/narrative/index.d.ts.map +1 -0
- package/dist/commands/narrative/index.js +19 -0
- package/dist/commands/narrative/inspect.d.ts +3 -0
- package/dist/commands/narrative/inspect.d.ts.map +1 -0
- package/dist/commands/narrative/inspect.js +109 -0
- package/dist/commands/narrative/list.d.ts +3 -0
- package/dist/commands/narrative/list.d.ts.map +1 -0
- package/dist/commands/narrative/list.js +101 -0
- package/dist/commands/narrative/render.d.ts +3 -0
- package/dist/commands/narrative/render.d.ts.map +1 -0
- package/dist/commands/narrative/render.js +99 -0
- package/dist/commands/narrative/test.d.ts +3 -0
- package/dist/commands/narrative/test.d.ts.map +1 -0
- package/dist/commands/narrative/test.js +150 -0
- package/dist/commands/narrative/utils.d.ts +69 -0
- package/dist/commands/narrative/utils.d.ts.map +1 -0
- package/dist/commands/narrative/utils.js +158 -0
- package/dist/commands/narrative/validate.d.ts +3 -0
- package/dist/commands/narrative/validate.d.ts.map +1 -0
- package/dist/commands/narrative/validate.js +135 -0
- package/dist/commands/validate-execution.d.ts +12 -0
- package/dist/commands/validate-execution.d.ts.map +1 -0
- package/dist/commands/validate-execution.js +230 -0
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +0 -4
- package/dist/index.js +4 -0
- package/package.json +3 -2
- package/dist/index.cjs +0 -24272
- package/dist/index.cjs.map +0 -7
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate execution files command
|
|
3
|
+
*
|
|
4
|
+
* Validates .spans.json, .execution.json, .otel.json, and .events.json files
|
|
5
|
+
* to ensure they conform to the expected ExecutionData structure.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { readFileSync } from 'node:fs';
|
|
9
|
+
import { resolve, relative } from 'node:path';
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
import { globby } from 'globby';
|
|
12
|
+
import { createExecutionValidator } from '@principal-ai/principal-view-core';
|
|
13
|
+
/**
|
|
14
|
+
* Load and parse an execution file
|
|
15
|
+
*/
|
|
16
|
+
function loadExecutionFile(filePath) {
|
|
17
|
+
try {
|
|
18
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
19
|
+
return JSON.parse(content);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new Error(`Failed to parse JSON: ${error.message}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Format validation results for console output
|
|
27
|
+
*/
|
|
28
|
+
function formatConsoleOutput(results, options) {
|
|
29
|
+
const lines = [];
|
|
30
|
+
let totalErrors = 0;
|
|
31
|
+
let totalWarnings = 0;
|
|
32
|
+
for (const { file, result } of results) {
|
|
33
|
+
totalErrors += result.errors.length;
|
|
34
|
+
totalWarnings += result.warnings.length;
|
|
35
|
+
// If quiet mode, only show files with issues
|
|
36
|
+
if (options.quiet && result.valid && result.warnings.length === 0) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
// Show file status
|
|
40
|
+
if (result.valid && result.warnings.length === 0) {
|
|
41
|
+
lines.push(chalk.green(`✓ ${file}`));
|
|
42
|
+
}
|
|
43
|
+
else if (result.valid && result.warnings.length > 0) {
|
|
44
|
+
lines.push(chalk.yellow(`⚠ ${file}`));
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
lines.push(chalk.red(`✗ ${file}`));
|
|
48
|
+
}
|
|
49
|
+
// Show errors
|
|
50
|
+
if (result.errors.length > 0) {
|
|
51
|
+
lines.push('');
|
|
52
|
+
result.errors.forEach((error) => {
|
|
53
|
+
lines.push(chalk.red(` ERROR: ${error.path}`));
|
|
54
|
+
lines.push(` ${error.message}`);
|
|
55
|
+
if (error.suggestion) {
|
|
56
|
+
lines.push(chalk.dim(` → ${error.suggestion}`));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
lines.push('');
|
|
60
|
+
}
|
|
61
|
+
// Show warnings
|
|
62
|
+
if (result.warnings.length > 0) {
|
|
63
|
+
lines.push('');
|
|
64
|
+
result.warnings.forEach((warning) => {
|
|
65
|
+
lines.push(chalk.yellow(` WARN: ${warning.path}`));
|
|
66
|
+
lines.push(` ${warning.message}`);
|
|
67
|
+
if (warning.suggestion) {
|
|
68
|
+
lines.push(chalk.dim(` → ${warning.suggestion}`));
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
lines.push('');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Summary
|
|
75
|
+
lines.push('');
|
|
76
|
+
if (totalErrors === 0 && totalWarnings === 0) {
|
|
77
|
+
lines.push(chalk.green(`✓ All ${results.length} file${results.length === 1 ? '' : 's'} passed validation`));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const parts = [];
|
|
81
|
+
if (totalErrors > 0) {
|
|
82
|
+
parts.push(chalk.red(`${totalErrors} error${totalErrors === 1 ? '' : 's'}`));
|
|
83
|
+
}
|
|
84
|
+
if (totalWarnings > 0) {
|
|
85
|
+
parts.push(chalk.yellow(`${totalWarnings} warning${totalWarnings === 1 ? '' : 's'}`));
|
|
86
|
+
}
|
|
87
|
+
lines.push(`✖ ${parts.join(', ')} found in ${results.length} file${results.length === 1 ? '' : 's'}`);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
output: lines.join('\n'),
|
|
91
|
+
hasErrors: totalErrors > 0,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Format validation results as JSON
|
|
96
|
+
*/
|
|
97
|
+
function formatJsonOutput(results) {
|
|
98
|
+
let totalErrors = 0;
|
|
99
|
+
let totalWarnings = 0;
|
|
100
|
+
const files = results.map(({ file, result }) => {
|
|
101
|
+
totalErrors += result.errors.length;
|
|
102
|
+
totalWarnings += result.warnings.length;
|
|
103
|
+
return {
|
|
104
|
+
file,
|
|
105
|
+
valid: result.valid,
|
|
106
|
+
errorCount: result.errors.length,
|
|
107
|
+
warningCount: result.warnings.length,
|
|
108
|
+
errors: result.errors,
|
|
109
|
+
warnings: result.warnings,
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
files,
|
|
114
|
+
summary: {
|
|
115
|
+
totalFiles: files.length,
|
|
116
|
+
totalErrors,
|
|
117
|
+
totalWarnings,
|
|
118
|
+
validFiles: files.filter((f) => f.valid).length,
|
|
119
|
+
invalidFiles: files.filter((f) => !f.valid).length,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Create the validate-execution command
|
|
125
|
+
*/
|
|
126
|
+
export function createValidateExecutionCommand() {
|
|
127
|
+
const command = new Command('validate-execution');
|
|
128
|
+
command
|
|
129
|
+
.description('Validate execution files (.spans.json, .execution.json, .otel.json, .events.json)')
|
|
130
|
+
.argument('[files...]', 'Files or glob patterns to validate (defaults to **/__executions__/**/*.json)')
|
|
131
|
+
.option('--json', 'Output results as JSON')
|
|
132
|
+
.option('-q, --quiet', 'Only show files with errors or warnings')
|
|
133
|
+
.action(async (files, options) => {
|
|
134
|
+
try {
|
|
135
|
+
const cwd = process.cwd();
|
|
136
|
+
const validator = createExecutionValidator();
|
|
137
|
+
// Determine files to validate
|
|
138
|
+
let patterns;
|
|
139
|
+
if (files.length > 0) {
|
|
140
|
+
patterns = files;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// Default: find all execution files in __executions__ directories
|
|
144
|
+
patterns = [
|
|
145
|
+
'**/__executions__/*.spans.json',
|
|
146
|
+
'**/__executions__/*.execution.json',
|
|
147
|
+
'**/__executions__/*.otel.json',
|
|
148
|
+
'**/__executions__/*.events.json',
|
|
149
|
+
'.principal-views/__executions__/*.spans.json',
|
|
150
|
+
'.principal-views/__executions__/*.execution.json',
|
|
151
|
+
'.principal-views/__executions__/*.otel.json',
|
|
152
|
+
'.principal-views/__executions__/*.events.json',
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
// Find matching files
|
|
156
|
+
const matchedFiles = await globby(patterns, {
|
|
157
|
+
ignore: ['**/node_modules/**'],
|
|
158
|
+
absolute: false,
|
|
159
|
+
});
|
|
160
|
+
if (matchedFiles.length === 0) {
|
|
161
|
+
if (options.json) {
|
|
162
|
+
console.log(JSON.stringify({
|
|
163
|
+
files: [],
|
|
164
|
+
summary: {
|
|
165
|
+
totalFiles: 0,
|
|
166
|
+
totalErrors: 0,
|
|
167
|
+
totalWarnings: 0,
|
|
168
|
+
validFiles: 0,
|
|
169
|
+
invalidFiles: 0,
|
|
170
|
+
},
|
|
171
|
+
}));
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
console.log(chalk.yellow('No execution files found matching the specified patterns.'));
|
|
175
|
+
console.log(chalk.dim(`Patterns searched: ${patterns.join(', ')}`));
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// Validate each file
|
|
180
|
+
const results = [];
|
|
181
|
+
for (const filePath of matchedFiles) {
|
|
182
|
+
const absolutePath = resolve(cwd, filePath);
|
|
183
|
+
const relativePath = relative(cwd, absolutePath);
|
|
184
|
+
try {
|
|
185
|
+
const data = loadExecutionFile(absolutePath);
|
|
186
|
+
const result = validator.validate(data, relativePath);
|
|
187
|
+
results.push({ file: relativePath, result });
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
// Parse error
|
|
191
|
+
results.push({
|
|
192
|
+
file: relativePath,
|
|
193
|
+
result: {
|
|
194
|
+
valid: false,
|
|
195
|
+
errors: [
|
|
196
|
+
{
|
|
197
|
+
path: relativePath,
|
|
198
|
+
message: error.message,
|
|
199
|
+
severity: 'error',
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
warnings: [],
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Output results
|
|
208
|
+
if (options.json) {
|
|
209
|
+
console.log(JSON.stringify(formatJsonOutput(results), null, 2));
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
const { output, hasErrors } = formatConsoleOutput(results, options);
|
|
213
|
+
console.log(output);
|
|
214
|
+
if (hasErrors) {
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
if (options.json) {
|
|
221
|
+
console.log(JSON.stringify({ error: error.message }));
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
console.error(chalk.red('Error:'), error.message);
|
|
225
|
+
}
|
|
226
|
+
process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
return command;
|
|
230
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAunCpC,wBAAgB,qBAAqB,IAAI,OAAO,CAsH/C"}
|
|
@@ -121,10 +121,6 @@ function validateLibrary(library) {
|
|
|
121
121
|
* Standard JSON Canvas node types that don't require pv metadata
|
|
122
122
|
*/
|
|
123
123
|
const STANDARD_CANVAS_TYPES = ['text', 'group', 'file', 'link'];
|
|
124
|
-
/**
|
|
125
|
-
* Valid node shapes for pv.shape
|
|
126
|
-
*/
|
|
127
|
-
const VALID_NODE_SHAPES = ['circle', 'rectangle', 'hexagon', 'diamond', 'custom'];
|
|
128
124
|
// ============================================================================
|
|
129
125
|
// Icon Validation
|
|
130
126
|
// ============================================================================
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { Command } from 'commander';
|
|
8
8
|
import { createValidateCommand } from './commands/validate.js';
|
|
9
|
+
import { createValidateExecutionCommand } from './commands/validate-execution.js';
|
|
9
10
|
import { createInitCommand } from './commands/init.js';
|
|
10
11
|
import { createListCommand } from './commands/list.js';
|
|
11
12
|
import { createSchemaCommand } from './commands/schema.js';
|
|
@@ -14,6 +15,7 @@ import { createHooksCommand } from './commands/hooks.js';
|
|
|
14
15
|
import { createCreateCommand } from './commands/create.js';
|
|
15
16
|
import { createLintCommand } from './commands/lint.js';
|
|
16
17
|
import { createCoverageCommand } from './commands/coverage.js';
|
|
18
|
+
import { createNarrativeCommand } from './commands/narrative/index.js';
|
|
17
19
|
// Version is injected at build time via package.json
|
|
18
20
|
const VERSION = '0.1.28';
|
|
19
21
|
const program = new Command();
|
|
@@ -25,12 +27,14 @@ program
|
|
|
25
27
|
program.addCommand(createInitCommand());
|
|
26
28
|
program.addCommand(createCreateCommand());
|
|
27
29
|
program.addCommand(createValidateCommand());
|
|
30
|
+
program.addCommand(createValidateExecutionCommand());
|
|
28
31
|
program.addCommand(createLintCommand());
|
|
29
32
|
program.addCommand(createListCommand());
|
|
30
33
|
program.addCommand(createSchemaCommand());
|
|
31
34
|
program.addCommand(createDoctorCommand());
|
|
32
35
|
program.addCommand(createHooksCommand());
|
|
33
36
|
program.addCommand(createCoverageCommand());
|
|
37
|
+
program.addCommand(createNarrativeCommand());
|
|
34
38
|
// Parse command line arguments
|
|
35
39
|
program.parse(process.argv);
|
|
36
40
|
// Show help if no command provided
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@principal-ai/principal-view-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"description": "Principal View CLI - Validate and manage .canvas configuration files",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -34,11 +34,12 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"chalk": "5.6.2",
|
|
36
36
|
"commander": "14.0.2",
|
|
37
|
+
"glob": "^13.0.0",
|
|
37
38
|
"globby": "16.0.0",
|
|
38
39
|
"js-yaml": "4.1.1"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"@principal-ai/principal-view-core": "
|
|
42
|
+
"@principal-ai/principal-view-core": "0.7.12",
|
|
42
43
|
"@types/js-yaml": "4.0.9",
|
|
43
44
|
"@types/node": "22.10.1",
|
|
44
45
|
"esbuild": "0.24.0",
|