scene-capability-engine 3.6.0 → 3.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +9 -3
- package/README.zh.md +9 -3
- package/bin/scene-capability-engine.js +2 -0
- package/docs/command-reference.md +40 -1
- package/docs/release-checklist.md +3 -3
- package/docs/zh/release-checklist.md +3 -3
- package/lib/commands/auth.js +269 -0
- package/lib/commands/studio.js +190 -8
- package/lib/commands/task.js +25 -2
- package/lib/security/write-authorization.js +632 -0
- package/lib/state/sce-state-store.js +400 -1
- package/package.json +3 -2
package/lib/commands/studio.js
CHANGED
|
@@ -13,6 +13,7 @@ const { captureTimelineCheckpoint } = require('../runtime/project-timeline');
|
|
|
13
13
|
const { runProblemEvaluation } = require('../problem/problem-evaluator');
|
|
14
14
|
const { TaskRefRegistry } = require('../task/task-ref-registry');
|
|
15
15
|
const { getSceStateStore } = require('../state/sce-state-store');
|
|
16
|
+
const { ensureWriteAuthorization } = require('../security/write-authorization');
|
|
16
17
|
const {
|
|
17
18
|
loadStudioIntakePolicy,
|
|
18
19
|
runStudioAutoIntake,
|
|
@@ -1336,6 +1337,129 @@ function buildTaskSummaryLines(job = {}, stageName = '', taskStatus = '', nextAc
|
|
|
1336
1337
|
];
|
|
1337
1338
|
}
|
|
1338
1339
|
|
|
1340
|
+
function truncateTaskText(value = '', maxLength = 96) {
|
|
1341
|
+
const normalized = normalizeString(value).replace(/\s+/g, ' ');
|
|
1342
|
+
if (!normalized) {
|
|
1343
|
+
return '';
|
|
1344
|
+
}
|
|
1345
|
+
if (normalized.length <= maxLength) {
|
|
1346
|
+
return normalized;
|
|
1347
|
+
}
|
|
1348
|
+
return `${normalized.slice(0, Math.max(0, maxLength - 3)).trim()}...`;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
function dedupeTaskList(items = [], limit = 3) {
|
|
1352
|
+
const seen = new Set();
|
|
1353
|
+
const result = [];
|
|
1354
|
+
for (const item of items) {
|
|
1355
|
+
const normalized = truncateTaskText(item, 120);
|
|
1356
|
+
if (!normalized) {
|
|
1357
|
+
continue;
|
|
1358
|
+
}
|
|
1359
|
+
const key = normalized.toLowerCase();
|
|
1360
|
+
if (seen.has(key)) {
|
|
1361
|
+
continue;
|
|
1362
|
+
}
|
|
1363
|
+
seen.add(key);
|
|
1364
|
+
result.push(normalized);
|
|
1365
|
+
if (result.length >= limit) {
|
|
1366
|
+
break;
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
return result;
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
function splitTaskRawRequest(rawRequest = '') {
|
|
1373
|
+
const normalized = normalizeString(rawRequest).replace(/\s+/g, ' ');
|
|
1374
|
+
if (!normalized) {
|
|
1375
|
+
return [];
|
|
1376
|
+
}
|
|
1377
|
+
const chunks = normalized
|
|
1378
|
+
.split(/(?:\r?\n|[;;。!?!?]|(?:\s+\band\b\s+)|(?:\s+\bthen\b\s+)|(?:\s+\balso\b\s+)|(?:\s*并且\s*)|(?:\s*同时\s*)|(?:\s*以及\s*)|(?:\s*然后\s*))/gi)
|
|
1379
|
+
.map((item) => normalizeString(item).replace(/^(?:and|then|also)\s+/i, ''))
|
|
1380
|
+
.filter(Boolean);
|
|
1381
|
+
return dedupeTaskList(chunks, 3);
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
function deriveTaskIntentShape(rawRequest = '', stageName = '') {
|
|
1385
|
+
const normalizedRaw = normalizeString(rawRequest).replace(/\s+/g, ' ');
|
|
1386
|
+
const clauses = splitTaskRawRequest(normalizedRaw);
|
|
1387
|
+
const hasRaw = normalizedRaw.length > 0;
|
|
1388
|
+
const inferredSubGoals = clauses.length > 1 ? clauses.slice(0, 3) : [];
|
|
1389
|
+
const needsSplit = inferredSubGoals.length > 1;
|
|
1390
|
+
const titleSource = clauses.length > 0
|
|
1391
|
+
? clauses[0]
|
|
1392
|
+
: (hasRaw ? normalizedRaw : `Studio ${stageName || 'task'} execution`);
|
|
1393
|
+
|
|
1394
|
+
let confidence = hasRaw ? 0.9 : 0.6;
|
|
1395
|
+
if (needsSplit) {
|
|
1396
|
+
confidence = 0.72;
|
|
1397
|
+
}
|
|
1398
|
+
if (normalizeString(stageName) && normalizeString(stageName) !== 'plan') {
|
|
1399
|
+
confidence = Math.min(0.95, confidence + 0.03);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
return {
|
|
1403
|
+
title_norm: truncateTaskText(titleSource, 96) || `Studio ${stageName || 'task'} execution`,
|
|
1404
|
+
raw_request: hasRaw ? normalizedRaw : null,
|
|
1405
|
+
sub_goals: inferredSubGoals,
|
|
1406
|
+
needs_split: needsSplit,
|
|
1407
|
+
confidence: Number(confidence.toFixed(2))
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
function buildTaskAcceptanceCriteria(stageName = '', job = {}, nextAction = '') {
|
|
1412
|
+
const normalizedStage = normalizeString(stageName) || 'task';
|
|
1413
|
+
const artifacts = job && job.artifacts ? job.artifacts : {};
|
|
1414
|
+
const criteriaByStage = {
|
|
1415
|
+
plan: [
|
|
1416
|
+
'Scene/spec binding is resolved and persisted in studio job metadata.',
|
|
1417
|
+
'Plan stage problem evaluation passes with no blockers.',
|
|
1418
|
+
`Next action is executable (${nextAction || 'sce studio generate --job <job-id>'}).`
|
|
1419
|
+
],
|
|
1420
|
+
generate: [
|
|
1421
|
+
'Patch bundle id is produced for downstream apply stage.',
|
|
1422
|
+
'Generate stage report is written to artifacts.',
|
|
1423
|
+
`Next action is executable (${nextAction || 'sce studio apply --patch-bundle <id> --job <job-id>'}).`
|
|
1424
|
+
],
|
|
1425
|
+
apply: [
|
|
1426
|
+
'Authorization requirements are satisfied for apply stage.',
|
|
1427
|
+
'Apply stage completes without policy blockers.',
|
|
1428
|
+
`Next action is executable (${nextAction || 'sce studio verify --job <job-id>'}).`
|
|
1429
|
+
],
|
|
1430
|
+
verify: [
|
|
1431
|
+
'Verification gates finish with no required-step failures.',
|
|
1432
|
+
`Verify report is available (${normalizeString(artifacts.verify_report) || 'artifact pending'}).`,
|
|
1433
|
+
`Next action is executable (${nextAction || 'sce studio release --job <job-id>'}).`
|
|
1434
|
+
],
|
|
1435
|
+
release: [
|
|
1436
|
+
'Release gates pass under configured release profile.',
|
|
1437
|
+
`Release reference is emitted (${normalizeString(artifacts.release_ref) || 'artifact pending'}).`,
|
|
1438
|
+
`Next action is executable (${nextAction || 'complete'}).`
|
|
1439
|
+
],
|
|
1440
|
+
rollback: [
|
|
1441
|
+
'Rollback stage transitions job status to rolled_back.',
|
|
1442
|
+
'Rollback evidence is appended to studio event stream.',
|
|
1443
|
+
`Recovery next action is executable (${nextAction || 'sce studio plan --scene <scene-id> --from-chat <session>'}).`
|
|
1444
|
+
],
|
|
1445
|
+
events: [
|
|
1446
|
+
'Events stream payload is available for task-level audit.',
|
|
1447
|
+
'Task envelope preserves normalized IDs and handoff fields.',
|
|
1448
|
+
`Next action is explicit (${nextAction || 'n/a'}).`
|
|
1449
|
+
],
|
|
1450
|
+
resume: [
|
|
1451
|
+
'Current job status and stage progress are restored deterministically.',
|
|
1452
|
+
'Task envelope remains schema-compatible for downstream UI.',
|
|
1453
|
+
`Next action is explicit (${nextAction || 'n/a'}).`
|
|
1454
|
+
]
|
|
1455
|
+
};
|
|
1456
|
+
return criteriaByStage[normalizedStage] || [
|
|
1457
|
+
'Task envelope contains normalized identifiers and task contract fields.',
|
|
1458
|
+
'Task output preserves evidence, command logs, and error bundles.',
|
|
1459
|
+
`Next action is explicit (${nextAction || 'n/a'}).`
|
|
1460
|
+
];
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1339
1463
|
function buildTaskEnvelope(mode, job, options = {}) {
|
|
1340
1464
|
const stageName = resolveTaskStage(mode, job, options.stageName);
|
|
1341
1465
|
const stageState = stageName && job && job.stages && job.stages[stageName]
|
|
@@ -1359,8 +1483,10 @@ function buildTaskEnvelope(mode, job, options = {}) {
|
|
|
1359
1483
|
|| (normalizeString(job && job.job_id)
|
|
1360
1484
|
? `${job.job_id}:${stageName || 'task'}`
|
|
1361
1485
|
: null);
|
|
1362
|
-
const
|
|
1486
|
+
const rawRequest = normalizeString(job?.source?.goal);
|
|
1487
|
+
const goal = rawRequest
|
|
1363
1488
|
|| `Studio ${stageName || 'task'} execution`;
|
|
1489
|
+
const taskIntent = deriveTaskIntentShape(rawRequest, stageName);
|
|
1364
1490
|
const sessionId = normalizeString(job?.session?.scene_session_id) || null;
|
|
1365
1491
|
const sceneId = normalizeString(job?.scene?.id) || null;
|
|
1366
1492
|
const specId = normalizeString(job?.scene?.spec_id) || normalizeString(job?.source?.spec_id) || null;
|
|
@@ -1400,7 +1526,14 @@ function buildTaskEnvelope(mode, job, options = {}) {
|
|
|
1400
1526
|
eventId: normalizeString(latestEvent && latestEvent.event_id) || null,
|
|
1401
1527
|
task: {
|
|
1402
1528
|
ref: taskRef,
|
|
1529
|
+
task_ref: taskRef,
|
|
1530
|
+
title_norm: taskIntent.title_norm,
|
|
1531
|
+
raw_request: taskIntent.raw_request,
|
|
1403
1532
|
goal,
|
|
1533
|
+
sub_goals: taskIntent.sub_goals,
|
|
1534
|
+
acceptance_criteria: buildTaskAcceptanceCriteria(stageName, job, nextAction),
|
|
1535
|
+
needs_split: taskIntent.needs_split,
|
|
1536
|
+
confidence: taskIntent.confidence,
|
|
1404
1537
|
status: taskStatus,
|
|
1405
1538
|
summary: buildTaskSummaryLines(job, stageName, taskStatus, nextAction, taskRef),
|
|
1406
1539
|
handoff: normalizedHandoff,
|
|
@@ -2529,6 +2662,12 @@ async function runStudioApplyCommand(options = {}, dependencies = {}) {
|
|
|
2529
2662
|
const job = await loadJob(paths, jobId, fileSystem);
|
|
2530
2663
|
ensureNotRolledBack(job, 'apply');
|
|
2531
2664
|
ensureStagePrerequisite(job, 'apply', 'generate');
|
|
2665
|
+
const leaseAuthResult = await ensureWriteAuthorization('studio:apply', options, {
|
|
2666
|
+
projectPath,
|
|
2667
|
+
fileSystem,
|
|
2668
|
+
env: dependencies.env,
|
|
2669
|
+
authSecret: dependencies.authSecret
|
|
2670
|
+
});
|
|
2532
2671
|
const authResult = await ensureStudioAuthorization('apply', options, {
|
|
2533
2672
|
projectPath,
|
|
2534
2673
|
fileSystem,
|
|
@@ -2564,14 +2703,22 @@ async function runStudioApplyCommand(options = {}, dependencies = {}) {
|
|
|
2564
2703
|
|
|
2565
2704
|
ensureStageCompleted(job, 'apply', {
|
|
2566
2705
|
patch_bundle_id: patchBundleId,
|
|
2567
|
-
auth_required: authResult.required,
|
|
2706
|
+
auth_required: authResult.required || leaseAuthResult.required,
|
|
2707
|
+
auth_password_required: authResult.required,
|
|
2708
|
+
auth_lease_required: leaseAuthResult.required,
|
|
2709
|
+
auth_lease_id: leaseAuthResult.lease_id || null,
|
|
2710
|
+
auth_lease_expires_at: leaseAuthResult.lease_expires_at || null,
|
|
2568
2711
|
problem_evaluation: summarizeProblemEvaluation(applyProblemEvaluation)
|
|
2569
2712
|
});
|
|
2570
2713
|
|
|
2571
2714
|
await saveJob(paths, job, fileSystem);
|
|
2572
2715
|
const applyEvent = await appendStudioEvent(paths, job, 'stage.apply.completed', {
|
|
2573
2716
|
patch_bundle_id: patchBundleId,
|
|
2574
|
-
auth_required: authResult.required,
|
|
2717
|
+
auth_required: authResult.required || leaseAuthResult.required,
|
|
2718
|
+
auth_password_required: authResult.required,
|
|
2719
|
+
auth_lease_required: leaseAuthResult.required,
|
|
2720
|
+
auth_lease_id: leaseAuthResult.lease_id || null,
|
|
2721
|
+
auth_lease_expires_at: leaseAuthResult.lease_expires_at || null,
|
|
2575
2722
|
problem_evaluation: summarizeProblemEvaluation(applyProblemEvaluation)
|
|
2576
2723
|
}, fileSystem);
|
|
2577
2724
|
await writeLatestJob(paths, jobId, fileSystem);
|
|
@@ -2758,6 +2905,12 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
2758
2905
|
const job = await loadJob(paths, jobId, fileSystem);
|
|
2759
2906
|
ensureNotRolledBack(job, 'release');
|
|
2760
2907
|
ensureStagePrerequisite(job, 'release', 'verify');
|
|
2908
|
+
const leaseAuthResult = await ensureWriteAuthorization('studio:release', options, {
|
|
2909
|
+
projectPath,
|
|
2910
|
+
fileSystem,
|
|
2911
|
+
env: dependencies.env,
|
|
2912
|
+
authSecret: dependencies.authSecret
|
|
2913
|
+
});
|
|
2761
2914
|
const authResult = await ensureStudioAuthorization('release', options, {
|
|
2762
2915
|
projectPath,
|
|
2763
2916
|
fileSystem,
|
|
@@ -2874,7 +3027,11 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
2874
3027
|
passed: false,
|
|
2875
3028
|
report: releaseReportPath,
|
|
2876
3029
|
gate_steps: gateResult.steps,
|
|
2877
|
-
auth_required: authResult.required,
|
|
3030
|
+
auth_required: authResult.required || leaseAuthResult.required,
|
|
3031
|
+
auth_password_required: authResult.required,
|
|
3032
|
+
auth_lease_required: leaseAuthResult.required,
|
|
3033
|
+
auth_lease_id: leaseAuthResult.lease_id || null,
|
|
3034
|
+
auth_lease_expires_at: leaseAuthResult.lease_expires_at || null,
|
|
2878
3035
|
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
2879
3036
|
domain_chain: domainChainMetadata,
|
|
2880
3037
|
auto_errorbook_records: autoErrorbookRecords
|
|
@@ -2885,7 +3042,11 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
2885
3042
|
channel,
|
|
2886
3043
|
release_ref: releaseRef,
|
|
2887
3044
|
report: releaseReportPath,
|
|
2888
|
-
auth_required: authResult.required,
|
|
3045
|
+
auth_required: authResult.required || leaseAuthResult.required,
|
|
3046
|
+
auth_password_required: authResult.required,
|
|
3047
|
+
auth_lease_required: leaseAuthResult.required,
|
|
3048
|
+
auth_lease_id: leaseAuthResult.lease_id || null,
|
|
3049
|
+
auth_lease_expires_at: leaseAuthResult.lease_expires_at || null,
|
|
2889
3050
|
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
2890
3051
|
domain_chain: domainChainMetadata,
|
|
2891
3052
|
auto_errorbook_records: autoErrorbookRecords
|
|
@@ -2900,7 +3061,11 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
2900
3061
|
release_ref: releaseRef,
|
|
2901
3062
|
report: releaseReportPath,
|
|
2902
3063
|
gate_steps: gateResult.steps,
|
|
2903
|
-
auth_required: authResult.required,
|
|
3064
|
+
auth_required: authResult.required || leaseAuthResult.required,
|
|
3065
|
+
auth_password_required: authResult.required,
|
|
3066
|
+
auth_lease_required: leaseAuthResult.required,
|
|
3067
|
+
auth_lease_id: leaseAuthResult.lease_id || null,
|
|
3068
|
+
auth_lease_expires_at: leaseAuthResult.lease_expires_at || null,
|
|
2904
3069
|
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
2905
3070
|
domain_chain: domainChainMetadata,
|
|
2906
3071
|
auto_errorbook_records: autoErrorbookRecords
|
|
@@ -2932,7 +3097,11 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
2932
3097
|
channel,
|
|
2933
3098
|
release_ref: releaseRef,
|
|
2934
3099
|
report: releaseReportPath,
|
|
2935
|
-
auth_required: authResult.required,
|
|
3100
|
+
auth_required: authResult.required || leaseAuthResult.required,
|
|
3101
|
+
auth_password_required: authResult.required,
|
|
3102
|
+
auth_lease_required: leaseAuthResult.required,
|
|
3103
|
+
auth_lease_id: leaseAuthResult.lease_id || null,
|
|
3104
|
+
auth_lease_expires_at: leaseAuthResult.lease_expires_at || null,
|
|
2936
3105
|
problem_evaluation: summarizeProblemEvaluation(releaseProblemEvaluation),
|
|
2937
3106
|
domain_chain: domainChainMetadata,
|
|
2938
3107
|
auto_errorbook_records: autoErrorbookRecords
|
|
@@ -2987,6 +3156,12 @@ async function runStudioRollbackCommand(options = {}, dependencies = {}) {
|
|
|
2987
3156
|
|
|
2988
3157
|
const reason = normalizeString(options.reason) || 'manual-rollback';
|
|
2989
3158
|
const job = await loadJob(paths, jobId, fileSystem);
|
|
3159
|
+
const leaseAuthResult = await ensureWriteAuthorization('studio:rollback', options, {
|
|
3160
|
+
projectPath,
|
|
3161
|
+
fileSystem,
|
|
3162
|
+
env: dependencies.env,
|
|
3163
|
+
authSecret: dependencies.authSecret
|
|
3164
|
+
});
|
|
2990
3165
|
const authResult = await ensureStudioAuthorization('rollback', options, {
|
|
2991
3166
|
projectPath,
|
|
2992
3167
|
fileSystem,
|
|
@@ -3002,7 +3177,11 @@ async function runStudioRollbackCommand(options = {}, dependencies = {}) {
|
|
|
3002
3177
|
job.rollback = {
|
|
3003
3178
|
reason,
|
|
3004
3179
|
rolled_back_at: job.updated_at,
|
|
3005
|
-
auth_required: authResult.required
|
|
3180
|
+
auth_required: authResult.required || leaseAuthResult.required,
|
|
3181
|
+
auth_password_required: authResult.required,
|
|
3182
|
+
auth_lease_required: leaseAuthResult.required,
|
|
3183
|
+
auth_lease_id: leaseAuthResult.lease_id || null,
|
|
3184
|
+
auth_lease_expires_at: leaseAuthResult.lease_expires_at || null
|
|
3006
3185
|
};
|
|
3007
3186
|
|
|
3008
3187
|
const sceneSessionId = normalizeString(job && job.session && job.session.scene_session_id);
|
|
@@ -3376,6 +3555,7 @@ function registerStudioCommands(program) {
|
|
|
3376
3555
|
.command('apply')
|
|
3377
3556
|
.description('Apply generated patch bundle metadata to studio job')
|
|
3378
3557
|
.option('--patch-bundle <id>', 'Patch bundle identifier (defaults to generated artifact)')
|
|
3558
|
+
.option('--auth-lease <lease-id>', 'Write authorization lease id (sce auth grant)')
|
|
3379
3559
|
.option('--auth-password <password>', 'Authorization password for protected apply action')
|
|
3380
3560
|
.option('--require-auth', 'Require authorization even when policy is advisory')
|
|
3381
3561
|
.option('--job <job-id>', 'Studio job id (defaults to latest)')
|
|
@@ -3395,6 +3575,7 @@ function registerStudioCommands(program) {
|
|
|
3395
3575
|
.description('Record release stage for studio job')
|
|
3396
3576
|
.option('--channel <channel>', 'Release channel (dev|prod)', 'dev')
|
|
3397
3577
|
.option('--profile <profile>', 'Release gate profile', 'standard')
|
|
3578
|
+
.option('--auth-lease <lease-id>', 'Write authorization lease id (sce auth grant)')
|
|
3398
3579
|
.option('--auth-password <password>', 'Authorization password for protected release action')
|
|
3399
3580
|
.option('--require-auth', 'Require authorization even when policy is advisory')
|
|
3400
3581
|
.option('--release-ref <ref>', 'Explicit release reference/tag')
|
|
@@ -3423,6 +3604,7 @@ function registerStudioCommands(program) {
|
|
|
3423
3604
|
.description('Rollback a studio job after apply/release')
|
|
3424
3605
|
.option('--job <job-id>', 'Studio job id (defaults to latest)')
|
|
3425
3606
|
.option('--reason <reason>', 'Rollback reason')
|
|
3607
|
+
.option('--auth-lease <lease-id>', 'Write authorization lease id (sce auth grant)')
|
|
3426
3608
|
.option('--auth-password <password>', 'Authorization password for protected rollback action')
|
|
3427
3609
|
.option('--require-auth', 'Require authorization even when policy is advisory')
|
|
3428
3610
|
.option('--json', 'Print machine-readable JSON output')
|
package/lib/commands/task.js
CHANGED
|
@@ -11,6 +11,7 @@ const chalk = require('chalk');
|
|
|
11
11
|
const TaskClaimer = require('../task/task-claimer');
|
|
12
12
|
const WorkspaceManager = require('../workspace/workspace-manager');
|
|
13
13
|
const { TaskRefRegistry } = require('../task/task-ref-registry');
|
|
14
|
+
const { ensureWriteAuthorization } = require('../security/write-authorization');
|
|
14
15
|
|
|
15
16
|
function normalizeString(value) {
|
|
16
17
|
if (typeof value !== 'string') {
|
|
@@ -436,6 +437,17 @@ async function runTaskRerunCommand(options = {}, dependencies = {}) {
|
|
|
436
437
|
if (!lookup) {
|
|
437
438
|
throw new Error(`Task ref not found: ${taskRef}`);
|
|
438
439
|
}
|
|
440
|
+
const writeAuthResult = dryRun
|
|
441
|
+
? {
|
|
442
|
+
required: false,
|
|
443
|
+
passed: true
|
|
444
|
+
}
|
|
445
|
+
: await ensureWriteAuthorization('task:rerun', options, {
|
|
446
|
+
projectPath,
|
|
447
|
+
fileSystem,
|
|
448
|
+
env: dependencies.env,
|
|
449
|
+
authSecret: dependencies.authSecret
|
|
450
|
+
});
|
|
439
451
|
|
|
440
452
|
if (isStudioTaskRef(lookup)) {
|
|
441
453
|
const stage = resolveStudioStageFromTaskKey(lookup.task_key);
|
|
@@ -453,7 +465,12 @@ async function runTaskRerunCommand(options = {}, dependencies = {}) {
|
|
|
453
465
|
stage,
|
|
454
466
|
job_id: normalizeString(job?.job_id) || null,
|
|
455
467
|
dry_run: dryRun,
|
|
456
|
-
command: stringifySceArgs(rerunPlan.args)
|
|
468
|
+
command: stringifySceArgs(rerunPlan.args),
|
|
469
|
+
authorization: {
|
|
470
|
+
required: writeAuthResult.required === true,
|
|
471
|
+
lease_id: writeAuthResult.lease_id || null,
|
|
472
|
+
lease_expires_at: writeAuthResult.lease_expires_at || null
|
|
473
|
+
}
|
|
457
474
|
};
|
|
458
475
|
|
|
459
476
|
if (!dryRun) {
|
|
@@ -486,7 +503,12 @@ async function runTaskRerunCommand(options = {}, dependencies = {}) {
|
|
|
486
503
|
task_ref: lookup.task_ref,
|
|
487
504
|
rerun_type: 'spec-task',
|
|
488
505
|
dry_run: dryRun,
|
|
489
|
-
command: `sce task claim ${lookup.spec_id} ${lookup.task_key}
|
|
506
|
+
command: `sce task claim ${lookup.spec_id} ${lookup.task_key}`,
|
|
507
|
+
authorization: {
|
|
508
|
+
required: writeAuthResult.required === true,
|
|
509
|
+
lease_id: writeAuthResult.lease_id || null,
|
|
510
|
+
lease_expires_at: writeAuthResult.lease_expires_at || null
|
|
511
|
+
}
|
|
490
512
|
};
|
|
491
513
|
|
|
492
514
|
if (!dryRun) {
|
|
@@ -734,6 +756,7 @@ function registerTaskCommands(program) {
|
|
|
734
756
|
.description('Rerun task by hierarchical reference')
|
|
735
757
|
.requiredOption('--ref <task-ref>', 'Task reference (SS.PP.TT)')
|
|
736
758
|
.option('--dry-run', 'Preview rerun command without executing')
|
|
759
|
+
.option('--auth-lease <lease-id>', 'Write authorization lease id (sce auth grant)')
|
|
737
760
|
.option('--from-chat <session>', 'Override session for studio plan rerun')
|
|
738
761
|
.option('--job <job-id>', 'Override studio job id')
|
|
739
762
|
.option('--profile <profile>', 'Override profile for studio verify/release rerun')
|