@principal-ai/principal-view-core 0.5.17 → 0.6.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.
package/dist/index.d.ts CHANGED
@@ -13,6 +13,8 @@ export { PathBasedEventProcessor } from './PathBasedEventProcessor';
13
13
  export type { LogEntry } from './PathBasedEventProcessor';
14
14
  export { PathMatcher } from './utils/PathMatcher';
15
15
  export { GraphConverter } from './utils/GraphConverter';
16
+ export { ExecutionFileDiscovery } from './utils/ExecutionFileDiscovery';
17
+ export type { ExecutionFile, CanvasFile, PackageContext, ExecutionMetadata, ExecutionSpan, ExecutionArtifact, FileTreeEntry, DiscoveryOptions, } from './utils/ExecutionFileDiscovery';
16
18
  export * from './types/canvas';
17
19
  export { CanvasConverter } from './utils/CanvasConverter';
18
20
  export type { ReactFlowNode, ReactFlowEdge } from './utils/CanvasConverter';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EACV,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAGlF,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG5E,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3G,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG5G,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACjG,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAG7F,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACzE,YAAY,EACV,SAAS,EACT,WAAW,EACX,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EACV,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AACtF,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGrF,YAAY,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAGjF,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -15,6 +15,8 @@ export { PathBasedEventProcessor } from './PathBasedEventProcessor';
15
15
  // Export path utilities
16
16
  export { PathMatcher } from './utils/PathMatcher';
17
17
  export { GraphConverter } from './utils/GraphConverter';
18
+ // Export execution file discovery
19
+ export { ExecutionFileDiscovery } from './utils/ExecutionFileDiscovery';
18
20
  // Export Canvas types and converter
19
21
  export * from './types/canvas';
20
22
  export { CanvasConverter } from './utils/CanvasConverter';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mBAAmB;AACnB,cAAc,SAAS,CAAC;AAExB,sBAAsB;AACtB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAMlE,iBAAiB;AACjB,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAElF,iDAAiD;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAGpE,wBAAwB;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,oCAAoC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,oCAAoC;AACpC,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAG3G,qCAAqC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,yBAAyB;AACzB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGjG,oCAAoC;AACpC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAQzE,qDAAqD;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAYlD,gCAAgC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAqB9D,+DAA+D;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAGtF,mCAAmC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAK5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAEjF,sBAAsB;AACtB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mBAAmB;AACnB,cAAc,SAAS,CAAC;AAExB,sBAAsB;AACtB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAMlE,iBAAiB;AACjB,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAElF,iDAAiD;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAGpE,wBAAwB;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,kCAAkC;AAClC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAYxE,oCAAoC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,oCAAoC;AACpC,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAG3G,qCAAqC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,yBAAyB;AACzB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGjG,oCAAoC;AACpC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAQzE,qDAAqD;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAYlD,gCAAgC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAqB9D,+DAA+D;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAGtF,mCAAmC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAK5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAEjF,sBAAsB;AACtB,cAAc,SAAS,CAAC"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Execution File Discovery
3
+ *
4
+ * Discovers execution artifacts and canvas files in a repository with monorepo awareness.
5
+ * Uses codebase-composition (browser-safe export) to intelligently detect package boundaries
6
+ * and workspace patterns.
7
+ */
8
+ /**
9
+ * Represents a discovered execution artifact file
10
+ */
11
+ export interface ExecutionFile {
12
+ /** Unique identifier for this execution */
13
+ id: string;
14
+ /** Display name for this execution */
15
+ name: string;
16
+ /** Full file path (relative to repository root) */
17
+ path: string;
18
+ /** Canvas basename (without extension) that this execution is linked to */
19
+ canvasBasename: string;
20
+ /** Package context if this execution belongs to a specific package */
21
+ packageContext?: PackageContext;
22
+ }
23
+ /**
24
+ * Represents a discovered canvas file
25
+ */
26
+ export interface CanvasFile {
27
+ /** Unique identifier for this canvas */
28
+ id: string;
29
+ /** Display name for this canvas */
30
+ name: string;
31
+ /** Full file path (relative to repository root) */
32
+ path: string;
33
+ /** Canvas basename (without .otel.canvas or .canvas extension) */
34
+ basename: string;
35
+ /** Package context if this canvas belongs to a specific package */
36
+ packageContext?: PackageContext;
37
+ }
38
+ /**
39
+ * Package context for execution/canvas files
40
+ */
41
+ export interface PackageContext {
42
+ /** Package name (from package.json, Cargo.toml, etc.) */
43
+ name: string;
44
+ /** Package directory path (relative to repository root) */
45
+ packagePath: string;
46
+ /** Package type (npm, cargo, go, etc.) */
47
+ packageType?: string;
48
+ }
49
+ /**
50
+ * Execution artifact metadata
51
+ */
52
+ export interface ExecutionMetadata {
53
+ name: string;
54
+ canvasName?: string;
55
+ exportedAt?: string;
56
+ source?: string;
57
+ framework?: string;
58
+ status?: 'success' | 'error' | 'OK';
59
+ spanCount: number;
60
+ eventCount: number;
61
+ }
62
+ /**
63
+ * Execution span structure
64
+ */
65
+ export interface ExecutionSpan {
66
+ id: string;
67
+ name: string;
68
+ startTime: number;
69
+ endTime?: number;
70
+ duration?: number;
71
+ status?: string;
72
+ attributes?: Record<string, any>;
73
+ events: Array<{
74
+ time: number;
75
+ name: string;
76
+ attributes?: Record<string, any>;
77
+ }>;
78
+ }
79
+ /**
80
+ * Execution artifact file structure
81
+ */
82
+ export interface ExecutionArtifact {
83
+ metadata?: {
84
+ canvasName?: string;
85
+ exportedAt?: string;
86
+ source?: string;
87
+ framework?: string;
88
+ status?: 'success' | 'error';
89
+ };
90
+ spans: ExecutionSpan[];
91
+ }
92
+ /**
93
+ * File tree entry for discovery
94
+ */
95
+ export interface FileTreeEntry {
96
+ path?: string;
97
+ relativePath?: string;
98
+ name?: string;
99
+ }
100
+ /**
101
+ * Options for execution file discovery
102
+ */
103
+ export interface DiscoveryOptions {
104
+ /** Whether to include package-level .principal-views folders */
105
+ includePackagePrincipalViews?: boolean;
106
+ /** Custom execution folder names (defaults to ['__executions__']) */
107
+ executionFolders?: string[];
108
+ /** Custom canvas extensions (defaults to ['.otel.canvas']) */
109
+ canvasExtensions?: string[];
110
+ }
111
+ /**
112
+ * Execution File Discovery Engine
113
+ *
114
+ * Discovers execution artifacts and canvas files using monorepo-aware logic.
115
+ */
116
+ export declare class ExecutionFileDiscovery {
117
+ private packageLayerModule;
118
+ private options;
119
+ constructor(options?: DiscoveryOptions);
120
+ /**
121
+ * Find all execution artifact files in the repository
122
+ */
123
+ findExecutionFiles(files: FileTreeEntry[]): Promise<ExecutionFile[]>;
124
+ /**
125
+ * Find all canvas files in the repository
126
+ */
127
+ findCanvasFiles(files: FileTreeEntry[]): Promise<CanvasFile[]>;
128
+ /**
129
+ * Find execution artifact for a given canvas
130
+ * Now package-aware - can disambiguate between packages
131
+ */
132
+ findExecutionForCanvas(canvas: CanvasFile, executionFiles: ExecutionFile[]): ExecutionFile | null;
133
+ /**
134
+ * Find canvas file for a given execution
135
+ */
136
+ findCanvasForExecution(execution: ExecutionFile, canvasFiles: CanvasFile[]): CanvasFile | null;
137
+ /**
138
+ * Parse execution artifact JSON
139
+ */
140
+ static parseExecutionArtifact(content: string): ExecutionArtifact;
141
+ /**
142
+ * Get spans from an artifact
143
+ */
144
+ static getSpans(artifact: ExecutionArtifact): ExecutionSpan[];
145
+ /**
146
+ * Extract metadata from an execution artifact
147
+ */
148
+ static getExecutionMetadata(artifact: ExecutionArtifact): ExecutionMetadata;
149
+ /**
150
+ * Detect packages using codebase-composition
151
+ */
152
+ private detectPackages;
153
+ /**
154
+ * Convert file entries to file tree format for codebase-composition
155
+ */
156
+ private convertToFileTree;
157
+ /**
158
+ * Find executions in a specific package
159
+ */
160
+ private findExecutionsInPackage;
161
+ /**
162
+ * Find executions in root-level locations
163
+ */
164
+ private findExecutionsInRoot;
165
+ /**
166
+ * Find canvas files in a specific directory
167
+ */
168
+ private findCanvasesInDirectory;
169
+ /**
170
+ * Create package context from PackageLayer
171
+ */
172
+ private createPackageContext;
173
+ /**
174
+ * Check if filename is an execution file
175
+ */
176
+ private isExecutionFile;
177
+ /**
178
+ * Check if filename is a canvas file
179
+ */
180
+ private isCanvasFile;
181
+ /**
182
+ * Extract basename from execution filename
183
+ */
184
+ private extractExecutionBasename;
185
+ /**
186
+ * Extract basename from canvas filename
187
+ */
188
+ private extractCanvasBasename;
189
+ /**
190
+ * Format display name from basename (kebab-case to Title Case)
191
+ */
192
+ private formatDisplayName;
193
+ /**
194
+ * Generate unique ID for execution file
195
+ */
196
+ private generateExecutionId;
197
+ /**
198
+ * Generate unique ID for canvas file
199
+ */
200
+ private generateCanvasId;
201
+ /**
202
+ * Sort execution files by package name, then by basename
203
+ */
204
+ private sortExecutionFiles;
205
+ }
206
+ //# sourceMappingURL=ExecutionFileDiscovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecutionFileDiscovery.d.ts","sourceRoot":"","sources":["../../src/utils/ExecutionFileDiscovery.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,cAAc,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAClC,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE;QACT,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;KAC9B,CAAC;IACF,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;GAIG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,OAAO,CAA6B;gBAEhC,OAAO,GAAE,gBAAqB;IAS1C;;OAEG;IACG,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAoB1E;;OAEG;IACG,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA0BpE;;;OAGG;IACH,sBAAsB,CACpB,MAAM,EAAE,UAAU,EAClB,cAAc,EAAE,aAAa,EAAE,GAC9B,aAAa,GAAG,IAAI;IAevB;;OAEG;IACH,sBAAsB,CACpB,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,UAAU,EAAE,GACxB,UAAU,GAAG,IAAI;IAepB;;OAEG;IACH,MAAM,CAAC,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IASjE;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,aAAa,EAAE;IAI7D;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,iBAAiB;IAkC3E;;OAEG;YACW,cAAc;IAa5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA+B/B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAyC5B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA0B/B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAQ5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAIhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAS7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAgB3B"}
@@ -0,0 +1,340 @@
1
+ /**
2
+ * Execution File Discovery
3
+ *
4
+ * Discovers execution artifacts and canvas files in a repository with monorepo awareness.
5
+ * Uses codebase-composition (browser-safe export) to intelligently detect package boundaries
6
+ * and workspace patterns.
7
+ */
8
+ import { PackageLayerModule } from '@principal-ai/codebase-composition/browser';
9
+ /**
10
+ * Execution File Discovery Engine
11
+ *
12
+ * Discovers execution artifacts and canvas files using monorepo-aware logic.
13
+ */
14
+ export class ExecutionFileDiscovery {
15
+ constructor(options = {}) {
16
+ this.packageLayerModule = new PackageLayerModule();
17
+ this.options = {
18
+ includePackagePrincipalViews: options.includePackagePrincipalViews ?? true,
19
+ executionFolders: options.executionFolders ?? ['__executions__'],
20
+ canvasExtensions: options.canvasExtensions ?? ['.otel.canvas'],
21
+ };
22
+ }
23
+ /**
24
+ * Find all execution artifact files in the repository
25
+ */
26
+ async findExecutionFiles(files) {
27
+ const executionFiles = [];
28
+ // Detect packages in the repository
29
+ const packages = await this.detectPackages(files);
30
+ // Search for execution files in each package
31
+ for (const pkg of packages) {
32
+ const pkgExecutions = this.findExecutionsInPackage(pkg, files);
33
+ executionFiles.push(...pkgExecutions);
34
+ }
35
+ // Search in root-level locations
36
+ const rootExecutions = this.findExecutionsInRoot(files);
37
+ executionFiles.push(...rootExecutions);
38
+ // Sort by package name, then by basename
39
+ return this.sortExecutionFiles(executionFiles);
40
+ }
41
+ /**
42
+ * Find all canvas files in the repository
43
+ */
44
+ async findCanvasFiles(files) {
45
+ const canvasFiles = [];
46
+ // Detect packages in the repository
47
+ const packages = await this.detectPackages(files);
48
+ // Search for canvas files in root .principal-views/
49
+ const rootCanvases = this.findCanvasesInDirectory('.principal-views', files);
50
+ canvasFiles.push(...rootCanvases);
51
+ // Search for canvas files in package-level .principal-views/ if enabled
52
+ if (this.options.includePackagePrincipalViews) {
53
+ for (const pkg of packages) {
54
+ const pkgCanvases = this.findCanvasesInDirectory(`${pkg.packageData.path}/.principal-views`, files, this.createPackageContext(pkg));
55
+ canvasFiles.push(...pkgCanvases);
56
+ }
57
+ }
58
+ // Sort by name
59
+ return canvasFiles.sort((a, b) => a.name.localeCompare(b.name));
60
+ }
61
+ /**
62
+ * Find execution artifact for a given canvas
63
+ * Now package-aware - can disambiguate between packages
64
+ */
65
+ findExecutionForCanvas(canvas, executionFiles) {
66
+ // First, try exact package match if canvas has package context
67
+ if (canvas.packageContext) {
68
+ const exactMatch = executionFiles.find(exec => exec.canvasBasename === canvas.basename &&
69
+ exec.packageContext?.name === canvas.packageContext?.name);
70
+ if (exactMatch)
71
+ return exactMatch;
72
+ }
73
+ // Fallback to basename-only match (for root-level canvases)
74
+ return executionFiles.find(exec => exec.canvasBasename === canvas.basename) || null;
75
+ }
76
+ /**
77
+ * Find canvas file for a given execution
78
+ */
79
+ findCanvasForExecution(execution, canvasFiles) {
80
+ // First, try exact package match if execution has package context
81
+ if (execution.packageContext) {
82
+ const exactMatch = canvasFiles.find(canvas => canvas.basename === execution.canvasBasename &&
83
+ canvas.packageContext?.name === execution.packageContext?.name);
84
+ if (exactMatch)
85
+ return exactMatch;
86
+ }
87
+ // Fallback to basename-only match (for root-level executions)
88
+ return canvasFiles.find(canvas => canvas.basename === execution.canvasBasename) || null;
89
+ }
90
+ /**
91
+ * Parse execution artifact JSON
92
+ */
93
+ static parseExecutionArtifact(content) {
94
+ try {
95
+ const parsed = JSON.parse(content);
96
+ return parsed;
97
+ }
98
+ catch (error) {
99
+ throw new Error(`Failed to parse execution artifact JSON: ${error.message}`);
100
+ }
101
+ }
102
+ /**
103
+ * Get spans from an artifact
104
+ */
105
+ static getSpans(artifact) {
106
+ return artifact.spans || [];
107
+ }
108
+ /**
109
+ * Extract metadata from an execution artifact
110
+ */
111
+ static getExecutionMetadata(artifact) {
112
+ const spans = ExecutionFileDiscovery.getSpans(artifact);
113
+ const spanCount = spans.length;
114
+ const eventCount = spans.reduce((total, span) => {
115
+ return total + (span.events?.length || 0);
116
+ }, 0);
117
+ const metadata = artifact.metadata;
118
+ let status = 'success';
119
+ if (metadata?.status) {
120
+ status = metadata.status;
121
+ }
122
+ else if (spans.length > 0) {
123
+ const hasError = spans.some(s => s.status === 'ERROR' || s.status === 'error' || s.status === 'FAILED');
124
+ status = hasError ? 'error' : 'OK';
125
+ }
126
+ return {
127
+ name: metadata?.canvasName || 'Untitled Execution',
128
+ canvasName: metadata?.canvasName,
129
+ exportedAt: metadata?.exportedAt,
130
+ source: metadata?.source,
131
+ framework: metadata?.framework,
132
+ status,
133
+ spanCount,
134
+ eventCount,
135
+ };
136
+ }
137
+ // Private helper methods
138
+ /**
139
+ * Detect packages using codebase-composition
140
+ */
141
+ async detectPackages(files) {
142
+ try {
143
+ // Convert files to the format expected by codebase-composition
144
+ const fileTree = this.convertToFileTree(files);
145
+ const packages = await this.packageLayerModule.discoverPackages(fileTree);
146
+ return packages || [];
147
+ }
148
+ catch (error) {
149
+ // If package detection fails, continue with fallback patterns
150
+ console.warn('Package detection failed, using fallback patterns:', error);
151
+ return [];
152
+ }
153
+ }
154
+ /**
155
+ * Convert file entries to file tree format for codebase-composition
156
+ */
157
+ convertToFileTree(files) {
158
+ // This is a simplified conversion - codebase-composition expects a specific format
159
+ // In practice, the caller should provide a proper FileTree from repository-abstraction
160
+ return {
161
+ files: files.map(f => ({
162
+ path: f.relativePath || f.path || '',
163
+ name: f.name || (f.relativePath || f.path || '').split('/').pop() || '',
164
+ })),
165
+ };
166
+ }
167
+ /**
168
+ * Find executions in a specific package
169
+ */
170
+ findExecutionsInPackage(pkg, files) {
171
+ const executions = [];
172
+ const pkgPath = pkg.packageData.path || '';
173
+ const packageContext = this.createPackageContext(pkg);
174
+ for (const execFolder of this.options.executionFolders) {
175
+ const execPath = pkgPath ? `${pkgPath}/${execFolder}` : execFolder;
176
+ for (const file of files) {
177
+ const filePath = file.relativePath || file.path || '';
178
+ const fileName = file.name || filePath.split('/').pop() || '';
179
+ if (filePath.startsWith(execPath + '/') && this.isExecutionFile(fileName)) {
180
+ const basename = this.extractExecutionBasename(fileName);
181
+ executions.push({
182
+ id: this.generateExecutionId(basename, packageContext),
183
+ name: this.formatDisplayName(basename),
184
+ path: filePath,
185
+ canvasBasename: basename,
186
+ packageContext,
187
+ });
188
+ }
189
+ }
190
+ }
191
+ return executions;
192
+ }
193
+ /**
194
+ * Find executions in root-level locations
195
+ */
196
+ findExecutionsInRoot(files) {
197
+ const executions = [];
198
+ // Root __executions__/
199
+ for (const execFolder of this.options.executionFolders) {
200
+ for (const file of files) {
201
+ const filePath = file.relativePath || file.path || '';
202
+ const fileName = file.name || filePath.split('/').pop() || '';
203
+ if (filePath.startsWith(`${execFolder}/`) && this.isExecutionFile(fileName)) {
204
+ const basename = this.extractExecutionBasename(fileName);
205
+ executions.push({
206
+ id: `root-${basename}`,
207
+ name: this.formatDisplayName(basename),
208
+ path: filePath,
209
+ canvasBasename: basename,
210
+ });
211
+ }
212
+ }
213
+ }
214
+ // .principal-views/__executions__/
215
+ const pvExecPath = '.principal-views/__executions__';
216
+ for (const file of files) {
217
+ const filePath = file.relativePath || file.path || '';
218
+ const fileName = file.name || filePath.split('/').pop() || '';
219
+ if (filePath.startsWith(pvExecPath + '/') && this.isExecutionFile(fileName)) {
220
+ const basename = this.extractExecutionBasename(fileName);
221
+ executions.push({
222
+ id: `pv-${basename}`,
223
+ name: this.formatDisplayName(basename),
224
+ path: filePath,
225
+ canvasBasename: basename,
226
+ });
227
+ }
228
+ }
229
+ return executions;
230
+ }
231
+ /**
232
+ * Find canvas files in a specific directory
233
+ */
234
+ findCanvasesInDirectory(directory, files, packageContext) {
235
+ const canvases = [];
236
+ for (const file of files) {
237
+ const filePath = file.relativePath || file.path || '';
238
+ const fileName = file.name || filePath.split('/').pop() || '';
239
+ if (filePath.startsWith(directory + '/') && this.isCanvasFile(fileName)) {
240
+ const basename = this.extractCanvasBasename(fileName);
241
+ canvases.push({
242
+ id: this.generateCanvasId(basename, packageContext),
243
+ name: this.formatDisplayName(basename),
244
+ path: filePath,
245
+ basename,
246
+ packageContext,
247
+ });
248
+ }
249
+ }
250
+ return canvases;
251
+ }
252
+ /**
253
+ * Create package context from PackageLayer
254
+ */
255
+ createPackageContext(pkg) {
256
+ return {
257
+ name: pkg.packageData.name || 'unknown',
258
+ packagePath: pkg.packageData.path || '',
259
+ packageType: pkg.type,
260
+ };
261
+ }
262
+ /**
263
+ * Check if filename is an execution file
264
+ */
265
+ isExecutionFile(filename) {
266
+ return /\.(spans|execution|events)\.json$/.test(filename);
267
+ }
268
+ /**
269
+ * Check if filename is a canvas file
270
+ */
271
+ isCanvasFile(filename) {
272
+ return this.options.canvasExtensions.some(ext => filename.endsWith(ext));
273
+ }
274
+ /**
275
+ * Extract basename from execution filename
276
+ */
277
+ extractExecutionBasename(filename) {
278
+ return filename.replace(/\.(spans|execution|events)\.json$/, '');
279
+ }
280
+ /**
281
+ * Extract basename from canvas filename
282
+ */
283
+ extractCanvasBasename(filename) {
284
+ for (const ext of this.options.canvasExtensions) {
285
+ if (filename.endsWith(ext)) {
286
+ return filename.slice(0, -ext.length);
287
+ }
288
+ }
289
+ return filename;
290
+ }
291
+ /**
292
+ * Format display name from basename (kebab-case to Title Case)
293
+ */
294
+ formatDisplayName(basename) {
295
+ return basename
296
+ .split('-')
297
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
298
+ .join(' ');
299
+ }
300
+ /**
301
+ * Generate unique ID for execution file
302
+ */
303
+ generateExecutionId(basename, packageContext) {
304
+ if (packageContext) {
305
+ return `${packageContext.name}-${basename}`;
306
+ }
307
+ return basename;
308
+ }
309
+ /**
310
+ * Generate unique ID for canvas file
311
+ */
312
+ generateCanvasId(basename, packageContext) {
313
+ if (packageContext) {
314
+ return `${packageContext.name}-${basename}`;
315
+ }
316
+ return basename;
317
+ }
318
+ /**
319
+ * Sort execution files by package name, then by basename
320
+ */
321
+ sortExecutionFiles(files) {
322
+ return files.sort((a, b) => {
323
+ // Sort by package name first
324
+ if (a.packageContext && b.packageContext) {
325
+ const pkgCompare = a.packageContext.name.localeCompare(b.packageContext.name);
326
+ if (pkgCompare !== 0)
327
+ return pkgCompare;
328
+ }
329
+ else if (a.packageContext) {
330
+ return -1;
331
+ }
332
+ else if (b.packageContext) {
333
+ return 1;
334
+ }
335
+ // Then by basename
336
+ return a.canvasBasename.localeCompare(b.canvasBasename);
337
+ });
338
+ }
339
+ }
340
+ //# sourceMappingURL=ExecutionFileDiscovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecutionFileDiscovery.js","sourceRoot":"","sources":["../../src/utils/ExecutionFileDiscovery.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ai/principal-view-core",
3
- "version": "0.5.17",
3
+ "version": "0.6.1",
4
4
  "description": "Core logic and types for graph-based principal view framework",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -28,6 +28,7 @@
28
28
  "zod": "^3.22.0",
29
29
  "date-fns": "^3.0.0",
30
30
  "@principal-ai/repository-abstraction": "^0.2.5",
31
+ "@principal-ai/codebase-composition": "^0.2.32",
31
32
  "js-yaml": "^4.1.0"
32
33
  },
33
34
  "devDependencies": {
package/src/index.ts CHANGED
@@ -29,6 +29,19 @@ export type { LogEntry } from './PathBasedEventProcessor';
29
29
  export { PathMatcher } from './utils/PathMatcher';
30
30
  export { GraphConverter } from './utils/GraphConverter';
31
31
 
32
+ // Export execution file discovery
33
+ export { ExecutionFileDiscovery } from './utils/ExecutionFileDiscovery';
34
+ export type {
35
+ ExecutionFile,
36
+ CanvasFile,
37
+ PackageContext,
38
+ ExecutionMetadata,
39
+ ExecutionSpan,
40
+ ExecutionArtifact,
41
+ FileTreeEntry,
42
+ DiscoveryOptions,
43
+ } from './utils/ExecutionFileDiscovery';
44
+
32
45
  // Export Canvas types and converter
33
46
  export * from './types/canvas';
34
47
  export { CanvasConverter } from './utils/CanvasConverter';
@@ -0,0 +1,522 @@
1
+ /**
2
+ * Execution File Discovery
3
+ *
4
+ * Discovers execution artifacts and canvas files in a repository with monorepo awareness.
5
+ * Uses codebase-composition (browser-safe export) to intelligently detect package boundaries
6
+ * and workspace patterns.
7
+ */
8
+
9
+ import { PackageLayerModule } from '@principal-ai/codebase-composition/browser';
10
+ import type { PackageLayer } from '@principal-ai/codebase-composition/browser';
11
+
12
+ /**
13
+ * Represents a discovered execution artifact file
14
+ */
15
+ export interface ExecutionFile {
16
+ /** Unique identifier for this execution */
17
+ id: string;
18
+ /** Display name for this execution */
19
+ name: string;
20
+ /** Full file path (relative to repository root) */
21
+ path: string;
22
+ /** Canvas basename (without extension) that this execution is linked to */
23
+ canvasBasename: string;
24
+ /** Package context if this execution belongs to a specific package */
25
+ packageContext?: PackageContext;
26
+ }
27
+
28
+ /**
29
+ * Represents a discovered canvas file
30
+ */
31
+ export interface CanvasFile {
32
+ /** Unique identifier for this canvas */
33
+ id: string;
34
+ /** Display name for this canvas */
35
+ name: string;
36
+ /** Full file path (relative to repository root) */
37
+ path: string;
38
+ /** Canvas basename (without .otel.canvas or .canvas extension) */
39
+ basename: string;
40
+ /** Package context if this canvas belongs to a specific package */
41
+ packageContext?: PackageContext;
42
+ }
43
+
44
+ /**
45
+ * Package context for execution/canvas files
46
+ */
47
+ export interface PackageContext {
48
+ /** Package name (from package.json, Cargo.toml, etc.) */
49
+ name: string;
50
+ /** Package directory path (relative to repository root) */
51
+ packagePath: string;
52
+ /** Package type (npm, cargo, go, etc.) */
53
+ packageType?: string;
54
+ }
55
+
56
+ /**
57
+ * Execution artifact metadata
58
+ */
59
+ export interface ExecutionMetadata {
60
+ name: string;
61
+ canvasName?: string;
62
+ exportedAt?: string;
63
+ source?: string;
64
+ framework?: string;
65
+ status?: 'success' | 'error' | 'OK';
66
+ spanCount: number;
67
+ eventCount: number;
68
+ }
69
+
70
+ /**
71
+ * Execution span structure
72
+ */
73
+ export interface ExecutionSpan {
74
+ id: string;
75
+ name: string;
76
+ startTime: number;
77
+ endTime?: number;
78
+ duration?: number;
79
+ status?: string;
80
+ attributes?: Record<string, any>;
81
+ events: Array<{
82
+ time: number;
83
+ name: string;
84
+ attributes?: Record<string, any>;
85
+ }>;
86
+ }
87
+
88
+ /**
89
+ * Execution artifact file structure
90
+ */
91
+ export interface ExecutionArtifact {
92
+ metadata?: {
93
+ canvasName?: string;
94
+ exportedAt?: string;
95
+ source?: string;
96
+ framework?: string;
97
+ status?: 'success' | 'error';
98
+ };
99
+ spans: ExecutionSpan[];
100
+ }
101
+
102
+ /**
103
+ * File tree entry for discovery
104
+ */
105
+ export interface FileTreeEntry {
106
+ path?: string;
107
+ relativePath?: string;
108
+ name?: string;
109
+ }
110
+
111
+ /**
112
+ * Options for execution file discovery
113
+ */
114
+ export interface DiscoveryOptions {
115
+ /** Whether to include package-level .principal-views folders */
116
+ includePackagePrincipalViews?: boolean;
117
+ /** Custom execution folder names (defaults to ['__executions__']) */
118
+ executionFolders?: string[];
119
+ /** Custom canvas extensions (defaults to ['.otel.canvas']) */
120
+ canvasExtensions?: string[];
121
+ }
122
+
123
+ /**
124
+ * Execution File Discovery Engine
125
+ *
126
+ * Discovers execution artifacts and canvas files using monorepo-aware logic.
127
+ */
128
+ export class ExecutionFileDiscovery {
129
+ private packageLayerModule: PackageLayerModule;
130
+ private options: Required<DiscoveryOptions>;
131
+
132
+ constructor(options: DiscoveryOptions = {}) {
133
+ this.packageLayerModule = new PackageLayerModule();
134
+ this.options = {
135
+ includePackagePrincipalViews: options.includePackagePrincipalViews ?? true,
136
+ executionFolders: options.executionFolders ?? ['__executions__'],
137
+ canvasExtensions: options.canvasExtensions ?? ['.otel.canvas'],
138
+ };
139
+ }
140
+
141
+ /**
142
+ * Find all execution artifact files in the repository
143
+ */
144
+ async findExecutionFiles(files: FileTreeEntry[]): Promise<ExecutionFile[]> {
145
+ const executionFiles: ExecutionFile[] = [];
146
+
147
+ // Detect packages in the repository
148
+ const packages = await this.detectPackages(files);
149
+
150
+ // Search for execution files in each package
151
+ for (const pkg of packages) {
152
+ const pkgExecutions = this.findExecutionsInPackage(pkg, files);
153
+ executionFiles.push(...pkgExecutions);
154
+ }
155
+
156
+ // Search in root-level locations
157
+ const rootExecutions = this.findExecutionsInRoot(files);
158
+ executionFiles.push(...rootExecutions);
159
+
160
+ // Sort by package name, then by basename
161
+ return this.sortExecutionFiles(executionFiles);
162
+ }
163
+
164
+ /**
165
+ * Find all canvas files in the repository
166
+ */
167
+ async findCanvasFiles(files: FileTreeEntry[]): Promise<CanvasFile[]> {
168
+ const canvasFiles: CanvasFile[] = [];
169
+
170
+ // Detect packages in the repository
171
+ const packages = await this.detectPackages(files);
172
+
173
+ // Search for canvas files in root .principal-views/
174
+ const rootCanvases = this.findCanvasesInDirectory('.principal-views', files);
175
+ canvasFiles.push(...rootCanvases);
176
+
177
+ // Search for canvas files in package-level .principal-views/ if enabled
178
+ if (this.options.includePackagePrincipalViews) {
179
+ for (const pkg of packages) {
180
+ const pkgCanvases = this.findCanvasesInDirectory(
181
+ `${pkg.packageData.path}/.principal-views`,
182
+ files,
183
+ this.createPackageContext(pkg)
184
+ );
185
+ canvasFiles.push(...pkgCanvases);
186
+ }
187
+ }
188
+
189
+ // Sort by name
190
+ return canvasFiles.sort((a, b) => a.name.localeCompare(b.name));
191
+ }
192
+
193
+ /**
194
+ * Find execution artifact for a given canvas
195
+ * Now package-aware - can disambiguate between packages
196
+ */
197
+ findExecutionForCanvas(
198
+ canvas: CanvasFile,
199
+ executionFiles: ExecutionFile[]
200
+ ): ExecutionFile | null {
201
+ // First, try exact package match if canvas has package context
202
+ if (canvas.packageContext) {
203
+ const exactMatch = executionFiles.find(
204
+ exec =>
205
+ exec.canvasBasename === canvas.basename &&
206
+ exec.packageContext?.name === canvas.packageContext?.name
207
+ );
208
+ if (exactMatch) return exactMatch;
209
+ }
210
+
211
+ // Fallback to basename-only match (for root-level canvases)
212
+ return executionFiles.find(exec => exec.canvasBasename === canvas.basename) || null;
213
+ }
214
+
215
+ /**
216
+ * Find canvas file for a given execution
217
+ */
218
+ findCanvasForExecution(
219
+ execution: ExecutionFile,
220
+ canvasFiles: CanvasFile[]
221
+ ): CanvasFile | null {
222
+ // First, try exact package match if execution has package context
223
+ if (execution.packageContext) {
224
+ const exactMatch = canvasFiles.find(
225
+ canvas =>
226
+ canvas.basename === execution.canvasBasename &&
227
+ canvas.packageContext?.name === execution.packageContext?.name
228
+ );
229
+ if (exactMatch) return exactMatch;
230
+ }
231
+
232
+ // Fallback to basename-only match (for root-level executions)
233
+ return canvasFiles.find(canvas => canvas.basename === execution.canvasBasename) || null;
234
+ }
235
+
236
+ /**
237
+ * Parse execution artifact JSON
238
+ */
239
+ static parseExecutionArtifact(content: string): ExecutionArtifact {
240
+ try {
241
+ const parsed = JSON.parse(content);
242
+ return parsed as ExecutionArtifact;
243
+ } catch (error) {
244
+ throw new Error(`Failed to parse execution artifact JSON: ${(error as Error).message}`);
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Get spans from an artifact
250
+ */
251
+ static getSpans(artifact: ExecutionArtifact): ExecutionSpan[] {
252
+ return artifact.spans || [];
253
+ }
254
+
255
+ /**
256
+ * Extract metadata from an execution artifact
257
+ */
258
+ static getExecutionMetadata(artifact: ExecutionArtifact): ExecutionMetadata {
259
+ const spans = ExecutionFileDiscovery.getSpans(artifact);
260
+ const spanCount = spans.length;
261
+
262
+ const eventCount = spans.reduce((total, span) => {
263
+ return total + (span.events?.length || 0);
264
+ }, 0);
265
+
266
+ const metadata = artifact.metadata;
267
+
268
+ let status: 'success' | 'error' | 'OK' = 'success';
269
+ if (metadata?.status) {
270
+ status = metadata.status;
271
+ } else if (spans.length > 0) {
272
+ const hasError = spans.some(
273
+ s => s.status === 'ERROR' || s.status === 'error' || s.status === 'FAILED'
274
+ );
275
+ status = hasError ? 'error' : 'OK';
276
+ }
277
+
278
+ return {
279
+ name: metadata?.canvasName || 'Untitled Execution',
280
+ canvasName: metadata?.canvasName,
281
+ exportedAt: metadata?.exportedAt,
282
+ source: metadata?.source,
283
+ framework: metadata?.framework,
284
+ status,
285
+ spanCount,
286
+ eventCount,
287
+ };
288
+ }
289
+
290
+ // Private helper methods
291
+
292
+ /**
293
+ * Detect packages using codebase-composition
294
+ */
295
+ private async detectPackages(files: FileTreeEntry[]): Promise<PackageLayer[]> {
296
+ try {
297
+ // Convert files to the format expected by codebase-composition
298
+ const fileTree = this.convertToFileTree(files);
299
+ const packages = await this.packageLayerModule.discoverPackages(fileTree);
300
+ return packages || [];
301
+ } catch (error) {
302
+ // If package detection fails, continue with fallback patterns
303
+ console.warn('Package detection failed, using fallback patterns:', error);
304
+ return [];
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Convert file entries to file tree format for codebase-composition
310
+ */
311
+ private convertToFileTree(files: FileTreeEntry[]): any {
312
+ // This is a simplified conversion - codebase-composition expects a specific format
313
+ // In practice, the caller should provide a proper FileTree from repository-abstraction
314
+ return {
315
+ files: files.map(f => ({
316
+ path: f.relativePath || f.path || '',
317
+ name: f.name || (f.relativePath || f.path || '').split('/').pop() || '',
318
+ })),
319
+ };
320
+ }
321
+
322
+ /**
323
+ * Find executions in a specific package
324
+ */
325
+ private findExecutionsInPackage(
326
+ pkg: PackageLayer,
327
+ files: FileTreeEntry[]
328
+ ): ExecutionFile[] {
329
+ const executions: ExecutionFile[] = [];
330
+ const pkgPath = pkg.packageData.path || '';
331
+ const packageContext = this.createPackageContext(pkg);
332
+
333
+ for (const execFolder of this.options.executionFolders) {
334
+ const execPath = pkgPath ? `${pkgPath}/${execFolder}` : execFolder;
335
+
336
+ for (const file of files) {
337
+ const filePath = file.relativePath || file.path || '';
338
+ const fileName = file.name || filePath.split('/').pop() || '';
339
+
340
+ if (filePath.startsWith(execPath + '/') && this.isExecutionFile(fileName)) {
341
+ const basename = this.extractExecutionBasename(fileName);
342
+ executions.push({
343
+ id: this.generateExecutionId(basename, packageContext),
344
+ name: this.formatDisplayName(basename),
345
+ path: filePath,
346
+ canvasBasename: basename,
347
+ packageContext,
348
+ });
349
+ }
350
+ }
351
+ }
352
+
353
+ return executions;
354
+ }
355
+
356
+ /**
357
+ * Find executions in root-level locations
358
+ */
359
+ private findExecutionsInRoot(files: FileTreeEntry[]): ExecutionFile[] {
360
+ const executions: ExecutionFile[] = [];
361
+
362
+ // Root __executions__/
363
+ for (const execFolder of this.options.executionFolders) {
364
+ for (const file of files) {
365
+ const filePath = file.relativePath || file.path || '';
366
+ const fileName = file.name || filePath.split('/').pop() || '';
367
+
368
+ if (filePath.startsWith(`${execFolder}/`) && this.isExecutionFile(fileName)) {
369
+ const basename = this.extractExecutionBasename(fileName);
370
+ executions.push({
371
+ id: `root-${basename}`,
372
+ name: this.formatDisplayName(basename),
373
+ path: filePath,
374
+ canvasBasename: basename,
375
+ });
376
+ }
377
+ }
378
+ }
379
+
380
+ // .principal-views/__executions__/
381
+ const pvExecPath = '.principal-views/__executions__';
382
+ for (const file of files) {
383
+ const filePath = file.relativePath || file.path || '';
384
+ const fileName = file.name || filePath.split('/').pop() || '';
385
+
386
+ if (filePath.startsWith(pvExecPath + '/') && this.isExecutionFile(fileName)) {
387
+ const basename = this.extractExecutionBasename(fileName);
388
+ executions.push({
389
+ id: `pv-${basename}`,
390
+ name: this.formatDisplayName(basename),
391
+ path: filePath,
392
+ canvasBasename: basename,
393
+ });
394
+ }
395
+ }
396
+
397
+ return executions;
398
+ }
399
+
400
+ /**
401
+ * Find canvas files in a specific directory
402
+ */
403
+ private findCanvasesInDirectory(
404
+ directory: string,
405
+ files: FileTreeEntry[],
406
+ packageContext?: PackageContext
407
+ ): CanvasFile[] {
408
+ const canvases: CanvasFile[] = [];
409
+
410
+ for (const file of files) {
411
+ const filePath = file.relativePath || file.path || '';
412
+ const fileName = file.name || filePath.split('/').pop() || '';
413
+
414
+ if (filePath.startsWith(directory + '/') && this.isCanvasFile(fileName)) {
415
+ const basename = this.extractCanvasBasename(fileName);
416
+ canvases.push({
417
+ id: this.generateCanvasId(basename, packageContext),
418
+ name: this.formatDisplayName(basename),
419
+ path: filePath,
420
+ basename,
421
+ packageContext,
422
+ });
423
+ }
424
+ }
425
+
426
+ return canvases;
427
+ }
428
+
429
+ /**
430
+ * Create package context from PackageLayer
431
+ */
432
+ private createPackageContext(pkg: PackageLayer): PackageContext {
433
+ return {
434
+ name: pkg.packageData.name || 'unknown',
435
+ packagePath: pkg.packageData.path || '',
436
+ packageType: pkg.type,
437
+ };
438
+ }
439
+
440
+ /**
441
+ * Check if filename is an execution file
442
+ */
443
+ private isExecutionFile(filename: string): boolean {
444
+ return /\.(spans|execution|events)\.json$/.test(filename);
445
+ }
446
+
447
+ /**
448
+ * Check if filename is a canvas file
449
+ */
450
+ private isCanvasFile(filename: string): boolean {
451
+ return this.options.canvasExtensions.some(ext => filename.endsWith(ext));
452
+ }
453
+
454
+ /**
455
+ * Extract basename from execution filename
456
+ */
457
+ private extractExecutionBasename(filename: string): string {
458
+ return filename.replace(/\.(spans|execution|events)\.json$/, '');
459
+ }
460
+
461
+ /**
462
+ * Extract basename from canvas filename
463
+ */
464
+ private extractCanvasBasename(filename: string): string {
465
+ for (const ext of this.options.canvasExtensions) {
466
+ if (filename.endsWith(ext)) {
467
+ return filename.slice(0, -ext.length);
468
+ }
469
+ }
470
+ return filename;
471
+ }
472
+
473
+ /**
474
+ * Format display name from basename (kebab-case to Title Case)
475
+ */
476
+ private formatDisplayName(basename: string): string {
477
+ return basename
478
+ .split('-')
479
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
480
+ .join(' ');
481
+ }
482
+
483
+ /**
484
+ * Generate unique ID for execution file
485
+ */
486
+ private generateExecutionId(basename: string, packageContext?: PackageContext): string {
487
+ if (packageContext) {
488
+ return `${packageContext.name}-${basename}`;
489
+ }
490
+ return basename;
491
+ }
492
+
493
+ /**
494
+ * Generate unique ID for canvas file
495
+ */
496
+ private generateCanvasId(basename: string, packageContext?: PackageContext): string {
497
+ if (packageContext) {
498
+ return `${packageContext.name}-${basename}`;
499
+ }
500
+ return basename;
501
+ }
502
+
503
+ /**
504
+ * Sort execution files by package name, then by basename
505
+ */
506
+ private sortExecutionFiles(files: ExecutionFile[]): ExecutionFile[] {
507
+ return files.sort((a, b) => {
508
+ // Sort by package name first
509
+ if (a.packageContext && b.packageContext) {
510
+ const pkgCompare = a.packageContext.name.localeCompare(b.packageContext.name);
511
+ if (pkgCompare !== 0) return pkgCompare;
512
+ } else if (a.packageContext) {
513
+ return -1;
514
+ } else if (b.packageContext) {
515
+ return 1;
516
+ }
517
+
518
+ // Then by basename
519
+ return a.canvasBasename.localeCompare(b.canvasBasename);
520
+ });
521
+ }
522
+ }