scene-capability-engine 3.0.8 → 3.2.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 (51) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/docs/331-poc-adaptation-roadmap.md +21 -2
  3. package/docs/331-poc-dual-track-integration-guide.md +10 -6
  4. package/docs/331-poc-weekly-delivery-checklist.md +5 -0
  5. package/docs/README.md +6 -0
  6. package/docs/command-reference.md +262 -4
  7. package/docs/handoff-profile-integration-guide.md +88 -0
  8. package/docs/interactive-customization/331-poc-sce-integration-checklist.md +148 -0
  9. package/docs/interactive-customization/README.md +362 -0
  10. package/docs/interactive-customization/adapter-extension-contract.md +55 -0
  11. package/docs/interactive-customization/adapter-extension-contract.sample.json +59 -0
  12. package/docs/interactive-customization/adapter-extension-contract.schema.json +192 -0
  13. package/docs/interactive-customization/approval-role-policy-baseline.json +36 -0
  14. package/docs/interactive-customization/change-intent.schema.json +72 -0
  15. package/docs/interactive-customization/change-plan.sample.json +41 -0
  16. package/docs/interactive-customization/change-plan.schema.json +125 -0
  17. package/docs/interactive-customization/cross-industry-replication-guide.md +49 -0
  18. package/docs/interactive-customization/dialogue-governance-policy-baseline.json +49 -0
  19. package/docs/interactive-customization/domain-pack-extension-flow.md +71 -0
  20. package/docs/interactive-customization/execution-record.schema.json +62 -0
  21. package/docs/interactive-customization/governance-alert-playbook.md +51 -0
  22. package/docs/interactive-customization/governance-report-template.md +46 -0
  23. package/docs/interactive-customization/governance-threshold-baseline.json +14 -0
  24. package/docs/interactive-customization/guardrail-policy-baseline.json +27 -0
  25. package/docs/interactive-customization/high-risk-action-catalog.json +22 -0
  26. package/docs/interactive-customization/moqui-adapter-interface.md +40 -0
  27. package/docs/interactive-customization/moqui-context-provider.sample.json +72 -0
  28. package/docs/interactive-customization/moqui-copilot-context-contract.json +50 -0
  29. package/docs/interactive-customization/moqui-copilot-integration-guide.md +100 -0
  30. package/docs/interactive-customization/moqui-interactive-template-playbook.md +94 -0
  31. package/docs/interactive-customization/non-technical-usability-report.md +57 -0
  32. package/docs/interactive-customization/page-context.sample.json +73 -0
  33. package/docs/interactive-customization/page-context.schema.json +150 -0
  34. package/docs/interactive-customization/phase-acceptance-evidence.md +110 -0
  35. package/docs/interactive-customization/runtime-mode-policy-baseline.json +99 -0
  36. package/docs/moqui-template-core-library-playbook.md +28 -0
  37. package/docs/release-checklist.md +29 -4
  38. package/docs/security-governance-default-baseline.md +54 -0
  39. package/docs/starter-kit/README.md +50 -0
  40. package/docs/starter-kit/handoff-manifest.starter.json +32 -0
  41. package/docs/starter-kit/handoff-profile-ci.sample.yml +53 -0
  42. package/docs/starter-kit/release.workflow.sample.yml +41 -0
  43. package/docs/zh/README.md +12 -0
  44. package/lib/auto/moqui-recovery-sequence.js +62 -0
  45. package/lib/commands/auto.js +245 -34
  46. package/lib/commands/scene.js +867 -0
  47. package/lib/data/moqui-capability-lexicon.json +14 -1
  48. package/lib/interactive-customization/change-plan-gate-core.js +201 -0
  49. package/lib/interactive-customization/index.js +9 -0
  50. package/lib/interactive-customization/moqui-interactive-adapter.js +732 -0
  51. package/package.json +27 -2
@@ -557,6 +557,141 @@ function registerSceneCommands(program) {
557
557
  await runSceneMoquiBaselineCommand(options);
558
558
  });
559
559
 
560
+ sceneCmd
561
+ .command('interactive-loop')
562
+ .description('Run one-command interactive customization loop (intent->plan->gate->approval->optional low-risk apply)')
563
+ .option('--context <path>', 'Page context JSON file')
564
+ .option('--goal <text>', 'Business goal text')
565
+ .option('--goal-file <path>', 'Path to business goal text file')
566
+ .option('--user-id <id>', 'User identifier')
567
+ .option('--session-id <id>', 'Session identifier')
568
+ .option('--execution-mode <mode>', 'suggestion|apply', 'suggestion')
569
+ .option('--policy <path>', 'Guardrail policy override path')
570
+ .option('--catalog <path>', 'High-risk catalog override path')
571
+ .option('--dialogue-policy <path>', 'Dialogue governance policy override path')
572
+ .option('--dialogue-out <path>', 'Dialogue governance report output path')
573
+ .option('--runtime-mode <name>', 'Runtime mode (user-assist|ops-fix|feature-dev)', 'ops-fix')
574
+ .option('--runtime-environment <name>', 'Runtime environment (dev|staging|prod)', 'staging')
575
+ .option('--runtime-policy <path>', 'Runtime mode/environment policy override path')
576
+ .option('--runtime-out <path>', 'Runtime policy evaluation output path')
577
+ .option('--context-contract <path>', 'Context contract override path for interactive intent build')
578
+ .option('--no-strict-contract', 'Do not fail when context contract validation has issues')
579
+ .option('--moqui-config <path>', 'Moqui adapter runtime config path')
580
+ .option('--out-dir <path>', 'Loop artifact root directory')
581
+ .option('--out <path>', 'Loop summary output file path')
582
+ .option('--work-order-out <path>', 'Work-order JSON output file path')
583
+ .option('--work-order-markdown-out <path>', 'Work-order markdown output file path')
584
+ .option('--approval-actor <id>', 'Approval workflow actor')
585
+ .option('--approval-actor-role <name>', 'Approval workflow actor role')
586
+ .option('--approver-actor <id>', 'Auto-approve actor')
587
+ .option('--approver-actor-role <name>', 'Auto-approve actor role')
588
+ .option('--approval-role-policy <path>', 'Approval role policy JSON path')
589
+ .option('--skip-submit', 'Skip approval submit step')
590
+ .option('--auto-approve-low-risk', 'Auto-approve low-risk allow plans')
591
+ .option('--auto-execute-low-risk', 'Auto-run low-risk apply for allow+low plans')
592
+ .option('--allow-suggestion-apply', 'Allow applying plans generated in suggestion mode')
593
+ .option('--live-apply', 'Enable live apply mode')
594
+ .option('--no-dry-run', 'Disable dry-run simulation')
595
+ .option('--feedback-score <number>', 'Optional feedback score (0-5)')
596
+ .option('--feedback-comment <text>', 'Optional feedback comment')
597
+ .option('--feedback-tags <csv>', 'Optional feedback tags (comma-separated)')
598
+ .option('--feedback-channel <channel>', 'Feedback channel (ui|cli|api|other)', 'ui')
599
+ .option('--auth-password <text>', 'One-time password for protected execute action')
600
+ .option('--auth-password-hash <sha256>', 'Password verifier hash override')
601
+ .option('--auth-password-env <name>', 'Password hash environment variable name')
602
+ .option('--fail-on-dialogue-deny', 'Exit code 2 when dialogue decision is deny')
603
+ .option('--fail-on-gate-deny', 'Exit code 2 when gate decision is deny')
604
+ .option('--fail-on-gate-non-allow', 'Exit code 2 when gate decision is deny/review-required')
605
+ .option('--fail-on-runtime-non-allow', 'Exit code 2 when runtime decision is deny/review-required')
606
+ .option('--fail-on-execute-blocked', 'Exit code 2 when auto execute result is blocked/non-success')
607
+ .option('--json', 'Print payload as JSON')
608
+ .action(async (options) => {
609
+ await runSceneInteractiveLoopCommand(options);
610
+ });
611
+
612
+ sceneCmd
613
+ .command('context-bridge')
614
+ .description('Normalize provider payload into SCE interactive page-context contract')
615
+ .option('--input <path>', 'Raw provider payload JSON path')
616
+ .option('--provider <name>', 'Provider dialect (moqui|generic)', 'moqui')
617
+ .option('--out-context <path>', 'Normalized page-context output path')
618
+ .option('--out-report <path>', 'Bridge report output path')
619
+ .option('--context-contract <path>', 'Context contract override path')
620
+ .option('--no-strict-contract', 'Do not fail when context contract validation has issues')
621
+ .option('--json', 'Print payload as JSON')
622
+ .action(async (options) => {
623
+ await runSceneContextBridgeCommand(options);
624
+ });
625
+
626
+ sceneCmd
627
+ .command('interactive-flow')
628
+ .description('Run one-command interactive flow (context-bridge -> interactive-loop)')
629
+ .option('--input <path>', 'Raw provider payload JSON path')
630
+ .option('--provider <name>', 'Provider dialect (moqui|generic)', 'moqui')
631
+ .option('--goal <text>', 'Business goal text')
632
+ .option('--goal-file <path>', 'Path to business goal text file')
633
+ .option('--user-id <id>', 'User identifier')
634
+ .option('--session-id <id>', 'Session identifier')
635
+ .option('--execution-mode <mode>', 'suggestion|apply', 'suggestion')
636
+ .option('--policy <path>', 'Guardrail policy override path')
637
+ .option('--catalog <path>', 'High-risk catalog override path')
638
+ .option('--dialogue-policy <path>', 'Dialogue governance policy override path')
639
+ .option('--dialogue-out <path>', 'Dialogue governance report output path')
640
+ .option('--runtime-mode <name>', 'Runtime mode (user-assist|ops-fix|feature-dev)', 'ops-fix')
641
+ .option('--runtime-environment <name>', 'Runtime environment (dev|staging|prod)', 'staging')
642
+ .option('--runtime-policy <path>', 'Runtime mode/environment policy override path')
643
+ .option('--runtime-out <path>', 'Runtime policy evaluation output path')
644
+ .option('--context-contract <path>', 'Context contract override path')
645
+ .option('--no-strict-contract', 'Do not fail when context contract validation has issues')
646
+ .option('--moqui-config <path>', 'Moqui adapter runtime config path')
647
+ .option('--out-dir <path>', 'Flow artifact root directory')
648
+ .option('--bridge-out-context <path>', 'Bridge normalized context output file path')
649
+ .option('--bridge-out-report <path>', 'Bridge report output file path')
650
+ .option('--loop-out <path>', 'Interactive-loop summary output file path')
651
+ .option('--work-order-out <path>', 'Work-order JSON output file path')
652
+ .option('--work-order-markdown-out <path>', 'Work-order markdown output file path')
653
+ .option('--out <path>', 'Flow summary output file path')
654
+ .option('--approval-actor <id>', 'Approval workflow actor')
655
+ .option('--approval-actor-role <name>', 'Approval workflow actor role')
656
+ .option('--approver-actor <id>', 'Auto-approve actor')
657
+ .option('--approver-actor-role <name>', 'Auto-approve actor role')
658
+ .option('--approval-role-policy <path>', 'Approval role policy JSON path')
659
+ .option('--skip-submit', 'Skip approval submit step')
660
+ .option('--auto-approve-low-risk', 'Auto-approve low-risk allow plans')
661
+ .option('--auto-execute-low-risk', 'Auto-run low-risk apply for allow+low plans')
662
+ .option('--allow-suggestion-apply', 'Allow applying plans generated in suggestion mode')
663
+ .option('--live-apply', 'Enable live apply mode')
664
+ .option('--no-dry-run', 'Disable dry-run simulation')
665
+ .option('--feedback-score <number>', 'Optional feedback score (0-5)')
666
+ .option('--feedback-comment <text>', 'Optional feedback comment')
667
+ .option('--feedback-tags <csv>', 'Optional feedback tags (comma-separated)')
668
+ .option('--feedback-channel <channel>', 'Feedback channel (ui|cli|api|other)', 'ui')
669
+ .option('--auth-password <text>', 'One-time password for protected execute action')
670
+ .option('--auth-password-hash <sha256>', 'Password verifier hash override')
671
+ .option('--auth-password-env <name>', 'Password hash environment variable name')
672
+ .option('--fail-on-dialogue-deny', 'Exit code 2 when dialogue decision is deny')
673
+ .option('--fail-on-gate-deny', 'Exit code 2 when gate decision is deny')
674
+ .option('--fail-on-gate-non-allow', 'Exit code 2 when gate decision is deny/review-required')
675
+ .option('--fail-on-runtime-non-allow', 'Exit code 2 when runtime decision is deny/review-required')
676
+ .option('--fail-on-execute-blocked', 'Exit code 2 when auto execute result is blocked/non-success')
677
+ .option('--no-matrix', 'Disable matrix baseline snapshot stage')
678
+ .option('--matrix-template-dir <path>', 'Template library path for matrix stage')
679
+ .option('--matrix-match <regex>', 'Matrix selector regex')
680
+ .option('--matrix-include-all', 'Score all templates in matrix stage')
681
+ .option('--matrix-min-score <number>', 'Matrix min semantic score (0-100)')
682
+ .option('--matrix-min-valid-rate <number>', 'Matrix min ontology valid-rate (0-100)')
683
+ .option('--matrix-compare-with <path>', 'Previous matrix baseline report path')
684
+ .option('--matrix-out <path>', 'Matrix JSON report output path')
685
+ .option('--matrix-markdown-out <path>', 'Matrix markdown report output path')
686
+ .option('--matrix-signals <path>', 'Matrix signal JSONL append path')
687
+ .option('--matrix-fail-on-portfolio-fail', 'Exit non-zero when matrix portfolio baseline fails')
688
+ .option('--matrix-fail-on-regression', 'Exit code 2 when matrix regressions are detected')
689
+ .option('--matrix-fail-on-error', 'Exit non-zero when matrix stage fails unexpectedly')
690
+ .option('--json', 'Print payload as JSON')
691
+ .action(async (options) => {
692
+ await runSceneInteractiveFlowCommand(options);
693
+ });
694
+
560
695
  sceneCmd
561
696
  .command('instantiate')
562
697
  .description('Instantiate scene template package with full pipeline (resolve, validate, render, manifest, log, hook)')
@@ -10981,6 +11116,239 @@ function validateSceneTemplateResolveOptions(options) {
10981
11116
  return null;
10982
11117
  }
10983
11118
 
11119
+ function normalizeSceneContextBridgeOptions(options = {}) {
11120
+ return {
11121
+ input: options.input ? String(options.input).trim() : undefined,
11122
+ provider: options.provider ? String(options.provider).trim().toLowerCase() : 'moqui',
11123
+ outContext: options.outContext ? String(options.outContext).trim() : undefined,
11124
+ outReport: options.outReport ? String(options.outReport).trim() : undefined,
11125
+ contextContract: options.contextContract ? String(options.contextContract).trim() : undefined,
11126
+ strictContract: options.strictContract !== false,
11127
+ json: options.json === true
11128
+ };
11129
+ }
11130
+
11131
+ function validateSceneContextBridgeOptions(options) {
11132
+ if (!options.input || typeof options.input !== 'string' || options.input.trim().length === 0) {
11133
+ return '--input is required';
11134
+ }
11135
+ if (!['moqui', 'generic'].includes(String(options.provider || '').trim().toLowerCase())) {
11136
+ return '--provider must be one of: moqui, generic';
11137
+ }
11138
+ if (options.contextContract !== undefined && (!options.contextContract || options.contextContract.length === 0)) {
11139
+ return '--context-contract cannot be empty';
11140
+ }
11141
+ return null;
11142
+ }
11143
+
11144
+ function normalizeSceneInteractiveFlowOptions(options = {}) {
11145
+ const feedbackScore = options.feedbackScore !== undefined ? Number(options.feedbackScore) : null;
11146
+ const matrixMinScore = options.matrixMinScore !== undefined ? Number(options.matrixMinScore) : null;
11147
+ const matrixMinValidRate = options.matrixMinValidRate !== undefined ? Number(options.matrixMinValidRate) : null;
11148
+ return {
11149
+ input: options.input ? String(options.input).trim() : undefined,
11150
+ provider: options.provider ? String(options.provider).trim().toLowerCase() : 'moqui',
11151
+ goal: options.goal ? String(options.goal).trim() : undefined,
11152
+ goalFile: options.goalFile ? String(options.goalFile).trim() : undefined,
11153
+ userId: options.userId ? String(options.userId).trim() : undefined,
11154
+ sessionId: options.sessionId ? String(options.sessionId).trim() : undefined,
11155
+ executionMode: options.executionMode ? String(options.executionMode).trim() : 'suggestion',
11156
+ policy: options.policy ? String(options.policy).trim() : undefined,
11157
+ catalog: options.catalog ? String(options.catalog).trim() : undefined,
11158
+ dialoguePolicy: options.dialoguePolicy ? String(options.dialoguePolicy).trim() : undefined,
11159
+ dialogueOut: options.dialogueOut ? String(options.dialogueOut).trim() : undefined,
11160
+ runtimeMode: options.runtimeMode ? String(options.runtimeMode).trim().toLowerCase() : 'ops-fix',
11161
+ runtimeEnvironment: options.runtimeEnvironment ? String(options.runtimeEnvironment).trim().toLowerCase() : 'staging',
11162
+ runtimePolicy: options.runtimePolicy ? String(options.runtimePolicy).trim() : undefined,
11163
+ runtimeOut: options.runtimeOut ? String(options.runtimeOut).trim() : undefined,
11164
+ contextContract: options.contextContract ? String(options.contextContract).trim() : undefined,
11165
+ strictContract: options.strictContract !== false,
11166
+ moquiConfig: options.moquiConfig ? String(options.moquiConfig).trim() : undefined,
11167
+ outDir: options.outDir ? String(options.outDir).trim() : undefined,
11168
+ out: options.out ? String(options.out).trim() : undefined,
11169
+ loopOut: options.loopOut ? String(options.loopOut).trim() : undefined,
11170
+ workOrderOut: options.workOrderOut ? String(options.workOrderOut).trim() : undefined,
11171
+ workOrderMarkdownOut: options.workOrderMarkdownOut ? String(options.workOrderMarkdownOut).trim() : undefined,
11172
+ bridgeOutContext: options.bridgeOutContext ? String(options.bridgeOutContext).trim() : undefined,
11173
+ bridgeOutReport: options.bridgeOutReport ? String(options.bridgeOutReport).trim() : undefined,
11174
+ approvalActor: options.approvalActor ? String(options.approvalActor).trim() : undefined,
11175
+ approvalActorRole: options.approvalActorRole ? String(options.approvalActorRole).trim().toLowerCase() : undefined,
11176
+ approverActor: options.approverActor ? String(options.approverActor).trim() : undefined,
11177
+ approverActorRole: options.approverActorRole ? String(options.approverActorRole).trim().toLowerCase() : undefined,
11178
+ approvalRolePolicy: options.approvalRolePolicy ? String(options.approvalRolePolicy).trim() : undefined,
11179
+ skipSubmit: options.skipSubmit === true,
11180
+ autoApproveLowRisk: options.autoApproveLowRisk === true,
11181
+ autoExecuteLowRisk: options.autoExecuteLowRisk === true,
11182
+ allowSuggestionApply: options.allowSuggestionApply === true,
11183
+ liveApply: options.liveApply === true,
11184
+ dryRun: options.dryRun !== false,
11185
+ feedbackScore,
11186
+ feedbackComment: options.feedbackComment ? String(options.feedbackComment).trim() : undefined,
11187
+ feedbackTags: options.feedbackTags ? String(options.feedbackTags).trim() : undefined,
11188
+ feedbackChannel: options.feedbackChannel ? String(options.feedbackChannel).trim().toLowerCase() : 'ui',
11189
+ authPassword: options.authPassword != null ? String(options.authPassword) : undefined,
11190
+ authPasswordHash: options.authPasswordHash ? String(options.authPasswordHash).trim().toLowerCase() : undefined,
11191
+ authPasswordEnv: options.authPasswordEnv ? String(options.authPasswordEnv).trim() : undefined,
11192
+ failOnDialogueDeny: options.failOnDialogueDeny === true,
11193
+ failOnGateDeny: options.failOnGateDeny === true,
11194
+ failOnGateNonAllow: options.failOnGateNonAllow === true,
11195
+ failOnRuntimeNonAllow: options.failOnRuntimeNonAllow === true,
11196
+ failOnExecuteBlocked: options.failOnExecuteBlocked === true,
11197
+ matrix: options.matrix !== false,
11198
+ matrixTemplateDir: options.matrixTemplateDir ? String(options.matrixTemplateDir).trim() : undefined,
11199
+ matrixMatch: options.matrixMatch ? String(options.matrixMatch).trim() : undefined,
11200
+ matrixIncludeAll: options.matrixIncludeAll === true,
11201
+ matrixMinScore,
11202
+ matrixMinValidRate,
11203
+ matrixCompareWith: options.matrixCompareWith ? String(options.matrixCompareWith).trim() : undefined,
11204
+ matrixOut: options.matrixOut ? String(options.matrixOut).trim() : undefined,
11205
+ matrixMarkdownOut: options.matrixMarkdownOut ? String(options.matrixMarkdownOut).trim() : undefined,
11206
+ matrixSignals: options.matrixSignals ? String(options.matrixSignals).trim() : undefined,
11207
+ matrixFailOnPortfolioFail: options.matrixFailOnPortfolioFail === true,
11208
+ matrixFailOnRegression: options.matrixFailOnRegression === true,
11209
+ matrixFailOnError: options.matrixFailOnError === true,
11210
+ json: options.json === true
11211
+ };
11212
+ }
11213
+
11214
+ function validateSceneInteractiveFlowOptions(options) {
11215
+ if (!options.input || typeof options.input !== 'string' || options.input.trim().length === 0) {
11216
+ return '--input is required';
11217
+ }
11218
+ if (!['moqui', 'generic'].includes(String(options.provider || '').trim().toLowerCase())) {
11219
+ return '--provider must be one of: moqui, generic';
11220
+ }
11221
+ if ((!options.goal || options.goal.length === 0) && (!options.goalFile || options.goalFile.length === 0)) {
11222
+ return 'either --goal or --goal-file is required';
11223
+ }
11224
+ if (!['suggestion', 'apply'].includes(String(options.executionMode || '').trim())) {
11225
+ return '--execution-mode must be suggestion or apply';
11226
+ }
11227
+ if (!['user-assist', 'ops-fix', 'feature-dev'].includes(String(options.runtimeMode || '').trim().toLowerCase())) {
11228
+ return '--runtime-mode must be one of: user-assist, ops-fix, feature-dev';
11229
+ }
11230
+ if (!['dev', 'staging', 'prod'].includes(String(options.runtimeEnvironment || '').trim().toLowerCase())) {
11231
+ return '--runtime-environment must be one of: dev, staging, prod';
11232
+ }
11233
+ if (options.contextContract !== undefined && (!options.contextContract || options.contextContract.length === 0)) {
11234
+ return '--context-contract cannot be empty';
11235
+ }
11236
+ if (options.feedbackScore !== null) {
11237
+ if (!Number.isFinite(options.feedbackScore) || options.feedbackScore < 0 || options.feedbackScore > 5) {
11238
+ return '--feedback-score must be a number between 0 and 5';
11239
+ }
11240
+ }
11241
+ const feedbackChannel = String(options.feedbackChannel || '').trim().toLowerCase();
11242
+ if (!['ui', 'cli', 'api', 'other'].includes(feedbackChannel)) {
11243
+ return '--feedback-channel must be one of: ui, cli, api, other';
11244
+ }
11245
+ if (options.authPasswordHash !== undefined && !/^[a-f0-9]{64}$/i.test(options.authPasswordHash)) {
11246
+ return '--auth-password-hash must be a sha256 hex string (64 chars)';
11247
+ }
11248
+ if (options.authPasswordEnv !== undefined && String(options.authPasswordEnv).trim().length === 0) {
11249
+ return '--auth-password-env cannot be empty';
11250
+ }
11251
+ if (options.matrixMinScore != null) {
11252
+ if (!Number.isFinite(options.matrixMinScore) || options.matrixMinScore < 0 || options.matrixMinScore > 100) {
11253
+ return '--matrix-min-score must be a number between 0 and 100';
11254
+ }
11255
+ }
11256
+ if (options.matrixMinValidRate != null) {
11257
+ if (!Number.isFinite(options.matrixMinValidRate) || options.matrixMinValidRate < 0 || options.matrixMinValidRate > 100) {
11258
+ return '--matrix-min-valid-rate must be a number between 0 and 100';
11259
+ }
11260
+ }
11261
+ return null;
11262
+ }
11263
+
11264
+ function normalizeSceneInteractiveLoopOptions(options = {}) {
11265
+ const feedbackScore = options.feedbackScore !== undefined ? Number(options.feedbackScore) : null;
11266
+ return {
11267
+ context: options.context ? String(options.context).trim() : undefined,
11268
+ goal: options.goal ? String(options.goal).trim() : undefined,
11269
+ goalFile: options.goalFile ? String(options.goalFile).trim() : undefined,
11270
+ userId: options.userId ? String(options.userId).trim() : undefined,
11271
+ sessionId: options.sessionId ? String(options.sessionId).trim() : undefined,
11272
+ executionMode: options.executionMode ? String(options.executionMode).trim() : 'suggestion',
11273
+ policy: options.policy ? String(options.policy).trim() : undefined,
11274
+ catalog: options.catalog ? String(options.catalog).trim() : undefined,
11275
+ dialoguePolicy: options.dialoguePolicy ? String(options.dialoguePolicy).trim() : undefined,
11276
+ dialogueOut: options.dialogueOut ? String(options.dialogueOut).trim() : undefined,
11277
+ runtimeMode: options.runtimeMode ? String(options.runtimeMode).trim().toLowerCase() : 'ops-fix',
11278
+ runtimeEnvironment: options.runtimeEnvironment ? String(options.runtimeEnvironment).trim().toLowerCase() : 'staging',
11279
+ runtimePolicy: options.runtimePolicy ? String(options.runtimePolicy).trim() : undefined,
11280
+ runtimeOut: options.runtimeOut ? String(options.runtimeOut).trim() : undefined,
11281
+ contextContract: options.contextContract ? String(options.contextContract).trim() : undefined,
11282
+ strictContract: options.strictContract !== false,
11283
+ moquiConfig: options.moquiConfig ? String(options.moquiConfig).trim() : undefined,
11284
+ outDir: options.outDir ? String(options.outDir).trim() : undefined,
11285
+ out: options.out ? String(options.out).trim() : undefined,
11286
+ workOrderOut: options.workOrderOut ? String(options.workOrderOut).trim() : undefined,
11287
+ workOrderMarkdownOut: options.workOrderMarkdownOut ? String(options.workOrderMarkdownOut).trim() : undefined,
11288
+ approvalActor: options.approvalActor ? String(options.approvalActor).trim() : undefined,
11289
+ approvalActorRole: options.approvalActorRole ? String(options.approvalActorRole).trim().toLowerCase() : undefined,
11290
+ approverActor: options.approverActor ? String(options.approverActor).trim() : undefined,
11291
+ approverActorRole: options.approverActorRole ? String(options.approverActorRole).trim().toLowerCase() : undefined,
11292
+ approvalRolePolicy: options.approvalRolePolicy ? String(options.approvalRolePolicy).trim() : undefined,
11293
+ skipSubmit: options.skipSubmit === true,
11294
+ autoApproveLowRisk: options.autoApproveLowRisk === true,
11295
+ autoExecuteLowRisk: options.autoExecuteLowRisk === true,
11296
+ allowSuggestionApply: options.allowSuggestionApply === true,
11297
+ liveApply: options.liveApply === true,
11298
+ dryRun: options.dryRun !== false,
11299
+ feedbackScore,
11300
+ feedbackComment: options.feedbackComment ? String(options.feedbackComment).trim() : undefined,
11301
+ feedbackTags: options.feedbackTags ? String(options.feedbackTags).trim() : undefined,
11302
+ feedbackChannel: options.feedbackChannel ? String(options.feedbackChannel).trim().toLowerCase() : 'ui',
11303
+ authPassword: options.authPassword != null ? String(options.authPassword) : undefined,
11304
+ authPasswordHash: options.authPasswordHash ? String(options.authPasswordHash).trim().toLowerCase() : undefined,
11305
+ authPasswordEnv: options.authPasswordEnv ? String(options.authPasswordEnv).trim() : undefined,
11306
+ failOnDialogueDeny: options.failOnDialogueDeny === true,
11307
+ failOnGateDeny: options.failOnGateDeny === true,
11308
+ failOnGateNonAllow: options.failOnGateNonAllow === true,
11309
+ failOnRuntimeNonAllow: options.failOnRuntimeNonAllow === true,
11310
+ failOnExecuteBlocked: options.failOnExecuteBlocked === true,
11311
+ json: options.json === true
11312
+ };
11313
+ }
11314
+
11315
+ function validateSceneInteractiveLoopOptions(options) {
11316
+ if (!options.context || typeof options.context !== 'string' || options.context.trim().length === 0) {
11317
+ return '--context is required';
11318
+ }
11319
+ if ((!options.goal || options.goal.length === 0) && (!options.goalFile || options.goalFile.length === 0)) {
11320
+ return 'either --goal or --goal-file is required';
11321
+ }
11322
+ if (!['suggestion', 'apply'].includes(String(options.executionMode || '').trim())) {
11323
+ return '--execution-mode must be suggestion or apply';
11324
+ }
11325
+ if (!['user-assist', 'ops-fix', 'feature-dev'].includes(String(options.runtimeMode || '').trim().toLowerCase())) {
11326
+ return '--runtime-mode must be one of: user-assist, ops-fix, feature-dev';
11327
+ }
11328
+ if (!['dev', 'staging', 'prod'].includes(String(options.runtimeEnvironment || '').trim().toLowerCase())) {
11329
+ return '--runtime-environment must be one of: dev, staging, prod';
11330
+ }
11331
+ if (options.contextContract !== undefined && (!options.contextContract || options.contextContract.length === 0)) {
11332
+ return '--context-contract cannot be empty';
11333
+ }
11334
+ if (options.feedbackScore !== null) {
11335
+ if (!Number.isFinite(options.feedbackScore) || options.feedbackScore < 0 || options.feedbackScore > 5) {
11336
+ return '--feedback-score must be a number between 0 and 5';
11337
+ }
11338
+ }
11339
+ const feedbackChannel = String(options.feedbackChannel || '').trim().toLowerCase();
11340
+ if (!['ui', 'cli', 'api', 'other'].includes(feedbackChannel)) {
11341
+ return '--feedback-channel must be one of: ui, cli, api, other';
11342
+ }
11343
+ if (options.authPasswordHash !== undefined && !/^[a-f0-9]{64}$/i.test(options.authPasswordHash)) {
11344
+ return '--auth-password-hash must be a sha256 hex string (64 chars)';
11345
+ }
11346
+ if (options.authPasswordEnv !== undefined && String(options.authPasswordEnv).trim().length === 0) {
11347
+ return '--auth-password-env cannot be empty';
11348
+ }
11349
+ return null;
11350
+ }
11351
+
10984
11352
  function normalizeSceneMoquiBaselineOptions(options = {}) {
10985
11353
  const minScore = Number(options.minScore);
10986
11354
  const minValidRate = Number(options.minValidRate);
@@ -11139,6 +11507,496 @@ function printSceneTemplateRenderSummary(options, payload, projectRoot = process
11139
11507
 
11140
11508
  // --- Command runners for template commands ---
11141
11509
 
11510
+ async function runSceneContextBridgeCommand(rawOptions = {}, dependencies = {}) {
11511
+ const projectRoot = dependencies.projectRoot || process.cwd();
11512
+ const fileSystem = dependencies.fileSystem || fs;
11513
+
11514
+ const options = normalizeSceneContextBridgeOptions(rawOptions);
11515
+ const validationError = validateSceneContextBridgeOptions(options);
11516
+ if (validationError) {
11517
+ console.error(chalk.red(`Scene context-bridge failed: ${validationError}`));
11518
+ process.exitCode = 1;
11519
+ return null;
11520
+ }
11521
+
11522
+ const scriptPath = path.join(projectRoot, 'scripts', 'interactive-context-bridge.js');
11523
+ const scriptExists = await fileSystem.pathExists(scriptPath);
11524
+ if (!scriptExists) {
11525
+ console.error(chalk.red(`Scene context-bridge failed: script not found at ${scriptPath}`));
11526
+ process.exitCode = 1;
11527
+ return null;
11528
+ }
11529
+
11530
+ const args = [scriptPath, '--input', options.input, '--provider', options.provider];
11531
+ if (options.outContext) {
11532
+ args.push('--out-context', options.outContext);
11533
+ }
11534
+ if (options.outReport) {
11535
+ args.push('--out-report', options.outReport);
11536
+ }
11537
+ if (options.contextContract) {
11538
+ args.push('--context-contract', options.contextContract);
11539
+ }
11540
+ if (!options.strictContract) {
11541
+ args.push('--no-strict-contract');
11542
+ }
11543
+ if (options.json) {
11544
+ args.push('--json');
11545
+ }
11546
+
11547
+ const result = spawnSync(process.execPath, args, {
11548
+ cwd: projectRoot,
11549
+ encoding: 'utf8'
11550
+ });
11551
+
11552
+ if (typeof result.stdout === 'string' && result.stdout.length > 0) {
11553
+ process.stdout.write(result.stdout);
11554
+ }
11555
+ if (typeof result.stderr === 'string' && result.stderr.length > 0) {
11556
+ process.stderr.write(result.stderr);
11557
+ }
11558
+
11559
+ if (result.error) {
11560
+ console.error(chalk.red(`Scene context-bridge failed: ${result.error.message}`));
11561
+ process.exitCode = 1;
11562
+ return null;
11563
+ }
11564
+
11565
+ const exitCode = Number.isInteger(result.status) ? result.status : 1;
11566
+ if (exitCode !== 0) {
11567
+ process.exitCode = exitCode;
11568
+ }
11569
+
11570
+ if (options.json && typeof result.stdout === 'string' && result.stdout.trim().length > 0) {
11571
+ try {
11572
+ return JSON.parse(result.stdout);
11573
+ } catch (_error) {
11574
+ return null;
11575
+ }
11576
+ }
11577
+
11578
+ return null;
11579
+ }
11580
+
11581
+ async function runSceneInteractiveFlowCommand(rawOptions = {}, dependencies = {}) {
11582
+ const projectRoot = dependencies.projectRoot || process.cwd();
11583
+ const fileSystem = dependencies.fileSystem || fs;
11584
+
11585
+ const options = normalizeSceneInteractiveFlowOptions(rawOptions);
11586
+ const validationError = validateSceneInteractiveFlowOptions(options);
11587
+ if (validationError) {
11588
+ console.error(chalk.red(`Scene interactive-flow failed: ${validationError}`));
11589
+ process.exitCode = 1;
11590
+ return null;
11591
+ }
11592
+
11593
+ const scriptPath = path.join(projectRoot, 'scripts', 'interactive-flow.js');
11594
+ const scriptExists = await fileSystem.pathExists(scriptPath);
11595
+ if (!scriptExists) {
11596
+ console.error(chalk.red(`Scene interactive-flow failed: script not found at ${scriptPath}`));
11597
+ process.exitCode = 1;
11598
+ return null;
11599
+ }
11600
+
11601
+ const args = [scriptPath, '--input', options.input, '--provider', options.provider];
11602
+ if (options.goal) {
11603
+ args.push('--goal', options.goal);
11604
+ } else if (options.goalFile) {
11605
+ args.push('--goal-file', options.goalFile);
11606
+ }
11607
+ args.push('--execution-mode', options.executionMode);
11608
+ if (options.userId) {
11609
+ args.push('--user-id', options.userId);
11610
+ }
11611
+ if (options.sessionId) {
11612
+ args.push('--session-id', options.sessionId);
11613
+ }
11614
+ if (options.policy) {
11615
+ args.push('--policy', options.policy);
11616
+ }
11617
+ if (options.catalog) {
11618
+ args.push('--catalog', options.catalog);
11619
+ }
11620
+ if (options.dialoguePolicy) {
11621
+ args.push('--dialogue-policy', options.dialoguePolicy);
11622
+ }
11623
+ if (options.dialogueOut) {
11624
+ args.push('--dialogue-out', options.dialogueOut);
11625
+ }
11626
+ if (options.runtimeMode) {
11627
+ args.push('--runtime-mode', options.runtimeMode);
11628
+ }
11629
+ if (options.runtimeEnvironment) {
11630
+ args.push('--runtime-environment', options.runtimeEnvironment);
11631
+ }
11632
+ if (options.runtimePolicy) {
11633
+ args.push('--runtime-policy', options.runtimePolicy);
11634
+ }
11635
+ if (options.runtimeOut) {
11636
+ args.push('--runtime-out', options.runtimeOut);
11637
+ }
11638
+ if (options.contextContract) {
11639
+ args.push('--context-contract', options.contextContract);
11640
+ }
11641
+ if (!options.strictContract) {
11642
+ args.push('--no-strict-contract');
11643
+ }
11644
+ if (options.moquiConfig) {
11645
+ args.push('--moqui-config', options.moquiConfig);
11646
+ }
11647
+ if (options.outDir) {
11648
+ args.push('--out-dir', options.outDir);
11649
+ }
11650
+ if (options.bridgeOutContext) {
11651
+ args.push('--bridge-out-context', options.bridgeOutContext);
11652
+ }
11653
+ if (options.bridgeOutReport) {
11654
+ args.push('--bridge-out-report', options.bridgeOutReport);
11655
+ }
11656
+ if (options.loopOut) {
11657
+ args.push('--loop-out', options.loopOut);
11658
+ }
11659
+ if (options.workOrderOut) {
11660
+ args.push('--work-order-out', options.workOrderOut);
11661
+ }
11662
+ if (options.workOrderMarkdownOut) {
11663
+ args.push('--work-order-markdown-out', options.workOrderMarkdownOut);
11664
+ }
11665
+ if (options.out) {
11666
+ args.push('--out', options.out);
11667
+ }
11668
+ if (options.approvalActor) {
11669
+ args.push('--approval-actor', options.approvalActor);
11670
+ }
11671
+ if (options.approvalActorRole) {
11672
+ args.push('--approval-actor-role', options.approvalActorRole);
11673
+ }
11674
+ if (options.approverActor) {
11675
+ args.push('--approver-actor', options.approverActor);
11676
+ }
11677
+ if (options.approverActorRole) {
11678
+ args.push('--approver-actor-role', options.approverActorRole);
11679
+ }
11680
+ if (options.approvalRolePolicy) {
11681
+ args.push('--approval-role-policy', options.approvalRolePolicy);
11682
+ }
11683
+ if (options.skipSubmit) {
11684
+ args.push('--skip-submit');
11685
+ }
11686
+ if (options.autoApproveLowRisk) {
11687
+ args.push('--auto-approve-low-risk');
11688
+ }
11689
+ if (options.autoExecuteLowRisk) {
11690
+ args.push('--auto-execute-low-risk');
11691
+ }
11692
+ if (options.allowSuggestionApply) {
11693
+ args.push('--allow-suggestion-apply');
11694
+ }
11695
+ if (options.liveApply) {
11696
+ args.push('--live-apply');
11697
+ }
11698
+ if (!options.dryRun) {
11699
+ args.push('--no-dry-run');
11700
+ }
11701
+ if (options.feedbackScore !== null) {
11702
+ args.push('--feedback-score', String(options.feedbackScore));
11703
+ }
11704
+ if (options.feedbackComment) {
11705
+ args.push('--feedback-comment', options.feedbackComment);
11706
+ }
11707
+ if (options.feedbackTags) {
11708
+ args.push('--feedback-tags', options.feedbackTags);
11709
+ }
11710
+ if (options.feedbackChannel) {
11711
+ args.push('--feedback-channel', options.feedbackChannel);
11712
+ }
11713
+ if (options.authPassword) {
11714
+ args.push('--auth-password', options.authPassword);
11715
+ }
11716
+ if (options.authPasswordHash) {
11717
+ args.push('--auth-password-hash', options.authPasswordHash);
11718
+ }
11719
+ if (options.authPasswordEnv) {
11720
+ args.push('--auth-password-env', options.authPasswordEnv);
11721
+ }
11722
+ if (options.failOnDialogueDeny) {
11723
+ args.push('--fail-on-dialogue-deny');
11724
+ }
11725
+ if (options.failOnGateDeny) {
11726
+ args.push('--fail-on-gate-deny');
11727
+ }
11728
+ if (options.failOnGateNonAllow) {
11729
+ args.push('--fail-on-gate-non-allow');
11730
+ }
11731
+ if (options.failOnRuntimeNonAllow) {
11732
+ args.push('--fail-on-runtime-non-allow');
11733
+ }
11734
+ if (options.failOnExecuteBlocked) {
11735
+ args.push('--fail-on-execute-blocked');
11736
+ }
11737
+ if (!options.matrix) {
11738
+ args.push('--no-matrix');
11739
+ }
11740
+ if (options.matrixTemplateDir) {
11741
+ args.push('--matrix-template-dir', options.matrixTemplateDir);
11742
+ }
11743
+ if (options.matrixMatch) {
11744
+ args.push('--matrix-match', options.matrixMatch);
11745
+ }
11746
+ if (options.matrixIncludeAll) {
11747
+ args.push('--matrix-include-all');
11748
+ }
11749
+ if (options.matrixMinScore !== null) {
11750
+ args.push('--matrix-min-score', String(options.matrixMinScore));
11751
+ }
11752
+ if (options.matrixMinValidRate !== null) {
11753
+ args.push('--matrix-min-valid-rate', String(options.matrixMinValidRate));
11754
+ }
11755
+ if (options.matrixCompareWith) {
11756
+ args.push('--matrix-compare-with', options.matrixCompareWith);
11757
+ }
11758
+ if (options.matrixOut) {
11759
+ args.push('--matrix-out', options.matrixOut);
11760
+ }
11761
+ if (options.matrixMarkdownOut) {
11762
+ args.push('--matrix-markdown-out', options.matrixMarkdownOut);
11763
+ }
11764
+ if (options.matrixSignals) {
11765
+ args.push('--matrix-signals', options.matrixSignals);
11766
+ }
11767
+ if (options.matrixFailOnPortfolioFail) {
11768
+ args.push('--matrix-fail-on-portfolio-fail');
11769
+ }
11770
+ if (options.matrixFailOnRegression) {
11771
+ args.push('--matrix-fail-on-regression');
11772
+ }
11773
+ if (options.matrixFailOnError) {
11774
+ args.push('--matrix-fail-on-error');
11775
+ }
11776
+ if (options.json) {
11777
+ args.push('--json');
11778
+ }
11779
+
11780
+ const result = spawnSync(process.execPath, args, {
11781
+ cwd: projectRoot,
11782
+ encoding: 'utf8'
11783
+ });
11784
+
11785
+ if (typeof result.stdout === 'string' && result.stdout.length > 0) {
11786
+ process.stdout.write(result.stdout);
11787
+ }
11788
+ if (typeof result.stderr === 'string' && result.stderr.length > 0) {
11789
+ process.stderr.write(result.stderr);
11790
+ }
11791
+
11792
+ if (result.error) {
11793
+ console.error(chalk.red(`Scene interactive-flow failed: ${result.error.message}`));
11794
+ process.exitCode = 1;
11795
+ return null;
11796
+ }
11797
+
11798
+ const exitCode = Number.isInteger(result.status) ? result.status : 1;
11799
+ if (exitCode !== 0) {
11800
+ process.exitCode = exitCode;
11801
+ }
11802
+
11803
+ if (options.json && typeof result.stdout === 'string' && result.stdout.trim().length > 0) {
11804
+ try {
11805
+ return JSON.parse(result.stdout);
11806
+ } catch (_error) {
11807
+ return null;
11808
+ }
11809
+ }
11810
+
11811
+ return null;
11812
+ }
11813
+
11814
+ async function runSceneInteractiveLoopCommand(rawOptions = {}, dependencies = {}) {
11815
+ const projectRoot = dependencies.projectRoot || process.cwd();
11816
+ const fileSystem = dependencies.fileSystem || fs;
11817
+
11818
+ const options = normalizeSceneInteractiveLoopOptions(rawOptions);
11819
+ const validationError = validateSceneInteractiveLoopOptions(options);
11820
+ if (validationError) {
11821
+ console.error(chalk.red(`Scene interactive-loop failed: ${validationError}`));
11822
+ process.exitCode = 1;
11823
+ return null;
11824
+ }
11825
+
11826
+ const scriptPath = path.join(projectRoot, 'scripts', 'interactive-customization-loop.js');
11827
+ const scriptExists = await fileSystem.pathExists(scriptPath);
11828
+ if (!scriptExists) {
11829
+ console.error(chalk.red(`Scene interactive-loop failed: script not found at ${scriptPath}`));
11830
+ process.exitCode = 1;
11831
+ return null;
11832
+ }
11833
+
11834
+ const args = [scriptPath];
11835
+ args.push('--context', options.context);
11836
+ if (options.goal) {
11837
+ args.push('--goal', options.goal);
11838
+ } else if (options.goalFile) {
11839
+ args.push('--goal-file', options.goalFile);
11840
+ }
11841
+ args.push('--execution-mode', options.executionMode);
11842
+ if (options.userId) {
11843
+ args.push('--user-id', options.userId);
11844
+ }
11845
+ if (options.sessionId) {
11846
+ args.push('--session-id', options.sessionId);
11847
+ }
11848
+ if (options.policy) {
11849
+ args.push('--policy', options.policy);
11850
+ }
11851
+ if (options.catalog) {
11852
+ args.push('--catalog', options.catalog);
11853
+ }
11854
+ if (options.dialoguePolicy) {
11855
+ args.push('--dialogue-policy', options.dialoguePolicy);
11856
+ }
11857
+ if (options.dialogueOut) {
11858
+ args.push('--dialogue-out', options.dialogueOut);
11859
+ }
11860
+ if (options.runtimeMode) {
11861
+ args.push('--runtime-mode', options.runtimeMode);
11862
+ }
11863
+ if (options.runtimeEnvironment) {
11864
+ args.push('--runtime-environment', options.runtimeEnvironment);
11865
+ }
11866
+ if (options.runtimePolicy) {
11867
+ args.push('--runtime-policy', options.runtimePolicy);
11868
+ }
11869
+ if (options.runtimeOut) {
11870
+ args.push('--runtime-out', options.runtimeOut);
11871
+ }
11872
+ if (options.contextContract) {
11873
+ args.push('--context-contract', options.contextContract);
11874
+ }
11875
+ if (!options.strictContract) {
11876
+ args.push('--no-strict-contract');
11877
+ }
11878
+ if (options.moquiConfig) {
11879
+ args.push('--moqui-config', options.moquiConfig);
11880
+ }
11881
+ if (options.outDir) {
11882
+ args.push('--out-dir', options.outDir);
11883
+ }
11884
+ if (options.out) {
11885
+ args.push('--out', options.out);
11886
+ }
11887
+ if (options.workOrderOut) {
11888
+ args.push('--work-order-out', options.workOrderOut);
11889
+ }
11890
+ if (options.workOrderMarkdownOut) {
11891
+ args.push('--work-order-markdown-out', options.workOrderMarkdownOut);
11892
+ }
11893
+ if (options.approvalActor) {
11894
+ args.push('--approval-actor', options.approvalActor);
11895
+ }
11896
+ if (options.approvalActorRole) {
11897
+ args.push('--approval-actor-role', options.approvalActorRole);
11898
+ }
11899
+ if (options.approverActor) {
11900
+ args.push('--approver-actor', options.approverActor);
11901
+ }
11902
+ if (options.approverActorRole) {
11903
+ args.push('--approver-actor-role', options.approverActorRole);
11904
+ }
11905
+ if (options.approvalRolePolicy) {
11906
+ args.push('--approval-role-policy', options.approvalRolePolicy);
11907
+ }
11908
+ if (options.skipSubmit) {
11909
+ args.push('--skip-submit');
11910
+ }
11911
+ if (options.autoApproveLowRisk) {
11912
+ args.push('--auto-approve-low-risk');
11913
+ }
11914
+ if (options.autoExecuteLowRisk) {
11915
+ args.push('--auto-execute-low-risk');
11916
+ }
11917
+ if (options.allowSuggestionApply) {
11918
+ args.push('--allow-suggestion-apply');
11919
+ }
11920
+ if (options.liveApply) {
11921
+ args.push('--live-apply');
11922
+ }
11923
+ if (!options.dryRun) {
11924
+ args.push('--no-dry-run');
11925
+ }
11926
+ if (options.feedbackScore !== null) {
11927
+ args.push('--feedback-score', String(options.feedbackScore));
11928
+ }
11929
+ if (options.feedbackComment) {
11930
+ args.push('--feedback-comment', options.feedbackComment);
11931
+ }
11932
+ if (options.feedbackTags) {
11933
+ args.push('--feedback-tags', options.feedbackTags);
11934
+ }
11935
+ if (options.feedbackChannel) {
11936
+ args.push('--feedback-channel', options.feedbackChannel);
11937
+ }
11938
+ if (options.authPassword) {
11939
+ args.push('--auth-password', options.authPassword);
11940
+ }
11941
+ if (options.authPasswordHash) {
11942
+ args.push('--auth-password-hash', options.authPasswordHash);
11943
+ }
11944
+ if (options.authPasswordEnv) {
11945
+ args.push('--auth-password-env', options.authPasswordEnv);
11946
+ }
11947
+ if (options.failOnDialogueDeny) {
11948
+ args.push('--fail-on-dialogue-deny');
11949
+ }
11950
+ if (options.failOnGateDeny) {
11951
+ args.push('--fail-on-gate-deny');
11952
+ }
11953
+ if (options.failOnGateNonAllow) {
11954
+ args.push('--fail-on-gate-non-allow');
11955
+ }
11956
+ if (options.failOnRuntimeNonAllow) {
11957
+ args.push('--fail-on-runtime-non-allow');
11958
+ }
11959
+ if (options.failOnExecuteBlocked) {
11960
+ args.push('--fail-on-execute-blocked');
11961
+ }
11962
+ if (options.json) {
11963
+ args.push('--json');
11964
+ }
11965
+
11966
+ const result = spawnSync(process.execPath, args, {
11967
+ cwd: projectRoot,
11968
+ encoding: 'utf8'
11969
+ });
11970
+
11971
+ if (typeof result.stdout === 'string' && result.stdout.length > 0) {
11972
+ process.stdout.write(result.stdout);
11973
+ }
11974
+ if (typeof result.stderr === 'string' && result.stderr.length > 0) {
11975
+ process.stderr.write(result.stderr);
11976
+ }
11977
+
11978
+ if (result.error) {
11979
+ console.error(chalk.red(`Scene interactive-loop failed: ${result.error.message}`));
11980
+ process.exitCode = 1;
11981
+ return null;
11982
+ }
11983
+
11984
+ const exitCode = Number.isInteger(result.status) ? result.status : 1;
11985
+ if (exitCode !== 0) {
11986
+ process.exitCode = exitCode;
11987
+ }
11988
+
11989
+ if (options.json && typeof result.stdout === 'string' && result.stdout.trim().length > 0) {
11990
+ try {
11991
+ return JSON.parse(result.stdout);
11992
+ } catch (_error) {
11993
+ return null;
11994
+ }
11995
+ }
11996
+
11997
+ return null;
11998
+ }
11999
+
11142
12000
  async function runSceneMoquiBaselineCommand(rawOptions = {}, dependencies = {}) {
11143
12001
  const projectRoot = dependencies.projectRoot || process.cwd();
11144
12002
  const fileSystem = dependencies.fileSystem || fs;
@@ -15403,8 +16261,17 @@ module.exports = {
15403
16261
  validateSceneTemplateValidateOptions,
15404
16262
  normalizeSceneTemplateResolveOptions,
15405
16263
  validateSceneTemplateResolveOptions,
16264
+ normalizeSceneContextBridgeOptions,
16265
+ validateSceneContextBridgeOptions,
16266
+ normalizeSceneInteractiveFlowOptions,
16267
+ validateSceneInteractiveFlowOptions,
16268
+ normalizeSceneInteractiveLoopOptions,
16269
+ validateSceneInteractiveLoopOptions,
15406
16270
  normalizeSceneMoquiBaselineOptions,
15407
16271
  validateSceneMoquiBaselineOptions,
16272
+ runSceneContextBridgeCommand,
16273
+ runSceneInteractiveFlowCommand,
16274
+ runSceneInteractiveLoopCommand,
15408
16275
  runSceneMoquiBaselineCommand,
15409
16276
  runSceneTemplateValidateCommand,
15410
16277
  runSceneTemplateResolveCommand,