scene-capability-engine 3.3.25 → 3.4.5

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.
@@ -9,6 +9,8 @@ const {
9
9
  ensureSpecDomainArtifacts
10
10
  } = require('../spec/domain-modeling');
11
11
  const { findRelatedSpecs } = require('../spec/related-specs');
12
+ const { captureTimelineCheckpoint } = require('../runtime/project-timeline');
13
+ const { runProblemEvaluation } = require('../problem/problem-evaluator');
12
14
 
13
15
  const STUDIO_JOB_API_VERSION = 'sce.studio.job/v0.1';
14
16
  const STAGE_ORDER = ['plan', 'generate', 'apply', 'verify', 'release'];
@@ -966,6 +968,119 @@ function buildJobDomainChainMetadata(job = {}) {
966
968
  };
967
969
  }
968
970
 
971
+ function summarizeProblemEvaluation(evaluation = {}) {
972
+ return {
973
+ passed: evaluation.passed === true,
974
+ blocked: evaluation.blocked === true,
975
+ confidence_score: Number(evaluation.confidence_score || 0),
976
+ risk_level: normalizeString(evaluation?.dimensions?.risk?.level) || 'low',
977
+ strategy: normalizeString(evaluation?.dimensions?.strategy?.strategy) || 'direct-execution',
978
+ blockers: Array.isArray(evaluation.blockers) ? evaluation.blockers : [],
979
+ warnings: Array.isArray(evaluation.warnings) ? evaluation.warnings : [],
980
+ recommendations: Array.isArray(evaluation.recommendations) ? evaluation.recommendations : [],
981
+ report_file: normalizeString(evaluation.report_file) || null
982
+ };
983
+ }
984
+
985
+ function deriveGateSignals(steps = []) {
986
+ const normalized = Array.isArray(steps) ? steps : [];
987
+ const requiredTotal = normalized.filter((step) => step && step.required !== false).length;
988
+ const requiredEnabled = normalized.filter((step) => step && step.required !== false && step.enabled !== false).length;
989
+ return {
990
+ required_total: requiredTotal,
991
+ required_enabled: requiredEnabled,
992
+ required_missing: Math.max(0, requiredTotal - requiredEnabled)
993
+ };
994
+ }
995
+
996
+ function buildStageReadiness(job = {}, stage = '', overrides = {}) {
997
+ const normalizedStage = normalizeString(stage).toLowerCase();
998
+ const patchBundleReady = normalizeString(job?.artifacts?.patch_bundle_id).length > 0;
999
+ const verifyReportReady = normalizeString(job?.artifacts?.verify_report).length > 0;
1000
+ const readiness = {
1001
+ prerequisites_ready: true,
1002
+ rollback_ready: isStageCompleted(job, 'apply'),
1003
+ patch_bundle_ready: patchBundleReady,
1004
+ verify_report_ready: verifyReportReady
1005
+ };
1006
+
1007
+ if (normalizedStage === 'generate') {
1008
+ readiness.prerequisites_ready = isStageCompleted(job, 'plan');
1009
+ } else if (normalizedStage === 'apply') {
1010
+ readiness.prerequisites_ready = isStageCompleted(job, 'generate');
1011
+ } else if (normalizedStage === 'verify') {
1012
+ readiness.prerequisites_ready = isStageCompleted(job, 'apply');
1013
+ } else if (normalizedStage === 'release') {
1014
+ readiness.prerequisites_ready = isStageCompleted(job, 'verify');
1015
+ }
1016
+
1017
+ return {
1018
+ ...readiness,
1019
+ ...overrides
1020
+ };
1021
+ }
1022
+
1023
+ function assignProblemEvalArtifact(job = {}, stage = '', evaluation = {}) {
1024
+ const normalizedStage = normalizeString(stage).toLowerCase();
1025
+ if (!normalizedStage) {
1026
+ return;
1027
+ }
1028
+ job.artifacts = job.artifacts || {};
1029
+ const reports = job.artifacts.problem_eval_reports && typeof job.artifacts.problem_eval_reports === 'object'
1030
+ ? job.artifacts.problem_eval_reports
1031
+ : {};
1032
+ reports[normalizedStage] = normalizeString(evaluation.report_file) || null;
1033
+ job.artifacts.problem_eval_reports = reports;
1034
+ }
1035
+
1036
+ async function enforceProblemEvaluationForStage(job = {}, stage = '', context = {}, dependencies = {}) {
1037
+ const projectPath = dependencies.projectPath || process.cwd();
1038
+ const fileSystem = dependencies.fileSystem || fs;
1039
+ const evaluation = await runProblemEvaluation({
1040
+ stage,
1041
+ job_id: normalizeString(job.job_id),
1042
+ scene_id: normalizeString(context.scene_id || job?.scene?.id),
1043
+ spec_id: normalizeString(context.spec_id || job?.source?.spec_id || job?.scene?.spec_id),
1044
+ goal: normalizeString(context.goal || job?.source?.goal),
1045
+ release_channel: normalizeString(context.release_channel || ''),
1046
+ domain_chain: context.domain_chain || (job?.source?.domain_chain || {}),
1047
+ related_specs_count: Number(context.related_specs_count || job?.source?.related_specs?.total_candidates || 0),
1048
+ stage_readiness: context.stage_readiness || buildStageReadiness(job, stage),
1049
+ gate_signals: context.gate_signals || {}
1050
+ }, {
1051
+ projectPath,
1052
+ fileSystem,
1053
+ env: dependencies.env,
1054
+ writeReport: true
1055
+ });
1056
+ assignProblemEvalArtifact(job, stage, evaluation);
1057
+ return evaluation;
1058
+ }
1059
+
1060
+ async function markStudioStageBlockedByProblemEval(paths, job, stageName, evaluation, fileSystem = fs) {
1061
+ const summary = summarizeProblemEvaluation(evaluation);
1062
+ job.status = `${stageName}_blocked`;
1063
+ job.updated_at = nowIso();
1064
+ job.stages = job.stages || createStageState();
1065
+ job.stages[stageName] = {
1066
+ status: 'blocked',
1067
+ completed_at: null,
1068
+ metadata: {
1069
+ problem_evaluation: summary
1070
+ }
1071
+ };
1072
+ await saveJob(paths, job, fileSystem);
1073
+ await appendStudioEvent(paths, job, `stage.${stageName}.blocked`, {
1074
+ problem_evaluation: summary
1075
+ }, fileSystem);
1076
+ await writeLatestJob(paths, job.job_id, fileSystem);
1077
+
1078
+ const reason = summary.blockers.length > 0
1079
+ ? summary.blockers.join(', ')
1080
+ : 'problem-evaluation-policy';
1081
+ throw new Error(`studio ${stageName} blocked by problem evaluation: ${reason}`);
1082
+ }
1083
+
969
1084
  async function runStudioPlanCommand(options = {}, dependencies = {}) {
970
1085
  const projectPath = dependencies.projectPath || process.cwd();
971
1086
  const fileSystem = dependencies.fileSystem || fs;
@@ -1012,6 +1127,51 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
1012
1127
 
1013
1128
  const jobId = normalizeString(options.job) || createJobId();
1014
1129
  const now = nowIso();
1130
+ const planShadowJob = {
1131
+ job_id: jobId,
1132
+ scene: {
1133
+ id: sceneId,
1134
+ spec_id: domainChainBinding.spec_id || specId || null
1135
+ },
1136
+ source: {
1137
+ goal: normalizeString(options.goal) || null,
1138
+ spec_id: domainChainBinding.spec_id || specId || null,
1139
+ domain_chain: {
1140
+ resolved: domainChainBinding.resolved === true,
1141
+ summary: domainChainBinding.summary || null
1142
+ },
1143
+ related_specs: {
1144
+ total_candidates: Number(relatedSpecLookup.total_candidates || 0)
1145
+ }
1146
+ },
1147
+ artifacts: {}
1148
+ };
1149
+ const planProblemEvaluation = await enforceProblemEvaluationForStage(planShadowJob, 'plan', {
1150
+ scene_id: sceneId,
1151
+ spec_id: domainChainBinding.spec_id || specId || null,
1152
+ goal: normalizeString(options.goal) || null,
1153
+ domain_chain: {
1154
+ resolved: domainChainBinding.resolved === true,
1155
+ summary: domainChainBinding.summary || null
1156
+ },
1157
+ related_specs_count: Number(relatedSpecLookup.total_candidates || 0),
1158
+ stage_readiness: {
1159
+ prerequisites_ready: true,
1160
+ rollback_ready: false,
1161
+ patch_bundle_ready: false,
1162
+ verify_report_ready: false
1163
+ }
1164
+ }, {
1165
+ projectPath,
1166
+ fileSystem,
1167
+ env: dependencies.env
1168
+ });
1169
+ if (!planProblemEvaluation.passed) {
1170
+ const blockers = Array.isArray(planProblemEvaluation.blockers) && planProblemEvaluation.blockers.length > 0
1171
+ ? planProblemEvaluation.blockers.join(', ')
1172
+ : 'problem-evaluation-policy';
1173
+ throw new Error(`studio plan blocked by problem evaluation: ${blockers}`);
1174
+ }
1015
1175
  const stages = createStageState();
1016
1176
  const sessionStore = dependencies.sessionStore || new SessionStore(projectPath);
1017
1177
  const sceneSessionBinding = await sessionStore.beginSceneSession({
@@ -1034,6 +1194,7 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
1034
1194
  domain_chain_path: domainChainBinding.chain_path || null,
1035
1195
  domain_chain_summary: domainChainBinding.summary || null,
1036
1196
  domain_chain_reason: domainChainBinding.reason || null,
1197
+ problem_evaluation: summarizeProblemEvaluation(planProblemEvaluation),
1037
1198
  related_specs_total: Number(relatedSpecLookup.total_candidates || 0),
1038
1199
  related_specs_top: relatedSpecItems
1039
1200
  }
@@ -1087,7 +1248,10 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
1087
1248
  artifacts: {
1088
1249
  patch_bundle_id: null,
1089
1250
  verify_report: null,
1090
- release_ref: null
1251
+ release_ref: null,
1252
+ problem_eval_reports: {
1253
+ plan: normalizeString(planProblemEvaluation.report_file) || null
1254
+ }
1091
1255
  }
1092
1256
  };
1093
1257
 
@@ -1103,6 +1267,7 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
1103
1267
  domain_chain_source: domainChainBinding.source || 'none',
1104
1268
  domain_chain_spec_id: domainChainBinding.spec_id || null,
1105
1269
  domain_chain_path: domainChainBinding.chain_path || null,
1270
+ problem_evaluation: summarizeProblemEvaluation(planProblemEvaluation),
1106
1271
  related_specs_total: Number(relatedSpecLookup.total_candidates || 0),
1107
1272
  related_spec_ids: relatedSpecItems.map((item) => item.spec_id)
1108
1273
  }, fileSystem);
@@ -1137,6 +1302,21 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
1137
1302
  throw new Error(`Scene mismatch: planned scene is "${jobSceneId}" but --scene provided "${sceneArg}"`);
1138
1303
  }
1139
1304
  const sceneId = sceneArg || jobSceneId;
1305
+ const generateProblemEvaluation = await enforceProblemEvaluationForStage(job, 'generate', {
1306
+ scene_id: sceneId,
1307
+ spec_id: normalizeString(job?.source?.spec_id) || normalizeString(job?.scene?.spec_id) || null,
1308
+ goal: normalizeString(job?.source?.goal),
1309
+ domain_chain: job?.source?.domain_chain || {},
1310
+ related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
1311
+ stage_readiness: buildStageReadiness(job, 'generate')
1312
+ }, {
1313
+ projectPath,
1314
+ fileSystem,
1315
+ env: dependencies.env
1316
+ });
1317
+ if (!generateProblemEvaluation.passed) {
1318
+ await markStudioStageBlockedByProblemEval(paths, job, 'generate', generateProblemEvaluation, fileSystem);
1319
+ }
1140
1320
  const patchBundleId = normalizeString(options.patchBundle) || `patch-${sceneId}-${Date.now()}`;
1141
1321
  const domainChainMetadata = buildJobDomainChainMetadata(job);
1142
1322
  const generateReportPath = `${STUDIO_REPORTS_DIR}/generate-${job.job_id}.json`;
@@ -1166,6 +1346,7 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
1166
1346
  scene_id: sceneId,
1167
1347
  target: job.target,
1168
1348
  patch_bundle_id: patchBundleId,
1349
+ problem_evaluation: summarizeProblemEvaluation(generateProblemEvaluation),
1169
1350
  domain_chain: domainChainMetadata,
1170
1351
  report: generateReportPath
1171
1352
  });
@@ -1175,6 +1356,7 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
1175
1356
  scene_id: sceneId,
1176
1357
  target: job.target,
1177
1358
  patch_bundle_id: patchBundleId,
1359
+ problem_evaluation: summarizeProblemEvaluation(generateProblemEvaluation),
1178
1360
  domain_chain: domainChainMetadata,
1179
1361
  report: generateReportPath
1180
1362
  }, fileSystem);
@@ -1210,6 +1392,23 @@ async function runStudioApplyCommand(options = {}, dependencies = {}) {
1210
1392
  if (!patchBundleId) {
1211
1393
  throw new Error('--patch-bundle is required (or generate stage must provide one)');
1212
1394
  }
1395
+ const applyProblemEvaluation = await enforceProblemEvaluationForStage(job, 'apply', {
1396
+ scene_id: normalizeString(job?.scene?.id),
1397
+ spec_id: normalizeString(job?.source?.spec_id) || normalizeString(job?.scene?.spec_id) || null,
1398
+ goal: normalizeString(job?.source?.goal),
1399
+ domain_chain: job?.source?.domain_chain || {},
1400
+ related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
1401
+ stage_readiness: buildStageReadiness(job, 'apply', {
1402
+ patch_bundle_ready: normalizeString(patchBundleId).length > 0
1403
+ })
1404
+ }, {
1405
+ projectPath,
1406
+ fileSystem,
1407
+ env: dependencies.env
1408
+ });
1409
+ if (!applyProblemEvaluation.passed) {
1410
+ await markStudioStageBlockedByProblemEval(paths, job, 'apply', applyProblemEvaluation, fileSystem);
1411
+ }
1213
1412
 
1214
1413
  job.status = 'applied';
1215
1414
  job.artifacts = job.artifacts || {};
@@ -1218,13 +1417,15 @@ async function runStudioApplyCommand(options = {}, dependencies = {}) {
1218
1417
 
1219
1418
  ensureStageCompleted(job, 'apply', {
1220
1419
  patch_bundle_id: patchBundleId,
1221
- auth_required: authResult.required
1420
+ auth_required: authResult.required,
1421
+ problem_evaluation: summarizeProblemEvaluation(applyProblemEvaluation)
1222
1422
  });
1223
1423
 
1224
1424
  await saveJob(paths, job, fileSystem);
1225
1425
  await appendStudioEvent(paths, job, 'stage.apply.completed', {
1226
1426
  patch_bundle_id: patchBundleId,
1227
- auth_required: authResult.required
1427
+ auth_required: authResult.required,
1428
+ problem_evaluation: summarizeProblemEvaluation(applyProblemEvaluation)
1228
1429
  }, fileSystem);
1229
1430
  await writeLatestJob(paths, jobId, fileSystem);
1230
1431
 
@@ -1258,6 +1459,24 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1258
1459
  projectPath,
1259
1460
  fileSystem
1260
1461
  });
1462
+ const verifyProblemEvaluation = await enforceProblemEvaluationForStage(job, 'verify', {
1463
+ scene_id: normalizeString(job?.scene?.id),
1464
+ spec_id: normalizeString(domainChainMetadata.spec_id) || normalizeString(job?.source?.spec_id),
1465
+ goal: normalizeString(job?.source?.goal),
1466
+ domain_chain: job?.source?.domain_chain || {},
1467
+ related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
1468
+ stage_readiness: buildStageReadiness(job, 'verify', {
1469
+ gate_required_ready: deriveGateSignals(gateSteps).required_missing === 0
1470
+ }),
1471
+ gate_signals: deriveGateSignals(gateSteps)
1472
+ }, {
1473
+ projectPath,
1474
+ fileSystem,
1475
+ env: dependencies.env
1476
+ });
1477
+ if (!verifyProblemEvaluation.passed) {
1478
+ await markStudioStageBlockedByProblemEval(paths, job, 'verify', verifyProblemEvaluation, fileSystem);
1479
+ }
1261
1480
  const gateResult = await executeGateSteps(gateSteps, {
1262
1481
  projectPath,
1263
1482
  commandRunner: dependencies.commandRunner,
@@ -1295,6 +1514,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1295
1514
  passed: gateResult.passed,
1296
1515
  steps: gateResult.steps,
1297
1516
  domain_chain: domainChainMetadata,
1517
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1298
1518
  auto_errorbook_records: autoErrorbookRecords
1299
1519
  };
1300
1520
 
@@ -1313,6 +1533,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1313
1533
  profile,
1314
1534
  passed: false,
1315
1535
  report: verifyReportPath,
1536
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1316
1537
  domain_chain: domainChainMetadata,
1317
1538
  auto_errorbook_records: autoErrorbookRecords
1318
1539
  }
@@ -1321,6 +1542,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1321
1542
  await appendStudioEvent(paths, job, 'stage.verify.failed', {
1322
1543
  profile,
1323
1544
  report: verifyReportPath,
1545
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1324
1546
  domain_chain: domainChainMetadata,
1325
1547
  auto_errorbook_records: autoErrorbookRecords
1326
1548
  }, fileSystem);
@@ -1333,6 +1555,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1333
1555
  profile,
1334
1556
  passed: true,
1335
1557
  report: verifyReportPath,
1558
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1336
1559
  domain_chain: domainChainMetadata,
1337
1560
  auto_errorbook_records: autoErrorbookRecords
1338
1561
  });
@@ -1342,6 +1565,7 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
1342
1565
  profile,
1343
1566
  passed: true,
1344
1567
  report: verifyReportPath,
1568
+ problem_evaluation: summarizeProblemEvaluation(verifyProblemEvaluation),
1345
1569
  domain_chain: domainChainMetadata,
1346
1570
  auto_errorbook_records: autoErrorbookRecords
1347
1571
  }, fileSystem);
@@ -1389,6 +1613,26 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1389
1613
  projectPath,
1390
1614
  fileSystem
1391
1615
  });
1616
+ const releaseGateSignals = deriveGateSignals(gateSteps);
1617
+ const releaseProblemEvaluation = await enforceProblemEvaluationForStage(job, 'release', {
1618
+ scene_id: normalizeString(job?.scene?.id),
1619
+ spec_id: normalizeString(domainChainMetadata.spec_id) || normalizeString(job?.source?.spec_id),
1620
+ goal: normalizeString(job?.source?.goal),
1621
+ release_channel: channel,
1622
+ domain_chain: job?.source?.domain_chain || {},
1623
+ related_specs_count: Number(job?.source?.related_specs?.total_candidates || 0),
1624
+ stage_readiness: buildStageReadiness(job, 'release', {
1625
+ gate_required_ready: releaseGateSignals.required_missing === 0
1626
+ }),
1627
+ gate_signals: releaseGateSignals
1628
+ }, {
1629
+ projectPath,
1630
+ fileSystem,
1631
+ env: dependencies.env
1632
+ });
1633
+ if (!releaseProblemEvaluation.passed) {
1634
+ await markStudioStageBlockedByProblemEval(paths, job, 'release', releaseProblemEvaluation, fileSystem);
1635
+ }
1392
1636
  const gateResult = await executeGateSteps(gateSteps, {
1393
1637
  projectPath,
1394
1638
  commandRunner: dependencies.commandRunner,
@@ -1428,6 +1672,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1428
1672
  passed: gateResult.passed,
1429
1673
  steps: gateResult.steps,
1430
1674
  domain_chain: domainChainMetadata,
1675
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1431
1676
  auto_errorbook_records: autoErrorbookRecords
1432
1677
  };
1433
1678
 
@@ -1449,6 +1694,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1449
1694
  passed: false,
1450
1695
  report: releaseReportPath,
1451
1696
  auth_required: authResult.required,
1697
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1452
1698
  domain_chain: domainChainMetadata,
1453
1699
  auto_errorbook_records: autoErrorbookRecords
1454
1700
  }
@@ -1459,6 +1705,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1459
1705
  release_ref: releaseRef,
1460
1706
  report: releaseReportPath,
1461
1707
  auth_required: authResult.required,
1708
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1462
1709
  domain_chain: domainChainMetadata,
1463
1710
  auto_errorbook_records: autoErrorbookRecords
1464
1711
  }, fileSystem);
@@ -1472,6 +1719,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1472
1719
  release_ref: releaseRef,
1473
1720
  report: releaseReportPath,
1474
1721
  auth_required: authResult.required,
1722
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1475
1723
  domain_chain: domainChainMetadata,
1476
1724
  auto_errorbook_records: autoErrorbookRecords
1477
1725
  });
@@ -1503,6 +1751,7 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
1503
1751
  release_ref: releaseRef,
1504
1752
  report: releaseReportPath,
1505
1753
  auth_required: authResult.required,
1754
+ problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
1506
1755
  domain_chain: domainChainMetadata,
1507
1756
  auto_errorbook_records: autoErrorbookRecords
1508
1757
  }, fileSystem);
@@ -1636,8 +1885,30 @@ async function runStudioEventsCommand(options = {}, dependencies = {}) {
1636
1885
  return payload;
1637
1886
  }
1638
1887
 
1639
- async function runStudioCommand(handler, options) {
1888
+ async function runStudioCommand(handler, options, stageName = '') {
1640
1889
  try {
1890
+ const stage = normalizeString(stageName) || 'unknown';
1891
+ const sceneId = normalizeString(options && options.scene);
1892
+ const summaryGoal = normalizeString(options && options.goal);
1893
+ const fromChat = normalizeString(options && options.fromChat);
1894
+ const summaryParts = [
1895
+ 'studio',
1896
+ stage,
1897
+ sceneId ? `scene=${sceneId}` : '',
1898
+ summaryGoal ? `goal=${summaryGoal}` : '',
1899
+ fromChat ? `chat=${fromChat}` : ''
1900
+ ].filter(Boolean);
1901
+
1902
+ await captureTimelineCheckpoint({
1903
+ trigger: 'key-event',
1904
+ event: `studio.${stage}`,
1905
+ summary: summaryParts.join(' | '),
1906
+ command: `sce studio ${stage}`.trim(),
1907
+ sceneId
1908
+ }, {
1909
+ projectPath: process.cwd()
1910
+ });
1911
+
1641
1912
  await handler(options);
1642
1913
  } catch (error) {
1643
1914
  console.error(chalk.red(`Studio command failed: ${error.message}`));
@@ -1660,7 +1931,7 @@ function registerStudioCommands(program) {
1660
1931
  .option('--target <target>', 'Target integration profile', 'default')
1661
1932
  .option('--job <job-id>', 'Reuse an explicit studio job id')
1662
1933
  .option('--json', 'Print machine-readable JSON output')
1663
- .action(async (options) => runStudioCommand(runStudioPlanCommand, options));
1934
+ .action(async (options) => runStudioCommand(runStudioPlanCommand, options, 'plan'));
1664
1935
 
1665
1936
  studio
1666
1937
  .command('generate')
@@ -1670,7 +1941,7 @@ function registerStudioCommands(program) {
1670
1941
  .option('--patch-bundle <id>', 'Explicit patch bundle id')
1671
1942
  .option('--job <job-id>', 'Studio job id (defaults to latest)')
1672
1943
  .option('--json', 'Print machine-readable JSON output')
1673
- .action(async (options) => runStudioCommand(runStudioGenerateCommand, options));
1944
+ .action(async (options) => runStudioCommand(runStudioGenerateCommand, options, 'generate'));
1674
1945
 
1675
1946
  studio
1676
1947
  .command('apply')
@@ -1680,7 +1951,7 @@ function registerStudioCommands(program) {
1680
1951
  .option('--require-auth', 'Require authorization even when policy is advisory')
1681
1952
  .option('--job <job-id>', 'Studio job id (defaults to latest)')
1682
1953
  .option('--json', 'Print machine-readable JSON output')
1683
- .action(async (options) => runStudioCommand(runStudioApplyCommand, options));
1954
+ .action(async (options) => runStudioCommand(runStudioApplyCommand, options, 'apply'));
1684
1955
 
1685
1956
  studio
1686
1957
  .command('verify')
@@ -1688,7 +1959,7 @@ function registerStudioCommands(program) {
1688
1959
  .option('--profile <profile>', 'Verification profile', 'standard')
1689
1960
  .option('--job <job-id>', 'Studio job id (defaults to latest)')
1690
1961
  .option('--json', 'Print machine-readable JSON output')
1691
- .action(async (options) => runStudioCommand(runStudioVerifyCommand, options));
1962
+ .action(async (options) => runStudioCommand(runStudioVerifyCommand, options, 'verify'));
1692
1963
 
1693
1964
  studio
1694
1965
  .command('release')
@@ -1700,14 +1971,14 @@ function registerStudioCommands(program) {
1700
1971
  .option('--release-ref <ref>', 'Explicit release reference/tag')
1701
1972
  .option('--job <job-id>', 'Studio job id (defaults to latest)')
1702
1973
  .option('--json', 'Print machine-readable JSON output')
1703
- .action(async (options) => runStudioCommand(runStudioReleaseCommand, options));
1974
+ .action(async (options) => runStudioCommand(runStudioReleaseCommand, options, 'release'));
1704
1975
 
1705
1976
  studio
1706
1977
  .command('resume')
1707
1978
  .description('Inspect current studio job and next action')
1708
1979
  .option('--job <job-id>', 'Studio job id (defaults to latest)')
1709
1980
  .option('--json', 'Print machine-readable JSON output')
1710
- .action(async (options) => runStudioCommand(runStudioResumeCommand, options));
1981
+ .action(async (options) => runStudioCommand(runStudioResumeCommand, options, 'resume'));
1711
1982
 
1712
1983
  studio
1713
1984
  .command('events')
@@ -1715,7 +1986,7 @@ function registerStudioCommands(program) {
1715
1986
  .option('--job <job-id>', 'Studio job id (defaults to latest)')
1716
1987
  .option('--limit <number>', 'Maximum number of recent events to return', '50')
1717
1988
  .option('--json', 'Print machine-readable JSON output')
1718
- .action(async (options) => runStudioCommand(runStudioEventsCommand, options));
1989
+ .action(async (options) => runStudioCommand(runStudioEventsCommand, options, 'events'));
1719
1990
 
1720
1991
  studio
1721
1992
  .command('rollback')
@@ -1725,7 +1996,7 @@ function registerStudioCommands(program) {
1725
1996
  .option('--auth-password <password>', 'Authorization password for protected rollback action')
1726
1997
  .option('--require-auth', 'Require authorization even when policy is advisory')
1727
1998
  .option('--json', 'Print machine-readable JSON output')
1728
- .action(async (options) => runStudioCommand(runStudioRollbackCommand, options));
1999
+ .action(async (options) => runStudioCommand(runStudioRollbackCommand, options, 'rollback'));
1729
2000
  }
1730
2001
 
1731
2002
  module.exports = {