@principal-ai/principal-view-cli 0.6.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/commands/formats.js +19 -19
  2. package/dist/commands/lint.js +44 -44
  3. package/dist/commands/workflow/index.d.ts +3 -0
  4. package/dist/commands/workflow/index.d.ts.map +1 -0
  5. package/dist/commands/{narrative → workflow}/index.js +3 -3
  6. package/dist/commands/workflow/inspect.d.ts.map +1 -0
  7. package/dist/commands/workflow/list.d.ts.map +1 -0
  8. package/dist/commands/{narrative → workflow}/list.js +32 -32
  9. package/dist/commands/workflow/render.d.ts.map +1 -0
  10. package/dist/commands/{narrative → workflow}/render.js +16 -16
  11. package/dist/commands/workflow/test.d.ts.map +1 -0
  12. package/dist/commands/{narrative → workflow}/test.js +8 -8
  13. package/dist/commands/{narrative → workflow}/utils.d.ts +4 -4
  14. package/dist/commands/workflow/utils.d.ts.map +1 -0
  15. package/dist/commands/{narrative → workflow}/utils.js +5 -5
  16. package/dist/commands/workflow/validate.d.ts.map +1 -0
  17. package/dist/commands/{narrative → workflow}/validate.js +21 -21
  18. package/dist/index.cjs +370 -267
  19. package/dist/index.cjs.map +4 -4
  20. package/dist/index.js +2 -2
  21. package/package.json +3 -3
  22. package/dist/commands/narrative/index.d.ts +0 -3
  23. package/dist/commands/narrative/index.d.ts.map +0 -1
  24. package/dist/commands/narrative/inspect.d.ts.map +0 -1
  25. package/dist/commands/narrative/list.d.ts.map +0 -1
  26. package/dist/commands/narrative/render.d.ts.map +0 -1
  27. package/dist/commands/narrative/test.d.ts.map +0 -1
  28. package/dist/commands/narrative/utils.d.ts.map +0 -1
  29. package/dist/commands/narrative/validate.d.ts.map +0 -1
  30. /package/dist/commands/{narrative → workflow}/inspect.d.ts +0 -0
  31. /package/dist/commands/{narrative → workflow}/inspect.js +0 -0
  32. /package/dist/commands/{narrative → workflow}/list.d.ts +0 -0
  33. /package/dist/commands/{narrative → workflow}/render.d.ts +0 -0
  34. /package/dist/commands/{narrative → workflow}/test.d.ts +0 -0
  35. /package/dist/commands/{narrative → workflow}/validate.d.ts +0 -0
package/dist/index.cjs CHANGED
@@ -210597,7 +210597,7 @@ var ConfigurationLoader = class _ConfigurationLoader {
210597
210597
  };
210598
210598
  ConfigurationLoader.CONFIG_DIR = ".principal-views";
210599
210599
 
210600
- // ../core/dist/narrative/template-parser.js
210600
+ // ../core/dist/workflow/template-parser.js
210601
210601
  var import_handlebars = __toESM(require_lib());
210602
210602
  import_handlebars.default.registerHelper("eq", (a, b) => a === b);
210603
210603
  import_handlebars.default.registerHelper("ne", (a, b) => a !== b);
@@ -210623,7 +210623,7 @@ function parseTemplate(template, context) {
210623
210623
  }
210624
210624
  }
210625
210625
 
210626
- // ../core/dist/narrative/scenario-matcher.js
210626
+ // ../core/dist/workflow/scenario-matcher.js
210627
210627
  function selectScenario(template, events, attributes = {}) {
210628
210628
  const sorted = [...template.scenarios].sort((a, b) => a.priority - b.priority);
210629
210629
  const applicableScenarios = [];
@@ -210780,8 +210780,8 @@ function computeAggregates(events) {
210780
210780
  return aggregates;
210781
210781
  }
210782
210782
 
210783
- // ../core/dist/narrative/template-renderer.js
210784
- function renderNarrative(template, events) {
210783
+ // ../core/dist/workflow/template-renderer.js
210784
+ function renderWorkflow(template, events) {
210785
210785
  const aggregates = computeAggregates(events);
210786
210786
  const matchResult = selectScenario(template, events, aggregates);
210787
210787
  const context = {
@@ -214496,7 +214496,7 @@ var CanvasDiscovery = class _CanvasDiscovery {
214496
214496
  *
214497
214497
  * @param fileTree - FileTree from repository-abstraction
214498
214498
  * @param options - Discovery options (fileReader, includeContent)
214499
- * @returns Discovery result with canvases, executions, and errors
214499
+ * @returns Discovery result with canvases, executions, storyboards, and errors
214500
214500
  */
214501
214501
  async discover(fileTree, options = {}) {
214502
214502
  const errors = [];
@@ -214504,9 +214504,11 @@ var CanvasDiscovery = class _CanvasDiscovery {
214504
214504
  const packageMap = this.buildPackageMap(packages);
214505
214505
  const canvases = await this.discoverCanvasFiles(fileTree, packageMap, options, errors);
214506
214506
  const executions = await this.discoverExecutionFiles(fileTree, packageMap, options, errors);
214507
+ const storyboards = await this.discoverStoryboards(fileTree, packageMap, canvases, executions, options, errors);
214507
214508
  canvases.sort(this.compareByPackageThenName);
214508
214509
  executions.sort(this.compareByPackageThenName);
214509
- return { canvases, executions, errors };
214510
+ storyboards.sort(this.compareByPackageThenName);
214511
+ return { canvases, executions, storyboards, errors };
214510
214512
  }
214511
214513
  /**
214512
214514
  * Find canvas file for a given execution
@@ -214534,6 +214536,106 @@ var CanvasDiscovery = class _CanvasDiscovery {
214534
214536
  clearCache() {
214535
214537
  this.packageCache.clear();
214536
214538
  }
214539
+ /**
214540
+ * Discover storyboards (hierarchical organization of canvas + workflows + executions)
214541
+ */
214542
+ async discoverStoryboards(fileTree, packageMap, canvases, executions, options, errors) {
214543
+ const storyboards = [];
214544
+ const storyboardDirs = /* @__PURE__ */ new Map();
214545
+ for (const file of fileTree.allFiles) {
214546
+ const path4 = file.relativePath || file.path || "";
214547
+ const parts = path4.split("/");
214548
+ const pvIndex = parts.indexOf(_CanvasDiscovery.CANVAS_DIR);
214549
+ if (pvIndex === -1 || parts.length < pvIndex + 3)
214550
+ continue;
214551
+ const storyboardName = parts[pvIndex + 1];
214552
+ const storyboardPath = parts.slice(0, pvIndex + 2).join("/");
214553
+ if (!storyboardDirs.has(storyboardPath)) {
214554
+ storyboardDirs.set(storyboardPath, /* @__PURE__ */ new Set());
214555
+ }
214556
+ storyboardDirs.get(storyboardPath).add(storyboardName);
214557
+ }
214558
+ for (const [storyboardParentPath, storyboardNames] of storyboardDirs) {
214559
+ for (const storyboardName of storyboardNames) {
214560
+ const storyboardPath = `${storyboardParentPath}/${storyboardName}`;
214561
+ if (storyboardName === _CanvasDiscovery.EXECUTIONS_DIR)
214562
+ continue;
214563
+ const storyboardCanvas = canvases.find((c) => {
214564
+ const canvasDir = c.path.split("/").slice(0, -1).join("/");
214565
+ return canvasDir === storyboardPath && c.basename === storyboardName;
214566
+ });
214567
+ if (!storyboardCanvas)
214568
+ continue;
214569
+ const workflows = await this.discoverWorkflowsInStoryboard(fileTree, storyboardPath, storyboardName, packageMap, executions, options, errors);
214570
+ if (workflows.length === 0)
214571
+ continue;
214572
+ const packageInfo = this.findPackageForPath(storyboardPath, packageMap);
214573
+ const id = packageInfo ? `${packageInfo.packageData.name}/${storyboardName}` : storyboardName;
214574
+ const storyboard = {
214575
+ id,
214576
+ name: this.toDisplayName(storyboardName),
214577
+ path: storyboardPath,
214578
+ basename: storyboardName,
214579
+ canvas: storyboardCanvas,
214580
+ workflows,
214581
+ packageName: packageInfo?.packageData.name,
214582
+ packagePath: packageInfo?.packageData.path,
214583
+ scope: packageInfo ? "package" : "root"
214584
+ };
214585
+ storyboards.push(storyboard);
214586
+ }
214587
+ }
214588
+ return storyboards;
214589
+ }
214590
+ /**
214591
+ * Discover workflows within a storyboard folder
214592
+ */
214593
+ async discoverWorkflowsInStoryboard(fileTree, storyboardPath, storyboardName, packageMap, executions, options, errors) {
214594
+ const workflows = [];
214595
+ for (const file of fileTree.allFiles) {
214596
+ const path4 = file.relativePath || file.path || "";
214597
+ if (!path4.startsWith(storyboardPath + "/"))
214598
+ continue;
214599
+ if (!path4.endsWith(_CanvasDiscovery.WORKFLOW_EXTENSION))
214600
+ continue;
214601
+ const filename = path4.split("/").pop();
214602
+ if (!filename)
214603
+ continue;
214604
+ const basename3 = filename.replace(_CanvasDiscovery.WORKFLOW_EXTENSION, "");
214605
+ const workflowDir = path4.split("/").slice(0, -1).join("/");
214606
+ const packageInfo = this.findPackageForPath(path4, packageMap);
214607
+ const id = packageInfo ? `${packageInfo.packageData.name}/${storyboardName}/${basename3}` : `${storyboardName}/${basename3}`;
214608
+ const workflowExecutions = executions.filter((e) => {
214609
+ const execDir = e.path.split("/").slice(0, -1).join("/");
214610
+ return execDir === workflowDir;
214611
+ });
214612
+ let workflow = {
214613
+ id,
214614
+ name: this.toDisplayName(basename3),
214615
+ path: path4,
214616
+ basename: basename3,
214617
+ storyboardId: packageInfo ? `${packageInfo.packageData.name}/${storyboardName}` : storyboardName,
214618
+ packageName: packageInfo?.packageData.name,
214619
+ packagePath: packageInfo?.packageData.path,
214620
+ scope: packageInfo ? "package" : "root",
214621
+ executions: workflowExecutions
214622
+ };
214623
+ if (options.includeContent && options.fileReader) {
214624
+ try {
214625
+ const content = await options.fileReader(path4);
214626
+ const parsedContent = JSON.parse(content);
214627
+ workflow = { ...workflow, content: parsedContent };
214628
+ } catch (error) {
214629
+ errors.push({
214630
+ path: path4,
214631
+ error: `Failed to parse workflow content: ${error.message}`
214632
+ });
214633
+ }
214634
+ }
214635
+ workflows.push(workflow);
214636
+ }
214637
+ return workflows;
214638
+ }
214537
214639
  /**
214538
214640
  * Discover packages with caching by fileTree SHA
214539
214641
  */
@@ -214745,6 +214847,7 @@ var CanvasDiscovery = class _CanvasDiscovery {
214745
214847
  };
214746
214848
  CanvasDiscovery.CANVAS_DIR = ".principal-views";
214747
214849
  CanvasDiscovery.EXECUTIONS_DIR = "__executions__";
214850
+ CanvasDiscovery.WORKFLOW_EXTENSION = ".workflow.json";
214748
214851
 
214749
214852
  // ../core/dist/execution/ExecutionValidator.js
214750
214853
  function convertOtlpValue(value) {
@@ -216247,9 +216350,9 @@ ${source_default.bold("1. Canvas Files")} ${source_default.yellow(".otel.canvas"
216247
216350
  Define OTEL event schemas and telemetry structure for a feature.
216248
216351
  These are the single source of truth for what events should be emitted.
216249
216352
 
216250
- ${source_default.bold("2. Narrative Files")} ${source_default.yellow(".narrative.json")}
216353
+ ${source_default.bold("2. Workflow Files")} ${source_default.yellow(".workflow.json")}
216251
216354
  Define scenarios and templates for rendering executions as human-readable
216252
- narratives based on the emitted events.
216355
+ workflows based on the emitted events.
216253
216356
 
216254
216357
  ${source_default.bold("3. Execution Files")} ${source_default.yellow(".otel.json")}
216255
216358
  Captured OTEL spans from test runs or production code, exported for
@@ -216257,7 +216360,7 @@ ${source_default.bold("3. Execution Files")} ${source_default.yellow(".otel.json
216257
216360
 
216258
216361
  Run ${source_default.cyan("npx @principal-ai/principal-view-cli formats <section>")} for details on:
216259
216362
  ${source_default.yellow("canvas")} .otel.canvas format and event schemas
216260
- ${source_default.yellow("narrative")} .narrative.json format and scenario structure
216363
+ ${source_default.yellow("workflow")} .workflow.json format and scenario structure
216261
216364
  ${source_default.yellow("execution")} .otel.json format for captured spans
216262
216365
  ${source_default.yellow("examples")} Complete example files
216263
216366
  `,
@@ -216341,28 +216444,28 @@ ${source_default.cyan("5. Required vs Optional attributes:")}
216341
216444
  ${source_default.bold("Validation:")}
216342
216445
  ${source_default.cyan("npx @principal-ai/principal-view-cli validate")}
216343
216446
  `,
216344
- narrative: `
216345
- ${source_default.bold.cyan("Narrative Format (.narrative.json)")}
216447
+ workflow: `
216448
+ ${source_default.bold.cyan("Workflow Format (.workflow.json)")}
216346
216449
  ${source_default.dim("\u2550".repeat(70))}
216347
216450
 
216348
- Narrative files define scenarios for rendering execution data as human-readable
216451
+ Workflow files define scenarios for rendering execution data as human-readable
216349
216452
  stories. They evaluate conditions against captured events to select the best
216350
- matching narrative template.
216453
+ matching workflow template.
216351
216454
 
216352
216455
  ${source_default.bold("File Location:")}
216353
- ${source_default.dim(".principal-views/")}${source_default.yellow("<feature-name>.narrative.json")}
216456
+ ${source_default.dim(".principal-views/")}${source_default.yellow("<feature-name>.workflow.json")}
216354
216457
  ${source_default.dim("(co-located with corresponding .otel.canvas file)")}
216355
216458
 
216356
216459
  ${source_default.bold("Required Structure:")}
216357
216460
  ${source_default.dim("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510")}
216358
216461
  ${source_default.dim("\u2502")} { ${source_default.dim("\u2502")}
216359
- ${source_default.dim("\u2502")} ${source_default.green('"name"')}: "Feature Name", ${source_default.dim('// NOT "Feature Name Narratives"')} ${source_default.dim("\u2502")}
216360
- ${source_default.dim("\u2502")} ${source_default.green('"description"')}: "What the feature does", ${source_default.dim('// Purpose, not "Narratives for..."')} ${source_default.dim("\u2502")}
216462
+ ${source_default.dim("\u2502")} ${source_default.green('"name"')}: "Feature Name", ${source_default.dim('// NOT "Feature Name Workflows"')} ${source_default.dim("\u2502")}
216463
+ ${source_default.dim("\u2502")} ${source_default.green('"description"')}: "What the feature does", ${source_default.dim('// Purpose, not "Workflows for..."')} ${source_default.dim("\u2502")}
216361
216464
  ${source_default.dim("\u2502")} ${source_default.green('"scenarios"')}: [ ${source_default.dim("\u2502")}
216362
216465
  ${source_default.dim("\u2502")} { ${source_default.dim("\u2502")}
216363
216466
  ${source_default.dim("\u2502")} ${source_default.yellow('"priority"')}: 1, ${source_default.dim("// Lower = higher priority")} ${source_default.dim("\u2502")}
216364
216467
  ${source_default.dim("\u2502")} ${source_default.yellow('"condition"')}: "...", ${source_default.dim("// JSONPath/logic expression")} ${source_default.dim("\u2502")}
216365
- ${source_default.dim("\u2502")} ${source_default.yellow('"template"')}: { ${source_default.dim("// Narrative template")} ${source_default.dim("\u2502")}
216468
+ ${source_default.dim("\u2502")} ${source_default.yellow('"template"')}: { ${source_default.dim("// Workflow template")} ${source_default.dim("\u2502")}
216366
216469
  ${source_default.dim("\u2502")} ${source_default.cyan('"summary"')}: "Completed {{count}} items", ${source_default.dim("// Handlebars template")} ${source_default.dim("\u2502")}
216367
216470
  ${source_default.dim("\u2502")} ${source_default.cyan('"events"')}: { ${source_default.dim("// Per-event templates")} ${source_default.dim("\u2502")}
216368
216471
  ${source_default.dim("\u2502")} "event.name": "Event {{attribute}} occurred" ${source_default.dim("\u2502")}
@@ -216375,14 +216478,14 @@ ${source_default.dim("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25
216375
216478
 
216376
216479
  ${source_default.bold("Naming Guidelines:")}
216377
216480
 
216378
- \u274C DON'T append "Narratives" to the name:
216379
- "name": "Package Processor Narratives"
216481
+ \u274C DON'T append "Workflows" to the name:
216482
+ "name": "Package Processor Workflows"
216380
216483
 
216381
216484
  \u2705 DO use the feature name directly:
216382
216485
  "name": "Package Processor"
216383
216486
 
216384
216487
  \u274C DON'T prefix description with boilerplate:
216385
- "description": "Human-readable narratives for package extraction..."
216488
+ "description": "Human-readable workflows for package extraction..."
216386
216489
 
216387
216490
  \u2705 DO describe the feature's purpose:
216388
216491
  "description": "Package extraction and analysis from repository file trees"
@@ -216433,7 +216536,7 @@ ${source_default.cyan("5. Template style:")}
216433
216536
  - Include key metrics and IDs
216434
216537
 
216435
216538
  ${source_default.bold("Validation:")}
216436
- ${source_default.cyan("npx @principal-ai/principal-view-cli narrative validate")}
216539
+ ${source_default.cyan("npx @principal-ai/principal-view-cli workflow validate")}
216437
216540
  `,
216438
216541
  execution: `
216439
216542
  ${source_default.bold.cyan("Execution Format (.otel.json)")}
@@ -216632,9 +216735,9 @@ ${source_default.yellow(".principal-views/data-validator.otel.canvas")}
216632
216735
  }
216633
216736
  }
216634
216737
 
216635
- ${source_default.bold("Example 2: Narrative Scenarios")}
216738
+ ${source_default.bold("Example 2: Workflow Scenarios")}
216636
216739
  ${source_default.dim("\u2500".repeat(70))}
216637
- ${source_default.yellow(".principal-views/data-validator.narrative.json")}
216740
+ ${source_default.yellow(".principal-views/data-validator.workflow.json")}
216638
216741
 
216639
216742
  {
216640
216743
  "name": "Data Validator",
@@ -216734,7 +216837,7 @@ ${source_default.yellow("__executions__/data-validator.otel.json")}
216734
216837
 
216735
216838
  ${source_default.bold("Next Steps:")}
216736
216839
  ${source_default.cyan("npx @principal-ai/principal-view-cli validate")} Validate canvas
216737
- ${source_default.cyan("npx @principal-ai/principal-view-cli narrative validate")} Validate narratives
216840
+ ${source_default.cyan("npx @principal-ai/principal-view-cli workflow validate")} Validate workflows
216738
216841
  ${source_default.cyan("npx @principal-ai/principal-view-cli validate-execution")} Validate execution
216739
216842
  `
216740
216843
  };
@@ -216742,7 +216845,7 @@ function createFormatsCommand() {
216742
216845
  const command = new Command("formats");
216743
216846
  command.description("Display documentation about file formats").argument(
216744
216847
  "[section]",
216745
- "Section to display: overview, canvas, narrative, execution, examples"
216848
+ "Section to display: overview, canvas, workflow, execution, examples"
216746
216849
  ).action((section) => {
216747
216850
  const validSections = Object.keys(FORMAT_SECTIONS);
216748
216851
  if (!section) {
@@ -220293,12 +220396,12 @@ function createDefaultRulesEngine() {
220293
220396
  return createRulesEngine(builtinRules);
220294
220397
  }
220295
220398
 
220296
- // ../core/dist/narrative/validator.js
220399
+ // ../core/dist/workflow/validator.js
220297
220400
  var import_fs = require("fs");
220298
220401
  var import_path2 = require("path");
220299
- var NarrativeValidator = class {
220402
+ var WorkflowValidator = class {
220300
220403
  /**
220301
- * Validate a narrative template
220404
+ * Validate a workflow template
220302
220405
  */
220303
220406
  async validate(context) {
220304
220407
  const violations = [];
@@ -220319,122 +220422,122 @@ var NarrativeValidator = class {
220319
220422
  */
220320
220423
  checkSchema(context) {
220321
220424
  const violations = [];
220322
- const { narrative, narrativePath } = context;
220323
- if (!narrative.version) {
220425
+ const { workflow, workflowPath } = context;
220426
+ if (!workflow.version) {
220324
220427
  violations.push({
220325
- ruleId: "narrative-schema-valid",
220428
+ ruleId: "workflow-schema-valid",
220326
220429
  severity: "error",
220327
- file: narrativePath,
220430
+ file: workflowPath,
220328
220431
  path: "version",
220329
220432
  message: 'Missing required field "version"',
220330
220433
  impact: "Cannot determine template version for compatibility",
220331
220434
  suggestion: 'Add a version field (e.g., "1.0.0")',
220332
220435
  fixable: false
220333
220436
  });
220334
- } else if (!this.isValidSemver(narrative.version)) {
220437
+ } else if (!this.isValidSemver(workflow.version)) {
220335
220438
  violations.push({
220336
- ruleId: "narrative-schema-valid",
220439
+ ruleId: "workflow-schema-valid",
220337
220440
  severity: "error",
220338
- file: narrativePath,
220441
+ file: workflowPath,
220339
220442
  path: "version",
220340
- message: `Invalid version format: "${narrative.version}"`,
220443
+ message: `Invalid version format: "${workflow.version}"`,
220341
220444
  impact: "Version must follow semver format",
220342
220445
  suggestion: 'Use semver format like "1.0.0"',
220343
220446
  fixable: false
220344
220447
  });
220345
220448
  }
220346
- if (!narrative.canvas) {
220449
+ if (!workflow.canvas) {
220347
220450
  violations.push({
220348
- ruleId: "narrative-schema-valid",
220451
+ ruleId: "workflow-schema-valid",
220349
220452
  severity: "error",
220350
- file: narrativePath,
220453
+ file: workflowPath,
220351
220454
  path: "canvas",
220352
220455
  message: 'Missing required field "canvas"',
220353
- impact: "Cannot determine which canvas this narrative belongs to",
220456
+ impact: "Cannot determine which canvas this workflow belongs to",
220354
220457
  suggestion: "Add a canvas field pointing to an .otel.canvas file",
220355
220458
  fixable: false
220356
220459
  });
220357
220460
  }
220358
- if (!narrative.name) {
220461
+ if (!workflow.name) {
220359
220462
  violations.push({
220360
- ruleId: "narrative-schema-valid",
220463
+ ruleId: "workflow-schema-valid",
220361
220464
  severity: "error",
220362
- file: narrativePath,
220465
+ file: workflowPath,
220363
220466
  path: "name",
220364
220467
  message: 'Missing required field "name"',
220365
- impact: "Cannot identify this narrative template",
220468
+ impact: "Cannot identify this workflow template",
220366
220469
  suggestion: "Add a human-readable name",
220367
220470
  fixable: false
220368
220471
  });
220369
220472
  }
220370
- if (!narrative.description) {
220473
+ if (!workflow.description) {
220371
220474
  violations.push({
220372
- ruleId: "narrative-schema-valid",
220475
+ ruleId: "workflow-schema-valid",
220373
220476
  severity: "error",
220374
- file: narrativePath,
220477
+ file: workflowPath,
220375
220478
  path: "description",
220376
220479
  message: 'Missing required field "description"',
220377
- impact: "Cannot understand the purpose of this narrative",
220378
- suggestion: "Add a description explaining what this narrative shows",
220480
+ impact: "Cannot understand the purpose of this workflow",
220481
+ suggestion: "Add a description explaining what this workflow shows",
220379
220482
  fixable: false
220380
220483
  });
220381
220484
  }
220382
220485
  const validModes = ["span-tree", "timeline"];
220383
- if (!narrative.mode) {
220486
+ if (!workflow.mode) {
220384
220487
  violations.push({
220385
- ruleId: "narrative-schema-valid",
220488
+ ruleId: "workflow-schema-valid",
220386
220489
  severity: "error",
220387
- file: narrativePath,
220490
+ file: workflowPath,
220388
220491
  path: "mode",
220389
220492
  message: 'Missing required field "mode"',
220390
- impact: "Cannot determine how to structure the narrative",
220493
+ impact: "Cannot determine how to structure the workflow",
220391
220494
  suggestion: `Set mode to one of: ${validModes.join(", ")}`,
220392
220495
  fixable: false
220393
220496
  });
220394
- } else if (!validModes.includes(narrative.mode)) {
220497
+ } else if (!validModes.includes(workflow.mode)) {
220395
220498
  violations.push({
220396
- ruleId: "narrative-schema-valid",
220499
+ ruleId: "workflow-schema-valid",
220397
220500
  severity: "error",
220398
- file: narrativePath,
220501
+ file: workflowPath,
220399
220502
  path: "mode",
220400
- message: `Invalid mode: "${narrative.mode}"`,
220503
+ message: `Invalid mode: "${workflow.mode}"`,
220401
220504
  impact: "Mode must be one of the supported types",
220402
220505
  suggestion: `Use one of: ${validModes.join(", ")}`,
220403
220506
  fixable: false
220404
220507
  });
220405
220508
  }
220406
220509
  const validSelections = ["first-match", "manual"];
220407
- if (narrative.scenarioSelection && !validSelections.includes(narrative.scenarioSelection)) {
220510
+ if (workflow.scenarioSelection && !validSelections.includes(workflow.scenarioSelection)) {
220408
220511
  violations.push({
220409
- ruleId: "narrative-schema-valid",
220512
+ ruleId: "workflow-schema-valid",
220410
220513
  severity: "error",
220411
- file: narrativePath,
220514
+ file: workflowPath,
220412
220515
  path: "scenarioSelection",
220413
- message: `Invalid scenarioSelection: "${narrative.scenarioSelection}"`,
220516
+ message: `Invalid scenarioSelection: "${workflow.scenarioSelection}"`,
220414
220517
  impact: "Scenario selection must be a valid type",
220415
220518
  suggestion: `Use one of: ${validSelections.join(", ")}`,
220416
220519
  fixable: false
220417
220520
  });
220418
220521
  }
220419
- if (!narrative.scenarios || !Array.isArray(narrative.scenarios)) {
220522
+ if (!workflow.scenarios || !Array.isArray(workflow.scenarios)) {
220420
220523
  violations.push({
220421
- ruleId: "narrative-schema-valid",
220524
+ ruleId: "workflow-schema-valid",
220422
220525
  severity: "error",
220423
- file: narrativePath,
220526
+ file: workflowPath,
220424
220527
  path: "scenarios",
220425
220528
  message: 'Missing or invalid "scenarios" field',
220426
- impact: "Cannot generate narratives without scenarios",
220529
+ impact: "Cannot generate workflows without scenarios",
220427
220530
  suggestion: "Add a scenarios array with at least one scenario",
220428
220531
  fixable: false
220429
220532
  });
220430
- } else if (narrative.scenarios.length === 0) {
220533
+ } else if (workflow.scenarios.length === 0) {
220431
220534
  violations.push({
220432
- ruleId: "narrative-schema-valid",
220535
+ ruleId: "workflow-schema-valid",
220433
220536
  severity: "error",
220434
- file: narrativePath,
220537
+ file: workflowPath,
220435
220538
  path: "scenarios",
220436
220539
  message: "Scenarios array is empty",
220437
- impact: "Cannot generate narratives without scenarios",
220540
+ impact: "Cannot generate workflows without scenarios",
220438
220541
  suggestion: "Add at least one scenario definition",
220439
220542
  fixable: false
220440
220543
  });
@@ -220446,18 +220549,18 @@ var NarrativeValidator = class {
220446
220549
  */
220447
220550
  checkCanvasExists(context) {
220448
220551
  const violations = [];
220449
- const { narrative, narrativePath, basePath, canvasPath } = context;
220450
- if (!narrative.canvas) {
220552
+ const { workflow, workflowPath, basePath, canvasPath } = context;
220553
+ if (!workflow.canvas) {
220451
220554
  return violations;
220452
220555
  }
220453
- const resolvedPath = canvasPath || (0, import_path2.resolve)(basePath, narrative.canvas);
220556
+ const resolvedPath = canvasPath || (0, import_path2.resolve)(basePath, workflow.canvas);
220454
220557
  if (!(0, import_fs.existsSync)(resolvedPath)) {
220455
220558
  violations.push({
220456
- ruleId: "narrative-canvas-exists",
220559
+ ruleId: "workflow-canvas-exists",
220457
220560
  severity: "error",
220458
- file: narrativePath,
220561
+ file: workflowPath,
220459
220562
  path: "canvas",
220460
- message: `Referenced canvas file does not exist: ${narrative.canvas}`,
220563
+ message: `Referenced canvas file does not exist: ${workflow.canvas}`,
220461
220564
  impact: "Cannot validate event references without the canvas",
220462
220565
  suggestion: "Ensure the canvas field points to a valid .otel.canvas file",
220463
220566
  fixable: false
@@ -220474,7 +220577,7 @@ var NarrativeValidator = class {
220474
220577
  */
220475
220578
  checkEventReferences(context) {
220476
220579
  const violations = [];
220477
- const { narrative, narrativePath, canvas } = context;
220580
+ const { workflow, workflowPath, canvas } = context;
220478
220581
  if (!canvas || !canvas.nodes) {
220479
220582
  return violations;
220480
220583
  }
@@ -220485,10 +220588,10 @@ var NarrativeValidator = class {
220485
220588
  violations.push({
220486
220589
  ruleId: "canvas-event-format-deprecated",
220487
220590
  severity: "error",
220488
- file: narrative.canvas || "canvas",
220591
+ file: workflow.canvas || "canvas",
220489
220592
  path: `nodes[${node.id}].pv.event`,
220490
220593
  message: `Canvas node "${node.id}" uses deprecated string format for event: "${node.pv.event}"`,
220491
- impact: "Event will not be recognized by narrative validator and narratives will fail to match",
220594
+ impact: "Event will not be recognized by workflow validator and workflows will fail to match",
220492
220595
  suggestion: `Use "eventRef": "${node.pv.event}" to reference a library event, or use "event": { "name": "${node.pv.event}", "attributes": {} } for inline definition. If using eventRef, define the event schema in library.yaml under eventSchemas.`,
220493
220596
  fixable: false
220494
220597
  });
@@ -220500,47 +220603,47 @@ var NarrativeValidator = class {
220500
220603
  canvasEvents.add(node.pv.eventRef);
220501
220604
  }
220502
220605
  }
220503
- const narrativeEvents = /* @__PURE__ */ new Set();
220504
- for (const scenario of narrative.scenarios) {
220606
+ const workflowEvents = /* @__PURE__ */ new Set();
220607
+ for (const scenario of workflow.scenarios) {
220505
220608
  if (scenario.condition?.requires) {
220506
220609
  for (const eventPattern of scenario.condition.requires) {
220507
220610
  if (!eventPattern.includes("*")) {
220508
- narrativeEvents.add(eventPattern);
220611
+ workflowEvents.add(eventPattern);
220509
220612
  }
220510
220613
  }
220511
220614
  }
220512
220615
  if (scenario.template?.events) {
220513
220616
  for (const eventName of Object.keys(scenario.template.events)) {
220514
220617
  if (!eventName.includes("*")) {
220515
- narrativeEvents.add(eventName);
220618
+ workflowEvents.add(eventName);
220516
220619
  }
220517
220620
  }
220518
220621
  }
220519
220622
  }
220520
- for (const eventName of Array.from(narrativeEvents)) {
220623
+ for (const eventName of Array.from(workflowEvents)) {
220521
220624
  if (!canvasEvents.has(eventName)) {
220522
220625
  violations.push({
220523
- ruleId: "narrative-event-sync",
220626
+ ruleId: "workflow-event-sync",
220524
220627
  severity: "error",
220525
- file: narrativePath,
220628
+ file: workflowPath,
220526
220629
  path: "events",
220527
- message: `Narrative references event "${eventName}" which is not defined in canvas`,
220630
+ message: `Workflow references event "${eventName}" which is not defined in canvas`,
220528
220631
  impact: "This event will never highlight a canvas node and may never match",
220529
- suggestion: `Add event "${eventName}" to a node in ${narrative.canvas} or remove it from the narrative`,
220632
+ suggestion: `Add event "${eventName}" to a node in ${workflow.canvas} or remove it from the workflow`,
220530
220633
  fixable: false
220531
220634
  });
220532
220635
  }
220533
220636
  }
220534
- const eventsToCheckAgainst = context.allNarrativeEvents ?? narrativeEvents;
220637
+ const eventsToCheckAgainst = context.allWorkflowEvents ?? workflowEvents;
220535
220638
  for (const eventName of Array.from(canvasEvents)) {
220536
220639
  if (!eventsToCheckAgainst.has(eventName)) {
220537
220640
  violations.push({
220538
- ruleId: "narrative-event-coverage",
220641
+ ruleId: "workflow-event-coverage",
220539
220642
  severity: "warn",
220540
- file: narrativePath,
220643
+ file: workflowPath,
220541
220644
  path: "events",
220542
- message: context.allNarrativeEvents ? `Canvas defines event "${eventName}" which is not used in any narrative for this canvas` : `Canvas defines event "${eventName}" which is not used in this narrative scenario`,
220543
- impact: "This canvas node may never be highlighted during narrative playback",
220645
+ message: context.allWorkflowEvents ? `Canvas defines event "${eventName}" which is not used in any workflow for this canvas` : `Canvas defines event "${eventName}" which is not used in this workflow scenario`,
220646
+ impact: "This canvas node may never be highlighted during workflow playback",
220544
220647
  suggestion: `Add event "${eventName}" to a scenario's template.events or condition.requires`,
220545
220648
  fixable: false
220546
220649
  });
@@ -220553,19 +220656,19 @@ var NarrativeValidator = class {
220553
220656
  */
220554
220657
  checkScenarios(context) {
220555
220658
  const violations = [];
220556
- const { narrative, narrativePath } = context;
220557
- if (!narrative.scenarios || narrative.scenarios.length === 0) {
220659
+ const { workflow, workflowPath } = context;
220660
+ if (!workflow.scenarios || workflow.scenarios.length === 0) {
220558
220661
  return violations;
220559
220662
  }
220560
220663
  const scenarioIds = /* @__PURE__ */ new Set();
220561
220664
  const priorities = /* @__PURE__ */ new Set();
220562
220665
  let hasDefault = false;
220563
- narrative.scenarios.forEach((scenario, idx) => {
220666
+ workflow.scenarios.forEach((scenario, idx) => {
220564
220667
  if (!scenario.id) {
220565
220668
  violations.push({
220566
- ruleId: "narrative-scenario-valid",
220669
+ ruleId: "workflow-scenario-valid",
220567
220670
  severity: "error",
220568
- file: narrativePath,
220671
+ file: workflowPath,
220569
220672
  path: `scenarios[${idx}].id`,
220570
220673
  message: 'Scenario is missing required "id" field',
220571
220674
  impact: "Cannot identify this scenario",
@@ -220575,9 +220678,9 @@ var NarrativeValidator = class {
220575
220678
  } else {
220576
220679
  if (scenarioIds.has(scenario.id)) {
220577
220680
  violations.push({
220578
- ruleId: "narrative-scenario-valid",
220681
+ ruleId: "workflow-scenario-valid",
220579
220682
  severity: "error",
220580
- file: narrativePath,
220683
+ file: workflowPath,
220581
220684
  path: `scenarios[${idx}].id`,
220582
220685
  message: `Duplicate scenario ID: "${scenario.id}"`,
220583
220686
  impact: "Scenario IDs must be unique",
@@ -220589,9 +220692,9 @@ var NarrativeValidator = class {
220589
220692
  }
220590
220693
  if (scenario.priority === void 0 || scenario.priority === null) {
220591
220694
  violations.push({
220592
- ruleId: "narrative-scenario-valid",
220695
+ ruleId: "workflow-scenario-valid",
220593
220696
  severity: "error",
220594
- file: narrativePath,
220697
+ file: workflowPath,
220595
220698
  path: `scenarios[${idx}].priority`,
220596
220699
  message: 'Scenario is missing required "priority" field',
220597
220700
  impact: "Cannot determine scenario selection order",
@@ -220601,9 +220704,9 @@ var NarrativeValidator = class {
220601
220704
  } else {
220602
220705
  if (scenario.priority < 0) {
220603
220706
  violations.push({
220604
- ruleId: "narrative-scenario-valid",
220707
+ ruleId: "workflow-scenario-valid",
220605
220708
  severity: "error",
220606
- file: narrativePath,
220709
+ file: workflowPath,
220607
220710
  path: `scenarios[${idx}].priority`,
220608
220711
  message: "Priority must be a non-negative number",
220609
220712
  impact: "Invalid priority value",
@@ -220613,9 +220716,9 @@ var NarrativeValidator = class {
220613
220716
  }
220614
220717
  if (priorities.has(scenario.priority)) {
220615
220718
  violations.push({
220616
- ruleId: "narrative-scenario-valid",
220719
+ ruleId: "workflow-scenario-valid",
220617
220720
  severity: "error",
220618
- file: narrativePath,
220721
+ file: workflowPath,
220619
220722
  path: `scenarios[${idx}].priority`,
220620
220723
  message: `Duplicate priority: ${scenario.priority}`,
220621
220724
  impact: "Priorities must be unique to determine selection order",
@@ -220630,9 +220733,9 @@ var NarrativeValidator = class {
220630
220733
  }
220631
220734
  if (!scenario.condition) {
220632
220735
  violations.push({
220633
- ruleId: "narrative-scenario-valid",
220736
+ ruleId: "workflow-scenario-valid",
220634
220737
  severity: "error",
220635
- file: narrativePath,
220738
+ file: workflowPath,
220636
220739
  path: `scenarios[${idx}].condition`,
220637
220740
  message: 'Scenario is missing required "condition" field',
220638
220741
  impact: "Cannot determine when to use this scenario",
@@ -220640,31 +220743,31 @@ var NarrativeValidator = class {
220640
220743
  fixable: false
220641
220744
  });
220642
220745
  } else {
220643
- violations.push(...this.checkConditionStructure(scenario.condition, narrativePath, idx));
220746
+ violations.push(...this.checkConditionStructure(scenario.condition, workflowPath, idx));
220644
220747
  }
220645
220748
  if (!scenario.template) {
220646
220749
  violations.push({
220647
- ruleId: "narrative-scenario-valid",
220750
+ ruleId: "workflow-scenario-valid",
220648
220751
  severity: "error",
220649
- file: narrativePath,
220752
+ file: workflowPath,
220650
220753
  path: `scenarios[${idx}].template`,
220651
220754
  message: 'Scenario is missing required "template" field',
220652
- impact: "Cannot render narrative without a template",
220755
+ impact: "Cannot render workflow without a template",
220653
220756
  suggestion: "Add a template with introduction, events, or flow",
220654
220757
  fixable: false
220655
220758
  });
220656
220759
  } else {
220657
- violations.push(...this.checkTemplateStructure(scenario.template, narrativePath, idx));
220760
+ violations.push(...this.checkTemplateStructure(scenario.template, workflowPath, idx));
220658
220761
  }
220659
220762
  });
220660
220763
  if (!hasDefault) {
220661
220764
  violations.push({
220662
- ruleId: "narrative-scenario-valid",
220765
+ ruleId: "workflow-scenario-valid",
220663
220766
  severity: "error",
220664
- file: narrativePath,
220767
+ file: workflowPath,
220665
220768
  path: "scenarios",
220666
220769
  message: "No default scenario defined",
220667
- impact: "Narrative rendering may fail if no scenario matches",
220770
+ impact: "Workflow rendering may fail if no scenario matches",
220668
220771
  suggestion: 'Add a scenario with "condition.default: true" as a fallback',
220669
220772
  fixable: false
220670
220773
  });
@@ -220685,7 +220788,7 @@ var NarrativeValidator = class {
220685
220788
  if (!validFields.includes(key)) {
220686
220789
  if (key === "event") {
220687
220790
  violations.push({
220688
- ruleId: "narrative-condition-structure",
220791
+ ruleId: "workflow-condition-structure",
220689
220792
  severity: "error",
220690
220793
  file,
220691
220794
  path: `scenarios[${scenarioIdx}].condition.${key}`,
@@ -220696,7 +220799,7 @@ var NarrativeValidator = class {
220696
220799
  });
220697
220800
  } else if (key === "attributes") {
220698
220801
  violations.push({
220699
- ruleId: "narrative-condition-structure",
220802
+ ruleId: "workflow-condition-structure",
220700
220803
  severity: "error",
220701
220804
  file,
220702
220805
  path: `scenarios[${scenarioIdx}].condition.${key}`,
@@ -220707,7 +220810,7 @@ var NarrativeValidator = class {
220707
220810
  });
220708
220811
  } else {
220709
220812
  violations.push({
220710
- ruleId: "narrative-condition-structure",
220813
+ ruleId: "workflow-condition-structure",
220711
220814
  severity: "error",
220712
220815
  file,
220713
220816
  path: `scenarios[${scenarioIdx}].condition.${key}`,
@@ -220730,7 +220833,7 @@ var NarrativeValidator = class {
220730
220833
  const templateKeys = Object.keys(template);
220731
220834
  if (!template.events) {
220732
220835
  violations.push({
220733
- ruleId: "narrative-template-structure",
220836
+ ruleId: "workflow-template-structure",
220734
220837
  severity: "error",
220735
220838
  file,
220736
220839
  path: `scenarios[${scenarioIdx}].template`,
@@ -220741,7 +220844,7 @@ var NarrativeValidator = class {
220741
220844
  });
220742
220845
  } else if (typeof template.events !== "object" || Array.isArray(template.events)) {
220743
220846
  violations.push({
220744
- ruleId: "narrative-template-structure",
220847
+ ruleId: "workflow-template-structure",
220745
220848
  severity: "error",
220746
220849
  file,
220747
220850
  path: `scenarios[${scenarioIdx}].template.events`,
@@ -220752,7 +220855,7 @@ var NarrativeValidator = class {
220752
220855
  });
220753
220856
  } else if (Object.keys(template.events).length === 0) {
220754
220857
  violations.push({
220755
- ruleId: "narrative-template-structure",
220858
+ ruleId: "workflow-template-structure",
220756
220859
  severity: "error",
220757
220860
  file,
220758
220861
  path: `scenarios[${scenarioIdx}].template.events`,
@@ -220766,7 +220869,7 @@ var NarrativeValidator = class {
220766
220869
  if (!validFields.includes(key)) {
220767
220870
  if (key === "steps") {
220768
220871
  violations.push({
220769
- ruleId: "narrative-template-structure",
220872
+ ruleId: "workflow-template-structure",
220770
220873
  severity: "error",
220771
220874
  file,
220772
220875
  path: `scenarios[${scenarioIdx}].template.${key}`,
@@ -220777,7 +220880,7 @@ var NarrativeValidator = class {
220777
220880
  });
220778
220881
  } else if (key === "details") {
220779
220882
  violations.push({
220780
- ruleId: "narrative-template-structure",
220883
+ ruleId: "workflow-template-structure",
220781
220884
  severity: "error",
220782
220885
  file,
220783
220886
  path: `scenarios[${scenarioIdx}].template.${key}`,
@@ -220788,7 +220891,7 @@ var NarrativeValidator = class {
220788
220891
  });
220789
220892
  } else {
220790
220893
  violations.push({
220791
- ruleId: "narrative-template-structure",
220894
+ ruleId: "workflow-template-structure",
220792
220895
  severity: "error",
220793
220896
  file,
220794
220897
  path: `scenarios[${scenarioIdx}].template.${key}`,
@@ -220807,15 +220910,15 @@ var NarrativeValidator = class {
220807
220910
  */
220808
220911
  checkEventNameSyntax(context) {
220809
220912
  const violations = [];
220810
- const { narrative, narrativePath } = context;
220811
- narrative.scenarios.forEach((scenario, scenarioIdx) => {
220913
+ const { workflow, workflowPath } = context;
220914
+ workflow.scenarios.forEach((scenario, scenarioIdx) => {
220812
220915
  if (scenario.condition?.requires) {
220813
220916
  scenario.condition.requires.forEach((eventPattern, idx) => {
220814
220917
  if (eventPattern.includes("[") && eventPattern.includes("]")) {
220815
220918
  violations.push({
220816
- ruleId: "narrative-event-name-syntax",
220919
+ ruleId: "workflow-event-name-syntax",
220817
220920
  severity: "error",
220818
- file: narrativePath,
220921
+ file: workflowPath,
220819
220922
  path: `scenarios[${scenarioIdx}].condition.requires[${idx}]`,
220820
220923
  message: `Event name uses unsupported [attribute=value] syntax: "${eventPattern}"`,
220821
220924
  impact: "Attribute filter syntax is not supported - event will not match",
@@ -220829,9 +220932,9 @@ var NarrativeValidator = class {
220829
220932
  scenario.condition.excludes.forEach((eventPattern, idx) => {
220830
220933
  if (eventPattern.includes("[") && eventPattern.includes("]")) {
220831
220934
  violations.push({
220832
- ruleId: "narrative-event-name-syntax",
220935
+ ruleId: "workflow-event-name-syntax",
220833
220936
  severity: "error",
220834
- file: narrativePath,
220937
+ file: workflowPath,
220835
220938
  path: `scenarios[${scenarioIdx}].condition.excludes[${idx}]`,
220836
220939
  message: `Event name uses unsupported [attribute=value] syntax: "${eventPattern}"`,
220837
220940
  impact: "Attribute filter syntax is not supported - event will not match",
@@ -220845,9 +220948,9 @@ var NarrativeValidator = class {
220845
220948
  Object.keys(scenario.template.events).forEach((eventName) => {
220846
220949
  if (eventName.includes("[") && eventName.includes("]")) {
220847
220950
  violations.push({
220848
- ruleId: "narrative-event-name-syntax",
220951
+ ruleId: "workflow-event-name-syntax",
220849
220952
  severity: "error",
220850
- file: narrativePath,
220953
+ file: workflowPath,
220851
220954
  path: `scenarios[${scenarioIdx}].template.events["${eventName}"]`,
220852
220955
  message: `Event name uses unsupported [attribute=value] syntax: "${eventName}"`,
220853
220956
  impact: "Attribute filter syntax is not supported - template will never render",
@@ -220865,36 +220968,36 @@ var NarrativeValidator = class {
220865
220968
  */
220866
220969
  checkTemplateSyntax(context) {
220867
220970
  const violations = [];
220868
- const { narrative, narrativePath } = context;
220869
- narrative.scenarios.forEach((scenario, scenarioIdx) => {
220971
+ const { workflow, workflowPath } = context;
220972
+ workflow.scenarios.forEach((scenario, scenarioIdx) => {
220870
220973
  if (!scenario.template) {
220871
220974
  return;
220872
220975
  }
220873
220976
  const template = scenario.template;
220874
220977
  if (template.introduction) {
220875
- violations.push(...this.validateTemplateString(template.introduction, narrativePath, `scenarios[${scenarioIdx}].template.introduction`));
220978
+ violations.push(...this.validateTemplateString(template.introduction, workflowPath, `scenarios[${scenarioIdx}].template.introduction`));
220876
220979
  }
220877
220980
  if (template.summary) {
220878
- violations.push(...this.validateTemplateString(template.summary, narrativePath, `scenarios[${scenarioIdx}].template.summary`));
220981
+ violations.push(...this.validateTemplateString(template.summary, workflowPath, `scenarios[${scenarioIdx}].template.summary`));
220879
220982
  }
220880
220983
  if (template.events) {
220881
220984
  Object.entries(template.events).forEach(([eventName, templateStr]) => {
220882
- violations.push(...this.validateTemplateString(templateStr, narrativePath, `scenarios[${scenarioIdx}].template.events.${eventName}`));
220985
+ violations.push(...this.validateTemplateString(templateStr, workflowPath, `scenarios[${scenarioIdx}].template.events.${eventName}`));
220883
220986
  });
220884
220987
  }
220885
220988
  if (template.logs) {
220886
220989
  Object.entries(template.logs).forEach(([severity, templateStr]) => {
220887
220990
  if (typeof templateStr === "string") {
220888
- violations.push(...this.validateTemplateString(templateStr, narrativePath, `scenarios[${scenarioIdx}].template.logs.${severity}`));
220991
+ violations.push(...this.validateTemplateString(templateStr, workflowPath, `scenarios[${scenarioIdx}].template.logs.${severity}`));
220889
220992
  }
220890
220993
  });
220891
220994
  }
220892
220995
  if (template.flow && Array.isArray(template.flow)) {
220893
220996
  template.flow.forEach((item, flowIdx) => {
220894
220997
  if (typeof item === "string") {
220895
- violations.push(...this.validateTemplateString(item, narrativePath, `scenarios[${scenarioIdx}].template.flow[${flowIdx}]`));
220998
+ violations.push(...this.validateTemplateString(item, workflowPath, `scenarios[${scenarioIdx}].template.flow[${flowIdx}]`));
220896
220999
  } else if (typeof item === "object" && item.template) {
220897
- violations.push(...this.validateTemplateString(item.template, narrativePath, `scenarios[${scenarioIdx}].template.flow[${flowIdx}].template`));
221000
+ violations.push(...this.validateTemplateString(item.template, workflowPath, `scenarios[${scenarioIdx}].template.flow[${flowIdx}].template`));
220898
221001
  }
220899
221002
  });
220900
221003
  }
@@ -220928,7 +221031,7 @@ var NarrativeValidator = class {
220928
221031
  braceDepth--;
220929
221032
  if (braceDepth < 0) {
220930
221033
  violations.push({
220931
- ruleId: "narrative-template-syntax",
221034
+ ruleId: "workflow-template-syntax",
220932
221035
  severity: "error",
220933
221036
  file,
220934
221037
  path: path4,
@@ -220944,7 +221047,7 @@ var NarrativeValidator = class {
220944
221047
  }
220945
221048
  if (braceDepth > 0) {
220946
221049
  violations.push({
220947
- ruleId: "narrative-template-syntax",
221050
+ ruleId: "workflow-template-syntax",
220948
221051
  severity: "error",
220949
221052
  file,
220950
221053
  path: path4,
@@ -220961,7 +221064,7 @@ var NarrativeValidator = class {
220961
221064
  const colonCount = (expr.match(/:/g) || []).length;
220962
221065
  if (questionCount > colonCount) {
220963
221066
  violations.push({
220964
- ruleId: "narrative-template-syntax",
221067
+ ruleId: "workflow-template-syntax",
220965
221068
  severity: "error",
220966
221069
  file,
220967
221070
  path: path4,
@@ -220984,12 +221087,12 @@ var NarrativeValidator = class {
220984
221087
  */
220985
221088
  checkAttributeReferences(context) {
220986
221089
  const violations = [];
220987
- const { narrative, narrativePath, executionData } = context;
221090
+ const { workflow, workflowPath, executionData } = context;
220988
221091
  if (!executionData) {
220989
221092
  return violations;
220990
221093
  }
220991
221094
  const { aggregates, eventAttributes } = executionData;
220992
- for (const scenario of narrative.scenarios) {
221095
+ for (const scenario of workflow.scenarios) {
220993
221096
  const scenarioPath = `scenarios[${scenario.id}]`;
220994
221097
  if (scenario.template.introduction) {
220995
221098
  const attrs = this.extractAttributeReferences(scenario.template.introduction);
@@ -220998,7 +221101,7 @@ var NarrativeValidator = class {
220998
221101
  aggregates,
220999
221102
  null,
221000
221103
  // introduction doesn't have specific event context
221001
- narrativePath,
221104
+ workflowPath,
221002
221105
  `${scenarioPath}.template.introduction`
221003
221106
  ));
221004
221107
  }
@@ -221006,7 +221109,7 @@ var NarrativeValidator = class {
221006
221109
  for (const [eventName, eventTemplate] of Object.entries(scenario.template.events)) {
221007
221110
  const attrs = this.extractAttributeReferences(eventTemplate);
221008
221111
  const eventAttrs = eventAttributes.get(eventName);
221009
- violations.push(...this.validateAttributes(attrs, aggregates, eventAttrs || null, narrativePath, `${scenarioPath}.template.events.${eventName}`, eventName));
221112
+ violations.push(...this.validateAttributes(attrs, aggregates, eventAttrs || null, workflowPath, `${scenarioPath}.template.events.${eventName}`, eventName));
221010
221113
  }
221011
221114
  }
221012
221115
  if (scenario.template.summary) {
@@ -221016,7 +221119,7 @@ var NarrativeValidator = class {
221016
221119
  aggregates,
221017
221120
  null,
221018
221121
  // summary uses global aggregates
221019
- narrativePath,
221122
+ workflowPath,
221020
221123
  `${scenarioPath}.template.summary`
221021
221124
  ));
221022
221125
  }
@@ -221046,7 +221149,7 @@ var NarrativeValidator = class {
221046
221149
  ];
221047
221150
  const similar = this.findSimilarAttributes(attr, allKeys);
221048
221151
  violations.push({
221049
- ruleId: "narrative-attribute-undefined",
221152
+ ruleId: "workflow-attribute-undefined",
221050
221153
  severity: "warn",
221051
221154
  file,
221052
221155
  path: path4,
@@ -221062,7 +221165,7 @@ var NarrativeValidator = class {
221062
221165
  const objectKeys = Object.keys(value);
221063
221166
  const suggestions = objectKeys.slice(0, 3).map((k) => `{{${attr}.${k}}}`);
221064
221167
  violations.push({
221065
- ruleId: "narrative-attribute-object",
221168
+ ruleId: "workflow-attribute-object",
221066
221169
  severity: "warn",
221067
221170
  file,
221068
221171
  path: path4,
@@ -221111,19 +221214,19 @@ var NarrativeValidator = class {
221111
221214
  */
221112
221215
  checkFormattingOptions(context) {
221113
221216
  const violations = [];
221114
- const { narrative, narrativePath } = context;
221115
- if (!narrative.formatting) {
221217
+ const { workflow, workflowPath } = context;
221218
+ if (!workflow.formatting) {
221116
221219
  return violations;
221117
221220
  }
221118
- if (narrative.formatting.showAttributes) {
221221
+ if (workflow.formatting.showAttributes) {
221119
221222
  const validValues = ["none", "matched", "all"];
221120
- if (!validValues.includes(narrative.formatting.showAttributes)) {
221223
+ if (!validValues.includes(workflow.formatting.showAttributes)) {
221121
221224
  violations.push({
221122
- ruleId: "narrative-formatting-options",
221225
+ ruleId: "workflow-formatting-options",
221123
221226
  severity: "warn",
221124
- file: narrativePath,
221227
+ file: workflowPath,
221125
221228
  path: "formatting.showAttributes",
221126
- message: `Invalid showAttributes value: "${narrative.formatting.showAttributes}"`,
221229
+ message: `Invalid showAttributes value: "${workflow.formatting.showAttributes}"`,
221127
221230
  impact: "May not display attributes correctly",
221128
221231
  suggestion: `Use one of: ${validValues.join(", ")}`,
221129
221232
  fixable: false
@@ -221273,8 +221376,8 @@ var NarrativeValidator = class {
221273
221376
  return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date);
221274
221377
  }
221275
221378
  };
221276
- function createNarrativeValidator() {
221277
- return new NarrativeValidator();
221379
+ function createWorkflowValidator() {
221380
+ return new WorkflowValidator();
221278
221381
  }
221279
221382
 
221280
221383
  // ../core/dist/execution/ExecutionLoader.js
@@ -221558,14 +221661,14 @@ function loadGraphConfig(filePath) {
221558
221661
  return null;
221559
221662
  }
221560
221663
  }
221561
- function loadNarrativeTemplate(filePath) {
221664
+ function loadWorkflowTemplate(filePath) {
221562
221665
  if (!(0, import_node_fs11.existsSync)(filePath)) {
221563
221666
  return null;
221564
221667
  }
221565
221668
  try {
221566
221669
  const raw = (0, import_node_fs11.readFileSync)(filePath, "utf8");
221567
- const narrative = JSON.parse(raw);
221568
- return { narrative, raw };
221670
+ const workflow = JSON.parse(raw);
221671
+ return { workflow, raw };
221569
221672
  } catch {
221570
221673
  return null;
221571
221674
  }
@@ -221588,8 +221691,8 @@ function loadCanvas(filePath) {
221588
221691
  }
221589
221692
  function getFileType(filePath) {
221590
221693
  const name = (0, import_node_path12.basename)(filePath).toLowerCase();
221591
- if (name.endsWith(".narrative.json")) {
221592
- return "narrative";
221694
+ if (name.endsWith(".workflow.json")) {
221695
+ return "workflow";
221593
221696
  }
221594
221697
  if (name.endsWith(".canvas") || name.endsWith(".otel.canvas")) {
221595
221698
  return "canvas";
@@ -221772,38 +221875,38 @@ function createLintCommand() {
221772
221875
  }
221773
221876
  }
221774
221877
  const engine = createDefaultRulesEngine();
221775
- const narrativeValidator = createNarrativeValidator();
221878
+ const workflowValidator = createWorkflowValidator();
221776
221879
  const results = /* @__PURE__ */ new Map();
221777
- const narrativesByCanvas = /* @__PURE__ */ new Map();
221880
+ const workflowsByCanvas = /* @__PURE__ */ new Map();
221778
221881
  const canvasEventMap = /* @__PURE__ */ new Map();
221779
221882
  for (const filePath of configFiles) {
221780
221883
  const absolutePath = (0, import_node_path12.resolve)(cwd, filePath);
221781
221884
  const relativePath = (0, import_node_path12.relative)(cwd, absolutePath);
221782
221885
  const fileType = getFileType(absolutePath);
221783
- if (fileType === "narrative") {
221784
- const loaded = loadNarrativeTemplate(absolutePath);
221886
+ if (fileType === "workflow") {
221887
+ const loaded = loadWorkflowTemplate(absolutePath);
221785
221888
  if (!loaded) continue;
221786
- const canvasPath = loaded.narrative.canvas ? (0, import_node_path12.resolve)((0, import_node_path12.dirname)(absolutePath), loaded.narrative.canvas) : void 0;
221889
+ const canvasPath = loaded.workflow.canvas ? (0, import_node_path12.resolve)((0, import_node_path12.dirname)(absolutePath), loaded.workflow.canvas) : void 0;
221787
221890
  if (canvasPath) {
221788
221891
  const canvasKey = (0, import_node_path12.relative)(cwd, canvasPath);
221789
- if (!narrativesByCanvas.has(canvasKey)) {
221790
- narrativesByCanvas.set(canvasKey, []);
221892
+ if (!workflowsByCanvas.has(canvasKey)) {
221893
+ workflowsByCanvas.set(canvasKey, []);
221791
221894
  canvasEventMap.set(canvasKey, /* @__PURE__ */ new Set());
221792
221895
  }
221793
- narrativesByCanvas.get(canvasKey).push({ absolutePath, relativePath, loaded });
221794
- const narrativeEvents = canvasEventMap.get(canvasKey);
221795
- for (const scenario of loaded.narrative.scenarios) {
221896
+ workflowsByCanvas.get(canvasKey).push({ absolutePath, relativePath, loaded });
221897
+ const workflowEvents = canvasEventMap.get(canvasKey);
221898
+ for (const scenario of loaded.workflow.scenarios) {
221796
221899
  if (scenario.condition?.requires) {
221797
221900
  for (const eventPattern of scenario.condition.requires) {
221798
221901
  if (!eventPattern.includes("*")) {
221799
- narrativeEvents.add(eventPattern);
221902
+ workflowEvents.add(eventPattern);
221800
221903
  }
221801
221904
  }
221802
221905
  }
221803
221906
  if (scenario.template?.events) {
221804
221907
  for (const eventName of Object.keys(scenario.template.events)) {
221805
221908
  if (!eventName.includes("*")) {
221806
- narrativeEvents.add(eventName);
221909
+ workflowEvents.add(eventName);
221807
221910
  }
221808
221911
  }
221809
221912
  }
@@ -221815,8 +221918,8 @@ function createLintCommand() {
221815
221918
  const absolutePath = (0, import_node_path12.resolve)(cwd, filePath);
221816
221919
  const relativePath = (0, import_node_path12.relative)(cwd, absolutePath);
221817
221920
  const fileType = getFileType(absolutePath);
221818
- if (fileType === "narrative") {
221819
- const loaded = loadNarrativeTemplate(absolutePath);
221921
+ if (fileType === "workflow") {
221922
+ const loaded = loadWorkflowTemplate(absolutePath);
221820
221923
  if (!loaded) {
221821
221924
  results.set(relativePath, {
221822
221925
  violations: [
@@ -221824,7 +221927,7 @@ function createLintCommand() {
221824
221927
  ruleId: "parse-error",
221825
221928
  severity: "error",
221826
221929
  file: relativePath,
221827
- message: `Could not parse narrative file: ${filePath}`,
221930
+ message: `Could not parse workflow file: ${filePath}`,
221828
221931
  impact: "File cannot be validated",
221829
221932
  fixable: false
221830
221933
  }
@@ -221837,20 +221940,20 @@ function createLintCommand() {
221837
221940
  });
221838
221941
  continue;
221839
221942
  }
221840
- const canvasPath = loaded.narrative.canvas ? (0, import_node_path12.resolve)((0, import_node_path12.dirname)(absolutePath), loaded.narrative.canvas) : void 0;
221943
+ const canvasPath = loaded.workflow.canvas ? (0, import_node_path12.resolve)((0, import_node_path12.dirname)(absolutePath), loaded.workflow.canvas) : void 0;
221841
221944
  const canvas = canvasPath ? loadCanvas(canvasPath) : void 0;
221842
221945
  const canvasKey = canvasPath ? (0, import_node_path12.relative)(cwd, canvasPath) : void 0;
221843
- const allNarrativeEvents = canvasKey ? canvasEventMap.get(canvasKey) : void 0;
221844
- const narrativeResult = await narrativeValidator.validate({
221845
- narrative: loaded.narrative,
221846
- narrativePath: relativePath,
221946
+ const allWorkflowEvents = canvasKey ? canvasEventMap.get(canvasKey) : void 0;
221947
+ const workflowResult = await workflowValidator.validate({
221948
+ workflow: loaded.workflow,
221949
+ workflowPath: relativePath,
221847
221950
  canvas: canvas ?? void 0,
221848
221951
  canvasPath: canvasKey,
221849
221952
  basePath: (0, import_node_path12.dirname)(absolutePath),
221850
221953
  rawContent: loaded.raw,
221851
- allNarrativeEvents
221954
+ allWorkflowEvents
221852
221955
  });
221853
- const violations = narrativeResult.violations.map((v) => ({
221956
+ const violations = workflowResult.violations.map((v) => ({
221854
221957
  ruleId: v.ruleId,
221855
221958
  severity: v.severity,
221856
221959
  file: v.file,
@@ -221863,11 +221966,11 @@ function createLintCommand() {
221863
221966
  }));
221864
221967
  results.set(relativePath, {
221865
221968
  violations,
221866
- errorCount: narrativeResult.errorCount,
221867
- warningCount: narrativeResult.warningCount,
221868
- fixableCount: narrativeResult.fixableCount,
221969
+ errorCount: workflowResult.errorCount,
221970
+ warningCount: workflowResult.warningCount,
221971
+ fixableCount: workflowResult.fixableCount,
221869
221972
  byCategory: { schema: 0, reference: 0, structure: 0, pattern: 0, library: 0 },
221870
- // Could categorize narrative rules
221973
+ // Could categorize workflow rules
221871
221974
  byRule: countByRule(violations)
221872
221975
  });
221873
221976
  } else {
@@ -222059,22 +222162,22 @@ function createCoverageCommand() {
222059
222162
  return command;
222060
222163
  }
222061
222164
 
222062
- // src/commands/narrative/validate.ts
222165
+ // src/commands/workflow/validate.ts
222063
222166
  var import_node_path15 = require("node:path");
222064
222167
  var import_node_fs12 = require("node:fs");
222065
222168
 
222066
- // src/commands/narrative/utils.ts
222169
+ // src/commands/workflow/utils.ts
222067
222170
  var import_promises4 = require("node:fs/promises");
222068
222171
  var import_node_path14 = require("node:path");
222069
- async function loadNarrative(filePath) {
222172
+ async function loadWorkflow(filePath) {
222070
222173
  try {
222071
222174
  const content = await (0, import_promises4.readFile)(filePath, "utf-8");
222072
222175
  return JSON.parse(content);
222073
222176
  } catch (error) {
222074
222177
  if (error.code === "ENOENT") {
222075
- throw new Error(`Narrative file not found: ${filePath}`);
222178
+ throw new Error(`Workflow file not found: ${filePath}`);
222076
222179
  }
222077
- throw new Error(`Failed to parse narrative file: ${error.message}`);
222180
+ throw new Error(`Failed to parse workflow file: ${error.message}`);
222078
222181
  }
222079
222182
  }
222080
222183
  async function loadExecution(filePath) {
@@ -222191,21 +222294,21 @@ function capitalize(str3) {
222191
222294
  return str3.charAt(0).toUpperCase() + str3.slice(1);
222192
222295
  }
222193
222296
 
222194
- // src/commands/narrative/validate.ts
222297
+ // src/commands/workflow/validate.ts
222195
222298
  function createValidateCommand2() {
222196
222299
  const command = new Command("validate");
222197
- command.description("Validate narrative template syntax, schema, and references").argument("<file>", "Path to .narrative.json file").option("--canvas <path>", "Override canvas file path for validation").option("--execution <path>", "Execution file (.otel.json) for validating attribute references").option("--json", "Output violations as JSON").option("-q, --quiet", "Only show errors, suppress warnings").option("-d, --dir <path>", "Project directory (default: cwd)").action(async (file, options) => {
222300
+ command.description("Validate workflow template syntax, schema, and references").argument("<file>", "Path to .workflow.json file").option("--canvas <path>", "Override canvas file path for validation").option("--execution <path>", "Execution file (.otel.json) for validating attribute references").option("--json", "Output violations as JSON").option("-q, --quiet", "Only show errors, suppress warnings").option("-d, --dir <path>", "Project directory (default: cwd)").action(async (file, options) => {
222198
222301
  try {
222199
222302
  const baseDir = options.dir || process.cwd();
222200
- const narrativePath = resolvePath(file, baseDir);
222201
- const narrative = await loadNarrative(narrativePath);
222303
+ const workflowPath = resolvePath(file, baseDir);
222304
+ const workflow = await loadWorkflow(workflowPath);
222202
222305
  let canvasPath;
222203
222306
  let canvas;
222204
222307
  if (options.canvas) {
222205
222308
  canvasPath = resolvePath(options.canvas, baseDir);
222206
- } else if (narrative.canvas) {
222207
- const narrativeDir = (0, import_node_path15.dirname)(narrativePath);
222208
- canvasPath = (0, import_node_path15.resolve)(narrativeDir, narrative.canvas);
222309
+ } else if (workflow.canvas) {
222310
+ const workflowDir = (0, import_node_path15.dirname)(workflowPath);
222311
+ canvasPath = (0, import_node_path15.resolve)(workflowDir, workflow.canvas);
222209
222312
  }
222210
222313
  if (canvasPath) {
222211
222314
  try {
@@ -222241,10 +222344,10 @@ function createValidateCommand2() {
222241
222344
  console.error(source_default.gray(" Attribute validation will be skipped"));
222242
222345
  }
222243
222346
  }
222244
- const validator = new NarrativeValidator();
222347
+ const validator = new WorkflowValidator();
222245
222348
  const context = {
222246
- narrative,
222247
- narrativePath,
222349
+ workflow,
222350
+ workflowPath,
222248
222351
  canvasPath,
222249
222352
  canvas,
222250
222353
  basePath: baseDir,
@@ -222271,8 +222374,8 @@ function createValidateCommand2() {
222271
222374
  summary: {
222272
222375
  errors: errors.length,
222273
222376
  warnings: warnings.length,
222274
- scenarioCount: narrative.scenarios.length,
222275
- hasDefault: narrative.scenarios.some((s) => s.condition.default),
222377
+ scenarioCount: workflow.scenarios.length,
222378
+ hasDefault: workflow.scenarios.some((s) => s.condition.default),
222276
222379
  attributeValidation: executionData ? "enabled" : "skipped"
222277
222380
  }
222278
222381
  };
@@ -222285,14 +222388,14 @@ Validating: ${file}
222285
222388
  console.log(source_default.green("\u2713"), "Schema validation passed");
222286
222389
  console.log(
222287
222390
  source_default.green("\u2713"),
222288
- `${narrative.scenarios.length} scenarios found`
222391
+ `${workflow.scenarios.length} scenarios found`
222289
222392
  );
222290
- const hasDefault = narrative.scenarios.some((s) => s.condition.default);
222393
+ const hasDefault = workflow.scenarios.some((s) => s.condition.default);
222291
222394
  console.log(
222292
222395
  source_default.green("\u2713"),
222293
222396
  hasDefault ? "Default scenario present" : "No default scenario"
222294
222397
  );
222295
- const priorities = narrative.scenarios.map((s) => s.priority);
222398
+ const priorities = workflow.scenarios.map((s) => s.priority);
222296
222399
  const allUnique = new Set(priorities).size === priorities.length;
222297
222400
  console.log(
222298
222401
  source_default.green("\u2713"),
@@ -222301,7 +222404,7 @@ Validating: ${file}
222301
222404
  if (canvasPath) {
222302
222405
  console.log(
222303
222406
  source_default.green("\u2713"),
222304
- `Canvas: ${narrative.canvas || canvasPath} \u2713`
222407
+ `Canvas: ${workflow.canvas || canvasPath} \u2713`
222305
222408
  );
222306
222409
  }
222307
222410
  } else {
@@ -222333,10 +222436,10 @@ ${icon} ${severity}: ${violation.message}`);
222333
222436
  console.log(source_default.green(" \u2022 0 warnings"));
222334
222437
  }
222335
222438
  console.log(
222336
- source_default.gray(` \u2022 ${narrative.scenarios.length} scenario(s)`)
222439
+ source_default.gray(` \u2022 ${workflow.scenarios.length} scenario(s)`)
222337
222440
  );
222338
222441
  if (canvasPath) {
222339
- console.log(source_default.gray(` \u2022 Canvas: ${narrative.canvas || canvasPath}`));
222442
+ console.log(source_default.gray(` \u2022 Canvas: ${workflow.canvas || canvasPath}`));
222340
222443
  }
222341
222444
  if (executionData) {
222342
222445
  console.log(
@@ -222362,7 +222465,7 @@ ${icon} ${severity}: ${violation.message}`);
222362
222465
  return command;
222363
222466
  }
222364
222467
 
222365
- // src/commands/narrative/inspect.ts
222468
+ // src/commands/workflow/inspect.ts
222366
222469
  function createInspectCommand() {
222367
222470
  const command = new Command("inspect");
222368
222471
  command.description("Inspect execution file and show available attributes for templates").argument("<execution>", "Path to .otel.json execution file").option("--events", "Show all events").option("--aggregates", "Show computed aggregates (default)", true).option("--json", "Output as JSON").option("--filter <pattern>", "Filter attributes by pattern (e.g., auth.*)").action(async (execution, options) => {
@@ -222462,12 +222565,12 @@ ${capitalize(prefix)}:`));
222462
222565
  return command;
222463
222566
  }
222464
222567
 
222465
- // src/commands/narrative/render.ts
222568
+ // src/commands/workflow/render.ts
222466
222569
  function createRenderCommand() {
222467
222570
  const command = new Command("render");
222468
- command.description("Render narrative template using execution data").argument("<narrative>", "Path to .narrative.json file").argument("<execution>", "Path to .otel.json execution file").option("--mode <mode>", "Override rendering mode: span-tree, timeline").option("--scenario <id>", "Force specific scenario (skip auto-selection)").option("--json", "Output structured result as JSON").option("--format <format>", "Output format: text (default), markdown, json", "text").option("--show-metadata", "Include rendering metadata in output").action(async (narrativePath, executionPath, options) => {
222571
+ command.description("Render workflow template using execution data").argument("<workflow>", "Path to .workflow.json file").argument("<execution>", "Path to .otel.json execution file").option("--mode <mode>", "Override rendering mode: span-tree, timeline").option("--scenario <id>", "Force specific scenario (skip auto-selection)").option("--json", "Output structured result as JSON").option("--format <format>", "Output format: text (default), markdown, json", "text").option("--show-metadata", "Include rendering metadata in output").action(async (workflowPath, executionPath, options) => {
222469
222572
  try {
222470
- const narrative = await loadNarrative(resolvePath(narrativePath));
222573
+ const workflow = await loadWorkflow(resolvePath(workflowPath));
222471
222574
  const executionData = await loadExecution(resolvePath(executionPath));
222472
222575
  const events = executionToEvents(executionData);
222473
222576
  if (options.mode) {
@@ -222477,21 +222580,21 @@ function createRenderCommand() {
222477
222580
  `Invalid mode: ${options.mode}. Must be one of: ${validModes.join(", ")}`
222478
222581
  );
222479
222582
  }
222480
- narrative.mode = options.mode;
222583
+ workflow.mode = options.mode;
222481
222584
  }
222482
- const result = renderNarrative(narrative, events);
222483
- const selectedScenario = narrative.scenarios.find((s) => s.id === result.scenarioId);
222585
+ const result = renderWorkflow(workflow, events);
222586
+ const selectedScenario = workflow.scenarios.find((s) => s.id === result.scenarioId);
222484
222587
  if (options.scenario) {
222485
- const scenario = narrative.scenarios.find((s) => s.id === options.scenario);
222588
+ const scenario = workflow.scenarios.find((s) => s.id === options.scenario);
222486
222589
  if (!scenario) {
222487
222590
  throw new Error(`Scenario not found: ${options.scenario}`);
222488
222591
  }
222489
222592
  }
222490
222593
  if (options.json) {
222491
222594
  const output = {
222492
- narrative: narrativePath,
222595
+ workflow: workflowPath,
222493
222596
  execution: executionPath,
222494
- mode: narrative.mode,
222597
+ mode: workflow.mode,
222495
222598
  scenario: {
222496
222599
  id: selectedScenario?.id,
222497
222600
  priority: selectedScenario?.priority,
@@ -222505,9 +222608,9 @@ function createRenderCommand() {
222505
222608
  console.log(JSON.stringify(output, null, 2));
222506
222609
  } else {
222507
222610
  if (!options.format || options.format === "text") {
222508
- console.log(source_default.gray(`Rendering: ${narrativePath}`));
222611
+ console.log(source_default.gray(`Rendering: ${workflowPath}`));
222509
222612
  console.log(source_default.gray(`Execution: ${executionPath}`));
222510
- console.log(source_default.gray(`Mode: ${narrative.mode}`));
222613
+ console.log(source_default.gray(`Mode: ${workflow.mode}`));
222511
222614
  if (selectedScenario) {
222512
222615
  console.log(
222513
222616
  source_default.gray(
@@ -222554,16 +222657,16 @@ function createRenderCommand() {
222554
222657
  return command;
222555
222658
  }
222556
222659
 
222557
- // src/commands/narrative/test.ts
222660
+ // src/commands/workflow/test.ts
222558
222661
  function createTestCommand() {
222559
222662
  const command = new Command("test");
222560
- command.description("Test scenario matching and show why scenarios match or don't match").argument("<narrative>", "Path to .narrative.json file").argument("<execution>", "Path to .otel.json execution file").option("--show-all", "Show all scenarios (not just matches)").option("--show-aggregates", "Display computed aggregates").option("--json", "Output as JSON").action(async (narrativePath, executionPath, options) => {
222663
+ command.description("Test scenario matching and show why scenarios match or don't match").argument("<workflow>", "Path to .workflow.json file").argument("<execution>", "Path to .otel.json execution file").option("--show-all", "Show all scenarios (not just matches)").option("--show-aggregates", "Display computed aggregates").option("--json", "Output as JSON").action(async (workflowPath, executionPath, options) => {
222561
222664
  try {
222562
- const narrative = await loadNarrative(resolvePath(narrativePath));
222665
+ const workflow = await loadWorkflow(resolvePath(workflowPath));
222563
222666
  const executionData = await loadExecution(resolvePath(executionPath));
222564
222667
  const events = executionToEvents(executionData);
222565
222668
  const aggregates = computeAggregates(events);
222566
- const scenarioResults = narrative.scenarios.map((scenario) => {
222669
+ const scenarioResults = workflow.scenarios.map((scenario) => {
222567
222670
  const condition = scenario.condition;
222568
222671
  const matched = matchesCondition(condition, events, aggregates);
222569
222672
  let reason;
@@ -222604,11 +222707,11 @@ function createTestCommand() {
222604
222707
  excludesResults
222605
222708
  };
222606
222709
  });
222607
- const matchResult = selectScenario(narrative, events, aggregates);
222710
+ const matchResult = selectScenario(workflow, events, aggregates);
222608
222711
  const selectedScenario = matchResult.scenario;
222609
222712
  if (options.json) {
222610
222713
  const output = {
222611
- narrative: narrativePath,
222714
+ workflow: workflowPath,
222612
222715
  execution: executionPath,
222613
222716
  scenarios: scenarioResults.map((r) => ({
222614
222717
  id: r.scenario.id,
@@ -222624,7 +222727,7 @@ function createTestCommand() {
222624
222727
  console.log(JSON.stringify(output, null, 2));
222625
222728
  } else {
222626
222729
  console.log(source_default.bold(`
222627
- Testing: ${narrativePath}`));
222730
+ Testing: ${workflowPath}`));
222628
222731
  console.log(source_default.gray(`Execution: ${executionPath}
222629
222732
  `));
222630
222733
  console.log(source_default.bold("Scenario Matching Results:"));
@@ -222693,27 +222796,27 @@ ${icon} ${source_default.bold(result.scenario.id)} (priority: ${result.scenario.
222693
222796
  return command;
222694
222797
  }
222695
222798
 
222696
- // src/commands/narrative/list.ts
222799
+ // src/commands/workflow/list.ts
222697
222800
  var import_promises5 = require("node:fs/promises");
222698
222801
  var import_node_path16 = require("node:path");
222699
222802
  function createListCommand2() {
222700
222803
  const command = new Command("list");
222701
- command.description("List all narrative files in project").argument("[dir]", "Directory to search (default: .principal-views/)").option("--json", "Output as JSON").option("--show-canvas", "Show linked canvas files").action(async (dir, options) => {
222804
+ command.description("List all workflow files in project").argument("[dir]", "Directory to search (default: .principal-views/)").option("--json", "Output as JSON").option("--show-canvas", "Show linked canvas files").action(async (dir, options) => {
222702
222805
  try {
222703
222806
  const searchDir = dir || ".principal-views";
222704
222807
  const searchPath = (0, import_node_path16.resolve)(process.cwd(), searchDir);
222705
- const files = await globby("**/*.narrative.json", {
222808
+ const files = await globby("**/*.workflow.json", {
222706
222809
  cwd: searchPath,
222707
222810
  ignore: ["node_modules/**", ".git/**", "__executions__/**"]
222708
222811
  });
222709
- const narratives = await Promise.all(
222812
+ const workflows = await Promise.all(
222710
222813
  files.map(async (file) => {
222711
222814
  const fullPath = (0, import_node_path16.join)(searchPath, file);
222712
- const narrative = await loadNarrative(fullPath);
222815
+ const workflow = await loadWorkflow(fullPath);
222713
222816
  let canvasExists;
222714
- if (options.showCanvas && narrative.canvas) {
222715
- const narrativeDir = (0, import_node_path16.dirname)(fullPath);
222716
- const canvasPath = (0, import_node_path16.resolve)(narrativeDir, narrative.canvas);
222817
+ if (options.showCanvas && workflow.canvas) {
222818
+ const workflowDir = (0, import_node_path16.dirname)(fullPath);
222819
+ const canvasPath = (0, import_node_path16.resolve)(workflowDir, workflow.canvas);
222717
222820
  try {
222718
222821
  await (0, import_promises5.access)(canvasPath);
222719
222822
  canvasExists = true;
@@ -222721,23 +222824,23 @@ function createListCommand2() {
222721
222824
  canvasExists = false;
222722
222825
  }
222723
222826
  }
222724
- const defaultCount = narrative.scenarios.filter((s) => s.condition.default).length;
222827
+ const defaultCount = workflow.scenarios.filter((s) => s.condition.default).length;
222725
222828
  return {
222726
222829
  file: (0, import_node_path16.join)(searchDir, file),
222727
- canvas: narrative.canvas,
222830
+ canvas: workflow.canvas,
222728
222831
  canvasExists,
222729
- scenarioCount: narrative.scenarios.length,
222832
+ scenarioCount: workflow.scenarios.length,
222730
222833
  defaultCount,
222731
- mode: narrative.mode,
222732
- name: narrative.name
222834
+ mode: workflow.mode,
222835
+ name: workflow.name
222733
222836
  };
222734
222837
  })
222735
222838
  );
222736
222839
  if (options.json) {
222737
222840
  const output = {
222738
222841
  searchDir,
222739
- count: narratives.length,
222740
- narratives: narratives.map((n) => ({
222842
+ count: workflows.length,
222843
+ workflows: workflows.map((n) => ({
222741
222844
  file: n.file,
222742
222845
  name: n.name,
222743
222846
  canvas: n.canvas,
@@ -222749,36 +222852,36 @@ function createListCommand2() {
222749
222852
  };
222750
222853
  console.log(JSON.stringify(output, null, 2));
222751
222854
  } else {
222752
- console.log(source_default.bold("\nNarrative Templates:"));
222855
+ console.log(source_default.bold("\nWorkflow Templates:"));
222753
222856
  console.log("\u2501".repeat(60));
222754
- if (narratives.length === 0) {
222857
+ if (workflows.length === 0) {
222755
222858
  console.log(source_default.yellow(`
222756
- No narrative templates found in ${searchDir}`));
222859
+ No workflow templates found in ${searchDir}`));
222757
222860
  console.log();
222758
222861
  return;
222759
222862
  }
222760
- for (const narrative of narratives) {
222863
+ for (const workflow of workflows) {
222761
222864
  console.log(source_default.bold(`
222762
- ${narrative.file}`));
222763
- if (narrative.name) {
222764
- console.log(source_default.gray(` Name: ${narrative.name}`));
222865
+ ${workflow.file}`));
222866
+ if (workflow.name) {
222867
+ console.log(source_default.gray(` Name: ${workflow.name}`));
222765
222868
  }
222766
- if (options.showCanvas && narrative.canvas) {
222767
- const status = narrative.canvasExists ? source_default.green("\u2713") : source_default.red("\u2717");
222768
- console.log(source_default.gray(` Canvas: ${narrative.canvas} ${status}`));
222769
- } else if (narrative.canvas) {
222770
- console.log(source_default.gray(` Canvas: ${narrative.canvas}`));
222869
+ if (options.showCanvas && workflow.canvas) {
222870
+ const status = workflow.canvasExists ? source_default.green("\u2713") : source_default.red("\u2717");
222871
+ console.log(source_default.gray(` Canvas: ${workflow.canvas} ${status}`));
222872
+ } else if (workflow.canvas) {
222873
+ console.log(source_default.gray(` Canvas: ${workflow.canvas}`));
222771
222874
  }
222772
222875
  console.log(
222773
222876
  source_default.gray(
222774
- ` Scenarios: ${narrative.scenarioCount} (${narrative.defaultCount} default)`
222877
+ ` Scenarios: ${workflow.scenarioCount} (${workflow.defaultCount} default)`
222775
222878
  )
222776
222879
  );
222777
- console.log(source_default.gray(` Mode: ${narrative.mode}`));
222880
+ console.log(source_default.gray(` Mode: ${workflow.mode}`));
222778
222881
  }
222779
222882
  console.log(
222780
222883
  source_default.bold(`
222781
- Found ${narratives.length} narrative template(s)`)
222884
+ Found ${workflows.length} workflow template(s)`)
222782
222885
  );
222783
222886
  console.log();
222784
222887
  }
@@ -222790,10 +222893,10 @@ Found ${narratives.length} narrative template(s)`)
222790
222893
  return command;
222791
222894
  }
222792
222895
 
222793
- // src/commands/narrative/index.ts
222794
- function createNarrativeCommand() {
222795
- const command = new Command("narrative");
222796
- command.description("Validate, test, and debug narrative templates").addCommand(createValidateCommand2()).addCommand(createInspectCommand()).addCommand(createRenderCommand()).addCommand(createTestCommand()).addCommand(createListCommand2());
222896
+ // src/commands/workflow/index.ts
222897
+ function createWorkflowCommand() {
222898
+ const command = new Command("workflow");
222899
+ command.description("Validate, test, and debug workflow templates").addCommand(createValidateCommand2()).addCommand(createInspectCommand()).addCommand(createRenderCommand()).addCommand(createTestCommand()).addCommand(createListCommand2());
222797
222900
  return command;
222798
222901
  }
222799
222902
 
@@ -222812,7 +222915,7 @@ program2.addCommand(createFormatsCommand());
222812
222915
  program2.addCommand(createDoctorCommand());
222813
222916
  program2.addCommand(createHooksCommand());
222814
222917
  program2.addCommand(createCoverageCommand());
222815
- program2.addCommand(createNarrativeCommand());
222918
+ program2.addCommand(createWorkflowCommand());
222816
222919
  program2.parse(process.argv);
222817
222920
  if (!process.argv.slice(2).length) {
222818
222921
  program2.outputHelp();