@principal-ai/principal-view-cli 0.3.1 → 0.3.2
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/package.json +2 -2
- package/dist/commands/coverage.d.ts +0 -9
- package/dist/commands/coverage.d.ts.map +0 -1
- package/dist/commands/coverage.js +0 -158
- package/dist/commands/create.d.ts +0 -6
- package/dist/commands/create.d.ts.map +0 -1
- package/dist/commands/create.js +0 -50
- package/dist/commands/doctor.d.ts +0 -10
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js +0 -274
- package/dist/commands/formats.d.ts +0 -6
- package/dist/commands/formats.d.ts.map +0 -1
- package/dist/commands/formats.js +0 -475
- package/dist/commands/hooks.d.ts +0 -9
- package/dist/commands/hooks.d.ts.map +0 -1
- package/dist/commands/hooks.js +0 -295
- package/dist/commands/init.d.ts +0 -6
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -271
- package/dist/commands/lint.d.ts +0 -6
- package/dist/commands/lint.d.ts.map +0 -1
- package/dist/commands/lint.js +0 -506
- package/dist/commands/list.d.ts +0 -6
- package/dist/commands/list.d.ts.map +0 -1
- package/dist/commands/list.js +0 -80
- package/dist/commands/narrative/eval.d.ts +0 -3
- package/dist/commands/narrative/eval.d.ts.map +0 -1
- package/dist/commands/narrative/eval.js +0 -76
- package/dist/commands/narrative/index.d.ts +0 -3
- package/dist/commands/narrative/index.d.ts.map +0 -1
- package/dist/commands/narrative/index.js +0 -19
- package/dist/commands/narrative/inspect.d.ts +0 -3
- package/dist/commands/narrative/inspect.d.ts.map +0 -1
- package/dist/commands/narrative/inspect.js +0 -109
- package/dist/commands/narrative/list.d.ts +0 -3
- package/dist/commands/narrative/list.d.ts.map +0 -1
- package/dist/commands/narrative/list.js +0 -101
- package/dist/commands/narrative/render.d.ts +0 -3
- package/dist/commands/narrative/render.d.ts.map +0 -1
- package/dist/commands/narrative/render.js +0 -99
- package/dist/commands/narrative/test.d.ts +0 -3
- package/dist/commands/narrative/test.d.ts.map +0 -1
- package/dist/commands/narrative/test.js +0 -150
- package/dist/commands/narrative/utils.d.ts +0 -69
- package/dist/commands/narrative/utils.d.ts.map +0 -1
- package/dist/commands/narrative/utils.js +0 -158
- package/dist/commands/narrative/validate.d.ts +0 -3
- package/dist/commands/narrative/validate.d.ts.map +0 -1
- package/dist/commands/narrative/validate.js +0 -149
- package/dist/commands/schema.d.ts +0 -6
- package/dist/commands/schema.d.ts.map +0 -1
- package/dist/commands/schema.js +0 -336
- package/dist/commands/validate-execution.d.ts +0 -11
- package/dist/commands/validate-execution.d.ts.map +0 -1
- package/dist/commands/validate-execution.js +0 -223
- package/dist/commands/validate.d.ts +0 -6
- package/dist/commands/validate.d.ts.map +0 -1
- package/dist/commands/validate.js +0 -1065
- package/dist/index.cjs +0 -243779
- package/dist/index.cjs.map +0 -7
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -45
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
/**
|
|
4
|
-
* Load a narrative template from a file
|
|
5
|
-
*/
|
|
6
|
-
export async function loadNarrative(filePath) {
|
|
7
|
-
try {
|
|
8
|
-
const content = await readFile(filePath, 'utf-8');
|
|
9
|
-
return JSON.parse(content);
|
|
10
|
-
}
|
|
11
|
-
catch (error) {
|
|
12
|
-
if (error.code === 'ENOENT') {
|
|
13
|
-
throw new Error(`Narrative file not found: ${filePath}`);
|
|
14
|
-
}
|
|
15
|
-
throw new Error(`Failed to parse narrative file: ${error.message}`);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Load execution data from a .otel.json file
|
|
20
|
-
*/
|
|
21
|
-
export async function loadExecution(filePath) {
|
|
22
|
-
try {
|
|
23
|
-
const content = await readFile(filePath, 'utf-8');
|
|
24
|
-
return JSON.parse(content);
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
if (error.code === 'ENOENT') {
|
|
28
|
-
throw new Error(`Execution file not found: ${filePath}`);
|
|
29
|
-
}
|
|
30
|
-
throw new Error(`Failed to parse execution file: ${error.message}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Convert execution data to OtelEvent array format expected by narrative APIs
|
|
35
|
-
*/
|
|
36
|
-
export function executionToEvents(execution) {
|
|
37
|
-
const events = [];
|
|
38
|
-
for (const span of execution.spans) {
|
|
39
|
-
for (const event of span.events) {
|
|
40
|
-
events.push({
|
|
41
|
-
name: event.name,
|
|
42
|
-
timestamp: event.time,
|
|
43
|
-
type: 'log',
|
|
44
|
-
attributes: {
|
|
45
|
-
...event.attributes,
|
|
46
|
-
'span.id': span.id,
|
|
47
|
-
'span.name': span.name,
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return events;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Resolve a file path relative to a base directory
|
|
56
|
-
*/
|
|
57
|
-
export function resolvePath(filePath, baseDir) {
|
|
58
|
-
if (baseDir) {
|
|
59
|
-
return resolve(baseDir, filePath);
|
|
60
|
-
}
|
|
61
|
-
return resolve(filePath);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Format a timestamp as human-readable date/time
|
|
65
|
-
*/
|
|
66
|
-
export function formatTimestamp(timestamp) {
|
|
67
|
-
const date = new Date(timestamp);
|
|
68
|
-
return date.toLocaleString('en-US', {
|
|
69
|
-
year: 'numeric',
|
|
70
|
-
month: '2-digit',
|
|
71
|
-
day: '2-digit',
|
|
72
|
-
hour: '2-digit',
|
|
73
|
-
minute: '2-digit',
|
|
74
|
-
second: '2-digit',
|
|
75
|
-
hour12: false,
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Format duration in milliseconds
|
|
80
|
-
*/
|
|
81
|
-
export function formatDuration(ms) {
|
|
82
|
-
if (ms < 1000) {
|
|
83
|
-
return `${ms}ms`;
|
|
84
|
-
}
|
|
85
|
-
const seconds = (ms / 1000).toFixed(1);
|
|
86
|
-
return `${seconds}s`;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Group attributes by prefix (e.g., 'auth.method' -> 'auth')
|
|
90
|
-
*/
|
|
91
|
-
export function groupAttributesByPrefix(attributes) {
|
|
92
|
-
const grouped = {};
|
|
93
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
94
|
-
const parts = key.split('.');
|
|
95
|
-
if (parts.length > 1) {
|
|
96
|
-
const prefix = parts[0];
|
|
97
|
-
if (!grouped[prefix]) {
|
|
98
|
-
grouped[prefix] = {};
|
|
99
|
-
}
|
|
100
|
-
grouped[prefix][key] = value;
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
if (!grouped['Other']) {
|
|
104
|
-
grouped['Other'] = {};
|
|
105
|
-
}
|
|
106
|
-
grouped['Other'][key] = value;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return grouped;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Filter attributes by pattern (supports glob-like patterns)
|
|
113
|
-
*/
|
|
114
|
-
export function filterAttributes(attributes, pattern) {
|
|
115
|
-
const regex = new RegExp('^' + pattern.replace(/\./g, '\\.').replace(/\*/g, '.*') + '$');
|
|
116
|
-
const filtered = {};
|
|
117
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
118
|
-
if (regex.test(key)) {
|
|
119
|
-
filtered[key] = value;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return filtered;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Count events by type/name
|
|
126
|
-
*/
|
|
127
|
-
export function countEventsByType(events) {
|
|
128
|
-
const counts = new Map();
|
|
129
|
-
for (const event of events) {
|
|
130
|
-
const count = counts.get(event.name) || 0;
|
|
131
|
-
counts.set(event.name, count + 1);
|
|
132
|
-
}
|
|
133
|
-
return counts;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Format attribute value for display
|
|
137
|
-
*/
|
|
138
|
-
export function formatValue(value) {
|
|
139
|
-
if (typeof value === 'string') {
|
|
140
|
-
return `"${value}"`;
|
|
141
|
-
}
|
|
142
|
-
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
143
|
-
return String(value);
|
|
144
|
-
}
|
|
145
|
-
if (value === null || value === undefined) {
|
|
146
|
-
return 'null';
|
|
147
|
-
}
|
|
148
|
-
if (typeof value === 'object') {
|
|
149
|
-
return JSON.stringify(value);
|
|
150
|
-
}
|
|
151
|
-
return String(value);
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Capitalize first letter of a string
|
|
155
|
-
*/
|
|
156
|
-
export function capitalize(str) {
|
|
157
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
158
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/narrative/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,wBAAgB,qBAAqB,IAAI,OAAO,CA0K/C"}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { resolve, dirname } from 'node:path';
|
|
4
|
-
import { readFileSync } from 'node:fs';
|
|
5
|
-
import { NarrativeValidator } from '@principal-ai/principal-view-core';
|
|
6
|
-
import { loadNarrative, resolvePath } from './utils.js';
|
|
7
|
-
export function createValidateCommand() {
|
|
8
|
-
const command = new Command('validate');
|
|
9
|
-
command
|
|
10
|
-
.description('Validate narrative template syntax, schema, and references')
|
|
11
|
-
.argument('<file>', 'Path to .narrative.json file')
|
|
12
|
-
.option('--canvas <path>', 'Override canvas file path for validation')
|
|
13
|
-
.option('--json', 'Output violations as JSON')
|
|
14
|
-
.option('-q, --quiet', 'Only show errors, suppress warnings')
|
|
15
|
-
.option('-d, --dir <path>', 'Project directory (default: cwd)')
|
|
16
|
-
.action(async (file, options) => {
|
|
17
|
-
try {
|
|
18
|
-
const baseDir = options.dir || process.cwd();
|
|
19
|
-
const narrativePath = resolvePath(file, baseDir);
|
|
20
|
-
// Load narrative
|
|
21
|
-
const narrative = await loadNarrative(narrativePath);
|
|
22
|
-
// Resolve canvas path
|
|
23
|
-
let canvasPath;
|
|
24
|
-
let canvas;
|
|
25
|
-
if (options.canvas) {
|
|
26
|
-
canvasPath = resolvePath(options.canvas, baseDir);
|
|
27
|
-
}
|
|
28
|
-
else if (narrative.canvas) {
|
|
29
|
-
const narrativeDir = dirname(narrativePath);
|
|
30
|
-
canvasPath = resolve(narrativeDir, narrative.canvas);
|
|
31
|
-
}
|
|
32
|
-
// Load canvas if path exists
|
|
33
|
-
if (canvasPath) {
|
|
34
|
-
try {
|
|
35
|
-
const canvasContent = readFileSync(canvasPath, 'utf-8');
|
|
36
|
-
canvas = JSON.parse(canvasContent);
|
|
37
|
-
}
|
|
38
|
-
catch (error) {
|
|
39
|
-
// Canvas not found or invalid - will be flagged by validator
|
|
40
|
-
canvas = undefined;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// Create validator
|
|
44
|
-
const validator = new NarrativeValidator();
|
|
45
|
-
// Validate
|
|
46
|
-
const context = {
|
|
47
|
-
narrative,
|
|
48
|
-
narrativePath,
|
|
49
|
-
canvasPath,
|
|
50
|
-
canvas,
|
|
51
|
-
basePath: baseDir,
|
|
52
|
-
};
|
|
53
|
-
const result = await validator.validate(context);
|
|
54
|
-
// Filter violations if quiet mode
|
|
55
|
-
const violations = options.quiet
|
|
56
|
-
? result.violations.filter((v) => v.severity === 'error')
|
|
57
|
-
: result.violations;
|
|
58
|
-
const errors = violations.filter((v) => v.severity === 'error');
|
|
59
|
-
const warnings = violations.filter((v) => v.severity === 'warn');
|
|
60
|
-
// Output
|
|
61
|
-
if (options.json) {
|
|
62
|
-
const output = {
|
|
63
|
-
file: file,
|
|
64
|
-
valid: errors.length === 0,
|
|
65
|
-
violations: violations.map((v) => ({
|
|
66
|
-
severity: v.severity,
|
|
67
|
-
ruleId: v.ruleId,
|
|
68
|
-
file: v.file,
|
|
69
|
-
path: v.path,
|
|
70
|
-
message: v.message,
|
|
71
|
-
impact: v.impact,
|
|
72
|
-
suggestion: v.suggestion,
|
|
73
|
-
fixable: v.fixable,
|
|
74
|
-
})),
|
|
75
|
-
summary: {
|
|
76
|
-
errors: errors.length,
|
|
77
|
-
warnings: warnings.length,
|
|
78
|
-
scenarioCount: narrative.scenarios.length,
|
|
79
|
-
hasDefault: narrative.scenarios.some((s) => s.condition.default),
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
console.log(JSON.stringify(output, null, 2));
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
// Text output
|
|
86
|
-
console.log(chalk.bold(`\nValidating: ${file}\n`));
|
|
87
|
-
if (errors.length === 0 && warnings.length === 0) {
|
|
88
|
-
console.log(chalk.green('✓'), 'Schema validation passed');
|
|
89
|
-
console.log(chalk.green('✓'), `${narrative.scenarios.length} scenarios found`);
|
|
90
|
-
const hasDefault = narrative.scenarios.some((s) => s.condition.default);
|
|
91
|
-
console.log(chalk.green('✓'), hasDefault ? 'Default scenario present' : 'No default scenario');
|
|
92
|
-
const priorities = narrative.scenarios.map((s) => s.priority);
|
|
93
|
-
const allUnique = new Set(priorities).size === priorities.length;
|
|
94
|
-
console.log(chalk.green('✓'), allUnique ? 'All priorities unique' : 'Duplicate priorities found');
|
|
95
|
-
if (canvasPath) {
|
|
96
|
-
console.log(chalk.green('✓'), `Canvas: ${narrative.canvas || canvasPath} ✓`);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
// Show violations
|
|
101
|
-
for (const violation of violations) {
|
|
102
|
-
const icon = violation.severity === 'error' ? chalk.red('✗') : chalk.yellow('⚠');
|
|
103
|
-
const severity = violation.severity === 'error'
|
|
104
|
-
? chalk.red('Error')
|
|
105
|
-
: chalk.yellow('Warning');
|
|
106
|
-
console.log(`\n${icon} ${severity}: ${violation.message}`);
|
|
107
|
-
if (violation.path) {
|
|
108
|
-
console.log(chalk.gray(` Location: ${violation.path}`));
|
|
109
|
-
}
|
|
110
|
-
if (violation.impact) {
|
|
111
|
-
console.log(chalk.gray(` Impact: ${violation.impact}`));
|
|
112
|
-
}
|
|
113
|
-
if (violation.suggestion) {
|
|
114
|
-
console.log(chalk.cyan(` Suggestion: ${violation.suggestion}`));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// Summary
|
|
119
|
-
console.log(chalk.bold('\nSummary:'));
|
|
120
|
-
if (errors.length > 0) {
|
|
121
|
-
console.log(chalk.red(` • ${errors.length} error(s)`));
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
console.log(chalk.green(' • 0 errors'));
|
|
125
|
-
}
|
|
126
|
-
if (warnings.length > 0) {
|
|
127
|
-
console.log(chalk.yellow(` • ${warnings.length} warning(s)`));
|
|
128
|
-
}
|
|
129
|
-
else if (!options.quiet) {
|
|
130
|
-
console.log(chalk.green(' • 0 warnings'));
|
|
131
|
-
}
|
|
132
|
-
console.log(chalk.gray(` • ${narrative.scenarios.length} scenario(s)`));
|
|
133
|
-
if (canvasPath) {
|
|
134
|
-
console.log(chalk.gray(` • Canvas: ${narrative.canvas || canvasPath}`));
|
|
135
|
-
}
|
|
136
|
-
console.log();
|
|
137
|
-
}
|
|
138
|
-
// Exit with error code if validation failed
|
|
139
|
-
if (errors.length > 0) {
|
|
140
|
-
process.exit(1);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
console.error(chalk.red('Error:'), error.message);
|
|
145
|
-
process.exit(1);
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
return command;
|
|
149
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/commands/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8UpC,wBAAgB,mBAAmB,IAAI,OAAO,CA0B7C"}
|
package/dist/commands/schema.js
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema command - Display documentation about the canvas format
|
|
3
|
-
*/
|
|
4
|
-
import { Command } from 'commander';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
const SCHEMA_SECTIONS = {
|
|
7
|
-
overview: `
|
|
8
|
-
${chalk.bold.cyan('Principal View Canvas Schema')}
|
|
9
|
-
${chalk.dim('═'.repeat(50))}
|
|
10
|
-
|
|
11
|
-
Canvas files (.canvas) follow the JSON Canvas spec with Principal View extensions.
|
|
12
|
-
All PV extensions are placed in a ${chalk.yellow('"pv"')} field to maintain compatibility
|
|
13
|
-
with standard canvas tools like Obsidian.
|
|
14
|
-
|
|
15
|
-
${chalk.bold('Required Structure:')}
|
|
16
|
-
${chalk.dim('┌─────────────────────────────────────────────────┐')}
|
|
17
|
-
${chalk.dim('│')} { ${chalk.dim('│')}
|
|
18
|
-
${chalk.dim('│')} ${chalk.green('"nodes"')}: [...], ${chalk.dim('// Required: array of nodes')} ${chalk.dim('│')}
|
|
19
|
-
${chalk.dim('│')} ${chalk.green('"edges"')}: [...], ${chalk.dim('// Optional: array of edges')} ${chalk.dim('│')}
|
|
20
|
-
${chalk.dim('│')} ${chalk.green('"pv"')}: { ${chalk.dim('// Required: PV extension')} ${chalk.dim('│')}
|
|
21
|
-
${chalk.dim('│')} ${chalk.yellow('"name"')}: "...", ${chalk.dim('// Required: graph name')} ${chalk.dim('│')}
|
|
22
|
-
${chalk.dim('│')} ${chalk.yellow('"version"')}: "..." ${chalk.dim('// Required: schema version')} ${chalk.dim('│')}
|
|
23
|
-
${chalk.dim('│')} } ${chalk.dim('│')}
|
|
24
|
-
${chalk.dim('│')} } ${chalk.dim('│')}
|
|
25
|
-
${chalk.dim('└─────────────────────────────────────────────────┘')}
|
|
26
|
-
|
|
27
|
-
Run ${chalk.cyan('npx @principal-ai/principal-view-cli schema <section>')} for details on:
|
|
28
|
-
${chalk.yellow('nodes')} Node types and properties
|
|
29
|
-
${chalk.yellow('edges')} Edge properties and types
|
|
30
|
-
${chalk.yellow('vv')} Principal View extension fields
|
|
31
|
-
${chalk.yellow('examples')} Complete example configurations
|
|
32
|
-
`,
|
|
33
|
-
nodes: `
|
|
34
|
-
${chalk.bold.cyan('Node Schema')}
|
|
35
|
-
${chalk.dim('═'.repeat(50))}
|
|
36
|
-
|
|
37
|
-
${chalk.bold('Required Fields (all nodes):')}
|
|
38
|
-
${chalk.green('id')} ${chalk.dim('string')} Unique identifier
|
|
39
|
-
${chalk.green('type')} ${chalk.dim('string')} Node type (see below)
|
|
40
|
-
${chalk.green('x')} ${chalk.dim('number')} X position in pixels
|
|
41
|
-
${chalk.green('y')} ${chalk.dim('number')} Y position in pixels
|
|
42
|
-
${chalk.green('width')} ${chalk.dim('number')} Width in pixels
|
|
43
|
-
${chalk.green('height')} ${chalk.dim('number')} Height in pixels
|
|
44
|
-
|
|
45
|
-
${chalk.bold('Optional Fields:')}
|
|
46
|
-
${chalk.green('color')} ${chalk.dim('string|number')} Hex color or preset (1-6)
|
|
47
|
-
|
|
48
|
-
${chalk.bold('Standard Node Types:')}
|
|
49
|
-
${chalk.yellow('text')} Text/markdown content node
|
|
50
|
-
Requires: ${chalk.dim('text')} (string)
|
|
51
|
-
|
|
52
|
-
${chalk.yellow('group')} Visual container for other nodes
|
|
53
|
-
Optional: ${chalk.dim('label')}, ${chalk.dim('background')}, ${chalk.dim('backgroundStyle')}
|
|
54
|
-
|
|
55
|
-
${chalk.yellow('file')} Reference to external file
|
|
56
|
-
Requires: ${chalk.dim('file')} (path string)
|
|
57
|
-
Optional: ${chalk.dim('subpath')}
|
|
58
|
-
|
|
59
|
-
${chalk.yellow('link')} URL reference
|
|
60
|
-
Requires: ${chalk.dim('url')} (string)
|
|
61
|
-
|
|
62
|
-
${chalk.bold('Custom Node Types:')}
|
|
63
|
-
Any type not in the standard list requires a ${chalk.yellow('vv')} extension:
|
|
64
|
-
|
|
65
|
-
${chalk.dim('{')}
|
|
66
|
-
${chalk.green('"id"')}: "my-node",
|
|
67
|
-
${chalk.green('"type"')}: "api-gateway", ${chalk.dim('// Custom type')}
|
|
68
|
-
${chalk.green('"x"')}: 100, ${chalk.green('"y"')}: 100,
|
|
69
|
-
${chalk.green('"width"')}: 150, ${chalk.green('"height"')}: 80,
|
|
70
|
-
${chalk.green('"pv"')}: {
|
|
71
|
-
${chalk.yellow('"nodeType"')}: "api-gateway", ${chalk.dim('// Required')}
|
|
72
|
-
${chalk.yellow('"shape"')}: "rectangle", ${chalk.dim('// Required')}
|
|
73
|
-
${chalk.cyan('"fill"')}: "#3b82f6", ${chalk.dim('// Optional: fill color')}
|
|
74
|
-
${chalk.cyan('"stroke"')}: "#1d4ed8", ${chalk.dim('// Optional: border color')}
|
|
75
|
-
${chalk.cyan('"icon"')}: "Server", ${chalk.dim('// Optional: Lucide icon')}
|
|
76
|
-
${chalk.cyan('"sources"')}: ["src/api/**"] ${chalk.dim('// Optional: file patterns')}
|
|
77
|
-
}
|
|
78
|
-
${chalk.dim('}')}
|
|
79
|
-
|
|
80
|
-
${chalk.bold('Valid Shapes:')}
|
|
81
|
-
${chalk.cyan('circle')} Circular node
|
|
82
|
-
${chalk.cyan('rectangle')} Rectangular node (default)
|
|
83
|
-
${chalk.cyan('hexagon')} Hexagonal node
|
|
84
|
-
${chalk.cyan('diamond')} Diamond/rhombus node
|
|
85
|
-
${chalk.cyan('custom')} Custom SVG shape
|
|
86
|
-
|
|
87
|
-
${chalk.bold('Color Presets:')}
|
|
88
|
-
${chalk.red('1')} = red ${chalk.hex('#f97316')('2')} = orange ${chalk.yellow('3')} = yellow
|
|
89
|
-
${chalk.green('4')} = green ${chalk.cyan('5')} = cyan ${chalk.hex('#8b5cf6')('6')} = purple
|
|
90
|
-
`,
|
|
91
|
-
edges: `
|
|
92
|
-
${chalk.bold.cyan('Edge Schema')}
|
|
93
|
-
${chalk.dim('═'.repeat(50))}
|
|
94
|
-
|
|
95
|
-
${chalk.bold('Required Fields:')}
|
|
96
|
-
${chalk.green('id')} ${chalk.dim('string')} Unique identifier
|
|
97
|
-
${chalk.green('fromNode')} ${chalk.dim('string')} Source node ID
|
|
98
|
-
${chalk.green('toNode')} ${chalk.dim('string')} Target node ID
|
|
99
|
-
${chalk.green('fromSide')} ${chalk.dim('string')} Side of source: top, right, bottom, left
|
|
100
|
-
${chalk.green('toSide')} ${chalk.dim('string')} Side of target: top, right, bottom, left
|
|
101
|
-
|
|
102
|
-
${chalk.bold('Optional Fields:')}
|
|
103
|
-
${chalk.green('fromEnd')} ${chalk.dim('string')} Source endpoint: none, arrow
|
|
104
|
-
${chalk.green('toEnd')} ${chalk.dim('string')} Target endpoint: none, arrow (default)
|
|
105
|
-
${chalk.green('color')} ${chalk.dim('string')} Edge color (hex or preset)
|
|
106
|
-
${chalk.green('label')} ${chalk.dim('string')} Edge label text
|
|
107
|
-
|
|
108
|
-
${chalk.bold('PV Edge Extension:')}
|
|
109
|
-
${chalk.dim('{')}
|
|
110
|
-
${chalk.green('"id"')}: "edge-1",
|
|
111
|
-
${chalk.green('"fromNode"')}: "api", ${chalk.green('"toNode"')}: "db",
|
|
112
|
-
${chalk.green('"fromSide"')}: "right", ${chalk.green('"toSide"')}: "left",
|
|
113
|
-
${chalk.green('"pv"')}: {
|
|
114
|
-
${chalk.yellow('"edgeType"')}: "query" ${chalk.dim('// Must be defined in vv.edgeTypes')}
|
|
115
|
-
}
|
|
116
|
-
${chalk.dim('}')}
|
|
117
|
-
|
|
118
|
-
${chalk.bold('Defining Edge Types (in canvas vv):')}
|
|
119
|
-
${chalk.dim('{')}
|
|
120
|
-
${chalk.green('"pv"')}: {
|
|
121
|
-
"name": "My Graph",
|
|
122
|
-
"version": "1.0.0",
|
|
123
|
-
${chalk.yellow('"edgeTypes"')}: {
|
|
124
|
-
"query": {
|
|
125
|
-
${chalk.cyan('"style"')}: "solid", ${chalk.dim('// solid, dashed, dotted, animated')}
|
|
126
|
-
${chalk.cyan('"color"')}: "#64748b", ${chalk.dim('// Hex color')}
|
|
127
|
-
${chalk.cyan('"width"')}: 2, ${chalk.dim('// Line width in pixels')}
|
|
128
|
-
${chalk.cyan('"directed"')}: true, ${chalk.dim('// Show arrow')}
|
|
129
|
-
${chalk.cyan('"animation"')}: { ${chalk.dim('// Optional animation')}
|
|
130
|
-
"type": "flow", ${chalk.dim('// flow, pulse, particle, glow')}
|
|
131
|
-
"duration": 1000 ${chalk.dim('// Duration in ms')}
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
"event": {
|
|
135
|
-
"style": "dashed",
|
|
136
|
-
"color": "#f59e0b"
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
${chalk.dim('}')}
|
|
141
|
-
|
|
142
|
-
${chalk.bold('Edge Styles:')}
|
|
143
|
-
${chalk.cyan('solid')} Solid line
|
|
144
|
-
${chalk.cyan('dashed')} Dashed line
|
|
145
|
-
${chalk.cyan('dotted')} Dotted line
|
|
146
|
-
${chalk.cyan('animated')} Animated flowing line
|
|
147
|
-
|
|
148
|
-
${chalk.bold('Animation Types:')}
|
|
149
|
-
${chalk.cyan('flow')} Flowing dots along the edge
|
|
150
|
-
${chalk.cyan('pulse')} Pulsing glow effect
|
|
151
|
-
${chalk.cyan('particle')} Particle stream
|
|
152
|
-
${chalk.cyan('glow')} Static glow effect
|
|
153
|
-
`,
|
|
154
|
-
vv: `
|
|
155
|
-
${chalk.bold.cyan('Principal View Extension')}
|
|
156
|
-
${chalk.dim('═'.repeat(50))}
|
|
157
|
-
|
|
158
|
-
The ${chalk.yellow('vv')} extension adds rich visualization capabilities while
|
|
159
|
-
maintaining compatibility with standard JSON Canvas tools.
|
|
160
|
-
|
|
161
|
-
${chalk.bold('Canvas-Level pv (Required):')}
|
|
162
|
-
${chalk.dim('{')}
|
|
163
|
-
${chalk.green('"pv"')}: {
|
|
164
|
-
${chalk.yellow('"name"')}: "My Architecture", ${chalk.dim('// Required: Display name')}
|
|
165
|
-
${chalk.yellow('"version"')}: "1.0.0", ${chalk.dim('// Required: Schema version')}
|
|
166
|
-
${chalk.cyan('"description"')}: "...", ${chalk.dim('// Optional: Description')}
|
|
167
|
-
${chalk.cyan('"edgeTypes"')}: {...}, ${chalk.dim('// Optional: Edge type defs')}
|
|
168
|
-
${chalk.cyan('"pathConfig"')}: {...}, ${chalk.dim('// Optional: Path matching')}
|
|
169
|
-
${chalk.cyan('"display"')}: {...} ${chalk.dim('// Optional: Display settings')}
|
|
170
|
-
}
|
|
171
|
-
${chalk.dim('}')}
|
|
172
|
-
|
|
173
|
-
${chalk.bold('Node-Level pv (for custom types):')}
|
|
174
|
-
${chalk.dim('{')}
|
|
175
|
-
${chalk.green('"pv"')}: {
|
|
176
|
-
${chalk.yellow('"nodeType"')}: "service", ${chalk.dim('// Required: Type identifier')}
|
|
177
|
-
${chalk.yellow('"shape"')}: "rectangle", ${chalk.dim('// Required: Visual shape')}
|
|
178
|
-
${chalk.cyan('"fill"')}: "#3b82f6", ${chalk.dim('// Optional: Fill color (hex)')}
|
|
179
|
-
${chalk.cyan('"stroke"')}: "#1d4ed8", ${chalk.dim('// Optional: Border color (hex)')}
|
|
180
|
-
${chalk.cyan('"icon"')}: "Server", ${chalk.dim('// Optional: Lucide icon name')}
|
|
181
|
-
${chalk.cyan('"sources"')}: ["src/**/*.ts"], ${chalk.dim('// Optional: Source patterns')}
|
|
182
|
-
${chalk.cyan('"states"')}: { ${chalk.dim('// Optional: State definitions')}
|
|
183
|
-
"active": { "color": "#22c55e" },
|
|
184
|
-
"error": { "color": "#ef4444" }
|
|
185
|
-
},
|
|
186
|
-
${chalk.cyan('"actions"')}: [{ ${chalk.dim('// Optional: Action patterns')}
|
|
187
|
-
"pattern": "request.*",
|
|
188
|
-
"event": "request",
|
|
189
|
-
"state": "active"
|
|
190
|
-
}]
|
|
191
|
-
}
|
|
192
|
-
${chalk.dim('}')}
|
|
193
|
-
|
|
194
|
-
${chalk.bold('Edge-Level vv:')}
|
|
195
|
-
${chalk.dim('{')}
|
|
196
|
-
${chalk.green('"pv"')}: {
|
|
197
|
-
${chalk.yellow('"edgeType"')}: "query", ${chalk.dim('// References vv.edgeTypes')}
|
|
198
|
-
${chalk.cyan('"style"')}: "solid", ${chalk.dim('// Override: line style')}
|
|
199
|
-
${chalk.cyan('"width"')}: 2, ${chalk.dim('// Override: line width')}
|
|
200
|
-
${chalk.cyan('"animation"')}: {...} ${chalk.dim('// Override: animation')}
|
|
201
|
-
}
|
|
202
|
-
${chalk.dim('}')}
|
|
203
|
-
|
|
204
|
-
${chalk.bold('Path Configuration (vv.pathConfig):')}
|
|
205
|
-
${chalk.cyan('"pathConfig"')}: {
|
|
206
|
-
"projectRoot": "./", ${chalk.dim('// Project root path')}
|
|
207
|
-
"captureSource": true, ${chalk.dim('// Capture source locations')}
|
|
208
|
-
"enableActionPatterns": true, ${chalk.dim('// Enable action matching')}
|
|
209
|
-
"logLevel": "info", ${chalk.dim('// Minimum log level')}
|
|
210
|
-
"ignoreUnsourced": false ${chalk.dim('// Ignore logs without source')}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
${chalk.bold('Display Configuration (vv.display):')}
|
|
214
|
-
${chalk.cyan('"display"')}: {
|
|
215
|
-
"layout": "manual", ${chalk.dim('// manual, hierarchical, force-directed')}
|
|
216
|
-
"theme": {
|
|
217
|
-
"primary": "#3b82f6",
|
|
218
|
-
"success": "#22c55e",
|
|
219
|
-
"warning": "#f59e0b",
|
|
220
|
-
"danger": "#ef4444"
|
|
221
|
-
},
|
|
222
|
-
"animations": {
|
|
223
|
-
"enabled": true,
|
|
224
|
-
"speed": 1.0
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
`,
|
|
228
|
-
examples: `
|
|
229
|
-
${chalk.bold.cyan('Example Configurations')}
|
|
230
|
-
${chalk.dim('═'.repeat(50))}
|
|
231
|
-
|
|
232
|
-
${chalk.bold('Minimal Valid Canvas:')}
|
|
233
|
-
${chalk.dim('─'.repeat(50))}
|
|
234
|
-
{
|
|
235
|
-
"nodes": [
|
|
236
|
-
{
|
|
237
|
-
"id": "node-1",
|
|
238
|
-
"type": "text",
|
|
239
|
-
"x": 100, "y": 100,
|
|
240
|
-
"width": 150, "height": 80,
|
|
241
|
-
"text": "Hello World"
|
|
242
|
-
}
|
|
243
|
-
],
|
|
244
|
-
"edges": [],
|
|
245
|
-
"pv": {
|
|
246
|
-
"name": "My Graph",
|
|
247
|
-
"version": "1.0.0"
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
${chalk.bold('Service Architecture:')}
|
|
252
|
-
${chalk.dim('─'.repeat(50))}
|
|
253
|
-
{
|
|
254
|
-
"nodes": [
|
|
255
|
-
{
|
|
256
|
-
"id": "api",
|
|
257
|
-
"type": "text",
|
|
258
|
-
"x": 100, "y": 100,
|
|
259
|
-
"width": 150, "height": 80,
|
|
260
|
-
"text": "API Gateway",
|
|
261
|
-
"pv": {
|
|
262
|
-
"nodeType": "service",
|
|
263
|
-
"shape": "rectangle",
|
|
264
|
-
"fill": "#3b82f6",
|
|
265
|
-
"stroke": "#1d4ed8",
|
|
266
|
-
"icon": "Server",
|
|
267
|
-
"sources": ["src/api/**/*.ts"]
|
|
268
|
-
}
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
"id": "db",
|
|
272
|
-
"type": "text",
|
|
273
|
-
"x": 350, "y": 100,
|
|
274
|
-
"width": 150, "height": 80,
|
|
275
|
-
"text": "Database",
|
|
276
|
-
"pv": {
|
|
277
|
-
"nodeType": "database",
|
|
278
|
-
"shape": "hexagon",
|
|
279
|
-
"fill": "#8b5cf6",
|
|
280
|
-
"stroke": "#6d28d9",
|
|
281
|
-
"icon": "Database"
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
],
|
|
285
|
-
"edges": [
|
|
286
|
-
{
|
|
287
|
-
"id": "api-to-db",
|
|
288
|
-
"fromNode": "api",
|
|
289
|
-
"toNode": "db",
|
|
290
|
-
"fromSide": "right",
|
|
291
|
-
"toSide": "left",
|
|
292
|
-
"pv": { "edgeType": "query" }
|
|
293
|
-
}
|
|
294
|
-
],
|
|
295
|
-
"pv": {
|
|
296
|
-
"name": "Service Architecture",
|
|
297
|
-
"version": "1.0.0",
|
|
298
|
-
"edgeTypes": {
|
|
299
|
-
"query": {
|
|
300
|
-
"style": "solid",
|
|
301
|
-
"color": "#64748b",
|
|
302
|
-
"width": 2,
|
|
303
|
-
"animation": {
|
|
304
|
-
"type": "flow",
|
|
305
|
-
"duration": 1500
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
${chalk.bold('Run validation:')} ${chalk.cyan('npx @principal-ai/principal-view-cli validate <file>')}
|
|
313
|
-
${chalk.bold('Initialize project:')} ${chalk.cyan('npx @principal-ai/principal-view-cli init')}
|
|
314
|
-
`,
|
|
315
|
-
};
|
|
316
|
-
export function createSchemaCommand() {
|
|
317
|
-
const command = new Command('schema');
|
|
318
|
-
command
|
|
319
|
-
.description('Display documentation about the canvas schema')
|
|
320
|
-
.argument('[section]', 'Section to display: overview, nodes, edges, vv, examples')
|
|
321
|
-
.action((section) => {
|
|
322
|
-
const validSections = Object.keys(SCHEMA_SECTIONS);
|
|
323
|
-
if (!section) {
|
|
324
|
-
console.log(SCHEMA_SECTIONS.overview);
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
327
|
-
const normalizedSection = section.toLowerCase();
|
|
328
|
-
if (!validSections.includes(normalizedSection)) {
|
|
329
|
-
console.log(chalk.red(`Unknown section: ${section}`));
|
|
330
|
-
console.log(`Valid sections: ${validSections.join(', ')}`);
|
|
331
|
-
process.exit(1);
|
|
332
|
-
}
|
|
333
|
-
console.log(SCHEMA_SECTIONS[normalizedSection]);
|
|
334
|
-
});
|
|
335
|
-
return command;
|
|
336
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validate execution files command
|
|
3
|
-
*
|
|
4
|
-
* Validates .otel.json files to ensure they conform to the expected ExecutionData structure.
|
|
5
|
-
*/
|
|
6
|
-
import { Command } from 'commander';
|
|
7
|
-
/**
|
|
8
|
-
* Create the validate-execution command
|
|
9
|
-
*/
|
|
10
|
-
export declare function createValidateExecutionCommand(): Command;
|
|
11
|
-
//# sourceMappingURL=validate-execution.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate-execution.d.ts","sourceRoot":"","sources":["../../src/commands/validate-execution.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqJpC;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,OAAO,CAwGxD"}
|