scene-capability-engine 3.5.2 → 3.6.2
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 +28 -0
- package/README.md +14 -4
- package/README.zh.md +14 -4
- package/bin/scene-capability-engine.js +2 -0
- package/docs/command-reference.md +23 -4
- package/docs/release-checklist.md +3 -3
- package/docs/zh/release-checklist.md +3 -3
- package/lib/commands/studio.js +246 -59
- package/lib/commands/task.js +630 -68
- package/lib/state/sce-state-store.js +594 -0
- package/lib/task/task-ref-registry.js +139 -0
- package/package.json +3 -2
package/lib/commands/studio.js
CHANGED
|
@@ -11,6 +11,8 @@ const {
|
|
|
11
11
|
const { findRelatedSpecs } = require('../spec/related-specs');
|
|
12
12
|
const { captureTimelineCheckpoint } = require('../runtime/project-timeline');
|
|
13
13
|
const { runProblemEvaluation } = require('../problem/problem-evaluator');
|
|
14
|
+
const { TaskRefRegistry } = require('../task/task-ref-registry');
|
|
15
|
+
const { getSceStateStore } = require('../state/sce-state-store');
|
|
14
16
|
const {
|
|
15
17
|
loadStudioIntakePolicy,
|
|
16
18
|
runStudioAutoIntake,
|
|
@@ -40,8 +42,7 @@ function resolveStudioPaths(projectPath = process.cwd()) {
|
|
|
40
42
|
projectPath,
|
|
41
43
|
studioDir,
|
|
42
44
|
jobsDir: path.join(studioDir, 'jobs'),
|
|
43
|
-
latestFile: path.join(studioDir, 'latest-job.json')
|
|
44
|
-
eventsDir: path.join(studioDir, 'events')
|
|
45
|
+
latestFile: path.join(studioDir, 'latest-job.json')
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -597,7 +598,6 @@ async function writeStudioReport(projectPath, relativePath, payload, fileSystem
|
|
|
597
598
|
|
|
598
599
|
async function ensureStudioDirectories(paths, fileSystem = fs) {
|
|
599
600
|
await fileSystem.ensureDir(paths.jobsDir);
|
|
600
|
-
await fileSystem.ensureDir(paths.eventsDir);
|
|
601
601
|
}
|
|
602
602
|
|
|
603
603
|
async function writeLatestJob(paths, jobId, fileSystem = fs) {
|
|
@@ -622,10 +622,6 @@ function getJobFilePath(paths, jobId) {
|
|
|
622
622
|
return path.join(paths.jobsDir, `${jobId}.json`);
|
|
623
623
|
}
|
|
624
624
|
|
|
625
|
-
function getEventLogFilePath(paths, jobId) {
|
|
626
|
-
return path.join(paths.eventsDir, `${jobId}.jsonl`);
|
|
627
|
-
}
|
|
628
|
-
|
|
629
625
|
async function saveJob(paths, job, fileSystem = fs) {
|
|
630
626
|
const jobFile = getJobFilePath(paths, job.job_id);
|
|
631
627
|
await fileSystem.writeJson(jobFile, job, { spaces: 2 });
|
|
@@ -640,40 +636,28 @@ async function appendStudioEvent(paths, job, eventType, metadata = {}, fileSyste
|
|
|
640
636
|
timestamp: nowIso(),
|
|
641
637
|
metadata
|
|
642
638
|
};
|
|
643
|
-
const
|
|
644
|
-
const
|
|
645
|
-
|
|
639
|
+
const sceneId = normalizeString(job?.scene?.id) || null;
|
|
640
|
+
const specId = normalizeString(job?.scene?.spec_id) || normalizeString(job?.source?.spec_id) || null;
|
|
641
|
+
const stateStore = getSceStateStore(paths.projectPath, { fileSystem });
|
|
642
|
+
const persisted = await stateStore.appendStudioEvent({
|
|
643
|
+
...event,
|
|
644
|
+
scene_id: sceneId,
|
|
645
|
+
spec_id: specId
|
|
646
|
+
});
|
|
647
|
+
if (!persisted) {
|
|
648
|
+
throw new Error('Failed to persist studio event into sqlite state store');
|
|
649
|
+
}
|
|
646
650
|
return event;
|
|
647
651
|
}
|
|
648
652
|
|
|
649
653
|
async function readStudioEvents(paths, jobId, options = {}, fileSystem = fs) {
|
|
650
654
|
const { limit = 50 } = options;
|
|
651
|
-
const
|
|
652
|
-
const
|
|
653
|
-
if (
|
|
654
|
-
|
|
655
|
+
const stateStore = getSceStateStore(paths.projectPath, { fileSystem });
|
|
656
|
+
const events = await stateStore.listStudioEvents(jobId, { limit });
|
|
657
|
+
if (events === null) {
|
|
658
|
+
throw new Error('SQLite state backend unavailable while reading studio events');
|
|
655
659
|
}
|
|
656
|
-
|
|
657
|
-
const content = await fileSystem.readFile(eventFile, 'utf8');
|
|
658
|
-
const lines = content
|
|
659
|
-
.split(/\r?\n/)
|
|
660
|
-
.map((line) => line.trim())
|
|
661
|
-
.filter(Boolean);
|
|
662
|
-
|
|
663
|
-
const parsed = [];
|
|
664
|
-
for (const line of lines) {
|
|
665
|
-
try {
|
|
666
|
-
const payload = JSON.parse(line);
|
|
667
|
-
parsed.push(payload);
|
|
668
|
-
} catch (_error) {
|
|
669
|
-
// Ignore malformed lines to keep event stream robust.
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
if (limit <= 0) {
|
|
674
|
-
return parsed;
|
|
675
|
-
}
|
|
676
|
-
return parsed.slice(-limit);
|
|
660
|
+
return events;
|
|
677
661
|
}
|
|
678
662
|
|
|
679
663
|
async function loadJob(paths, jobId, fileSystem = fs) {
|
|
@@ -1333,25 +1317,148 @@ function collectTaskEvidence(job = {}, stageName = '', stageMetadata = {}) {
|
|
|
1333
1317
|
if (normalizeString(job && job.job_id)) {
|
|
1334
1318
|
evidence.push({
|
|
1335
1319
|
type: 'event-log',
|
|
1336
|
-
ref:
|
|
1337
|
-
detail:
|
|
1320
|
+
ref: '.sce/state/sce-state.sqlite',
|
|
1321
|
+
detail: `studio_event_stream:job_id=${job.job_id}`
|
|
1338
1322
|
});
|
|
1339
1323
|
}
|
|
1340
1324
|
|
|
1341
1325
|
return normalizeTaskEvidence(evidence);
|
|
1342
1326
|
}
|
|
1343
1327
|
|
|
1344
|
-
function buildTaskSummaryLines(job = {}, stageName = '', taskStatus = '', nextAction = '') {
|
|
1328
|
+
function buildTaskSummaryLines(job = {}, stageName = '', taskStatus = '', nextAction = '', taskRef = '') {
|
|
1345
1329
|
const sceneId = normalizeString(job?.scene?.id) || 'scene.n/a';
|
|
1346
1330
|
const specId = normalizeString(job?.scene?.spec_id) || normalizeString(job?.source?.spec_id) || 'spec.n/a';
|
|
1347
1331
|
const progress = buildProgress(job);
|
|
1348
1332
|
return [
|
|
1349
|
-
`Stage: ${stageName || 'plan'} | Status: ${taskStatus || 'unknown'}`,
|
|
1333
|
+
`Stage: ${stageName || 'plan'} | Status: ${taskStatus || 'unknown'}${taskRef ? ` | Ref: ${taskRef}` : ''}`,
|
|
1350
1334
|
`Scene: ${sceneId} | Spec: ${specId} | Progress: ${progress.completed}/${progress.total}`,
|
|
1351
1335
|
`Next: ${nextAction || 'n/a'}`
|
|
1352
1336
|
];
|
|
1353
1337
|
}
|
|
1354
1338
|
|
|
1339
|
+
function truncateTaskText(value = '', maxLength = 96) {
|
|
1340
|
+
const normalized = normalizeString(value).replace(/\s+/g, ' ');
|
|
1341
|
+
if (!normalized) {
|
|
1342
|
+
return '';
|
|
1343
|
+
}
|
|
1344
|
+
if (normalized.length <= maxLength) {
|
|
1345
|
+
return normalized;
|
|
1346
|
+
}
|
|
1347
|
+
return `${normalized.slice(0, Math.max(0, maxLength - 3)).trim()}...`;
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
function dedupeTaskList(items = [], limit = 3) {
|
|
1351
|
+
const seen = new Set();
|
|
1352
|
+
const result = [];
|
|
1353
|
+
for (const item of items) {
|
|
1354
|
+
const normalized = truncateTaskText(item, 120);
|
|
1355
|
+
if (!normalized) {
|
|
1356
|
+
continue;
|
|
1357
|
+
}
|
|
1358
|
+
const key = normalized.toLowerCase();
|
|
1359
|
+
if (seen.has(key)) {
|
|
1360
|
+
continue;
|
|
1361
|
+
}
|
|
1362
|
+
seen.add(key);
|
|
1363
|
+
result.push(normalized);
|
|
1364
|
+
if (result.length >= limit) {
|
|
1365
|
+
break;
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
return result;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
function splitTaskRawRequest(rawRequest = '') {
|
|
1372
|
+
const normalized = normalizeString(rawRequest).replace(/\s+/g, ' ');
|
|
1373
|
+
if (!normalized) {
|
|
1374
|
+
return [];
|
|
1375
|
+
}
|
|
1376
|
+
const chunks = normalized
|
|
1377
|
+
.split(/(?:\r?\n|[;;。!?!?]|(?:\s+\band\b\s+)|(?:\s+\bthen\b\s+)|(?:\s+\balso\b\s+)|(?:\s*并且\s*)|(?:\s*同时\s*)|(?:\s*以及\s*)|(?:\s*然后\s*))/gi)
|
|
1378
|
+
.map((item) => normalizeString(item).replace(/^(?:and|then|also)\s+/i, ''))
|
|
1379
|
+
.filter(Boolean);
|
|
1380
|
+
return dedupeTaskList(chunks, 3);
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
function deriveTaskIntentShape(rawRequest = '', stageName = '') {
|
|
1384
|
+
const normalizedRaw = normalizeString(rawRequest).replace(/\s+/g, ' ');
|
|
1385
|
+
const clauses = splitTaskRawRequest(normalizedRaw);
|
|
1386
|
+
const hasRaw = normalizedRaw.length > 0;
|
|
1387
|
+
const inferredSubGoals = clauses.length > 1 ? clauses.slice(0, 3) : [];
|
|
1388
|
+
const needsSplit = inferredSubGoals.length > 1;
|
|
1389
|
+
const titleSource = clauses.length > 0
|
|
1390
|
+
? clauses[0]
|
|
1391
|
+
: (hasRaw ? normalizedRaw : `Studio ${stageName || 'task'} execution`);
|
|
1392
|
+
|
|
1393
|
+
let confidence = hasRaw ? 0.9 : 0.6;
|
|
1394
|
+
if (needsSplit) {
|
|
1395
|
+
confidence = 0.72;
|
|
1396
|
+
}
|
|
1397
|
+
if (normalizeString(stageName) && normalizeString(stageName) !== 'plan') {
|
|
1398
|
+
confidence = Math.min(0.95, confidence + 0.03);
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
return {
|
|
1402
|
+
title_norm: truncateTaskText(titleSource, 96) || `Studio ${stageName || 'task'} execution`,
|
|
1403
|
+
raw_request: hasRaw ? normalizedRaw : null,
|
|
1404
|
+
sub_goals: inferredSubGoals,
|
|
1405
|
+
needs_split: needsSplit,
|
|
1406
|
+
confidence: Number(confidence.toFixed(2))
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
function buildTaskAcceptanceCriteria(stageName = '', job = {}, nextAction = '') {
|
|
1411
|
+
const normalizedStage = normalizeString(stageName) || 'task';
|
|
1412
|
+
const artifacts = job && job.artifacts ? job.artifacts : {};
|
|
1413
|
+
const criteriaByStage = {
|
|
1414
|
+
plan: [
|
|
1415
|
+
'Scene/spec binding is resolved and persisted in studio job metadata.',
|
|
1416
|
+
'Plan stage problem evaluation passes with no blockers.',
|
|
1417
|
+
`Next action is executable (${nextAction || 'sce studio generate --job <job-id>'}).`
|
|
1418
|
+
],
|
|
1419
|
+
generate: [
|
|
1420
|
+
'Patch bundle id is produced for downstream apply stage.',
|
|
1421
|
+
'Generate stage report is written to artifacts.',
|
|
1422
|
+
`Next action is executable (${nextAction || 'sce studio apply --patch-bundle <id> --job <job-id>'}).`
|
|
1423
|
+
],
|
|
1424
|
+
apply: [
|
|
1425
|
+
'Authorization requirements are satisfied for apply stage.',
|
|
1426
|
+
'Apply stage completes without policy blockers.',
|
|
1427
|
+
`Next action is executable (${nextAction || 'sce studio verify --job <job-id>'}).`
|
|
1428
|
+
],
|
|
1429
|
+
verify: [
|
|
1430
|
+
'Verification gates finish with no required-step failures.',
|
|
1431
|
+
`Verify report is available (${normalizeString(artifacts.verify_report) || 'artifact pending'}).`,
|
|
1432
|
+
`Next action is executable (${nextAction || 'sce studio release --job <job-id>'}).`
|
|
1433
|
+
],
|
|
1434
|
+
release: [
|
|
1435
|
+
'Release gates pass under configured release profile.',
|
|
1436
|
+
`Release reference is emitted (${normalizeString(artifacts.release_ref) || 'artifact pending'}).`,
|
|
1437
|
+
`Next action is executable (${nextAction || 'complete'}).`
|
|
1438
|
+
],
|
|
1439
|
+
rollback: [
|
|
1440
|
+
'Rollback stage transitions job status to rolled_back.',
|
|
1441
|
+
'Rollback evidence is appended to studio event stream.',
|
|
1442
|
+
`Recovery next action is executable (${nextAction || 'sce studio plan --scene <scene-id> --from-chat <session>'}).`
|
|
1443
|
+
],
|
|
1444
|
+
events: [
|
|
1445
|
+
'Events stream payload is available for task-level audit.',
|
|
1446
|
+
'Task envelope preserves normalized IDs and handoff fields.',
|
|
1447
|
+
`Next action is explicit (${nextAction || 'n/a'}).`
|
|
1448
|
+
],
|
|
1449
|
+
resume: [
|
|
1450
|
+
'Current job status and stage progress are restored deterministically.',
|
|
1451
|
+
'Task envelope remains schema-compatible for downstream UI.',
|
|
1452
|
+
`Next action is explicit (${nextAction || 'n/a'}).`
|
|
1453
|
+
]
|
|
1454
|
+
};
|
|
1455
|
+
return criteriaByStage[normalizedStage] || [
|
|
1456
|
+
'Task envelope contains normalized identifiers and task contract fields.',
|
|
1457
|
+
'Task output preserves evidence, command logs, and error bundles.',
|
|
1458
|
+
`Next action is explicit (${nextAction || 'n/a'}).`
|
|
1459
|
+
];
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1355
1462
|
function buildTaskEnvelope(mode, job, options = {}) {
|
|
1356
1463
|
const stageName = resolveTaskStage(mode, job, options.stageName);
|
|
1357
1464
|
const stageState = stageName && job && job.stages && job.stages[stageName]
|
|
@@ -1375,11 +1482,14 @@ function buildTaskEnvelope(mode, job, options = {}) {
|
|
|
1375
1482
|
|| (normalizeString(job && job.job_id)
|
|
1376
1483
|
? `${job.job_id}:${stageName || 'task'}`
|
|
1377
1484
|
: null);
|
|
1378
|
-
const
|
|
1485
|
+
const rawRequest = normalizeString(job?.source?.goal);
|
|
1486
|
+
const goal = rawRequest
|
|
1379
1487
|
|| `Studio ${stageName || 'task'} execution`;
|
|
1488
|
+
const taskIntent = deriveTaskIntentShape(rawRequest, stageName);
|
|
1380
1489
|
const sessionId = normalizeString(job?.session?.scene_session_id) || null;
|
|
1381
1490
|
const sceneId = normalizeString(job?.scene?.id) || null;
|
|
1382
1491
|
const specId = normalizeString(job?.scene?.spec_id) || normalizeString(job?.source?.spec_id) || null;
|
|
1492
|
+
const taskRef = normalizeString(options.taskRef) || null;
|
|
1383
1493
|
|
|
1384
1494
|
const commands = normalizeTaskCommands([
|
|
1385
1495
|
...(Array.isArray(stageMetadata.commands) ? stageMetadata.commands : []),
|
|
@@ -1401,17 +1511,31 @@ function buildTaskEnvelope(mode, job, options = {}) {
|
|
|
1401
1511
|
release_ref: normalizeString(stageMetadata.release_ref) || normalizeString(job?.artifacts?.release_ref) || null
|
|
1402
1512
|
};
|
|
1403
1513
|
|
|
1514
|
+
const normalizedHandoff = {
|
|
1515
|
+
...handoff,
|
|
1516
|
+
task_ref: taskRef
|
|
1517
|
+
};
|
|
1518
|
+
|
|
1404
1519
|
return {
|
|
1405
1520
|
sessionId,
|
|
1406
1521
|
sceneId,
|
|
1407
1522
|
specId,
|
|
1408
1523
|
taskId,
|
|
1524
|
+
taskRef,
|
|
1409
1525
|
eventId: normalizeString(latestEvent && latestEvent.event_id) || null,
|
|
1410
1526
|
task: {
|
|
1527
|
+
ref: taskRef,
|
|
1528
|
+
task_ref: taskRef,
|
|
1529
|
+
title_norm: taskIntent.title_norm,
|
|
1530
|
+
raw_request: taskIntent.raw_request,
|
|
1411
1531
|
goal,
|
|
1532
|
+
sub_goals: taskIntent.sub_goals,
|
|
1533
|
+
acceptance_criteria: buildTaskAcceptanceCriteria(stageName, job, nextAction),
|
|
1534
|
+
needs_split: taskIntent.needs_split,
|
|
1535
|
+
confidence: taskIntent.confidence,
|
|
1412
1536
|
status: taskStatus,
|
|
1413
|
-
summary: buildTaskSummaryLines(job, stageName, taskStatus, nextAction),
|
|
1414
|
-
handoff,
|
|
1537
|
+
summary: buildTaskSummaryLines(job, stageName, taskStatus, nextAction, taskRef),
|
|
1538
|
+
handoff: normalizedHandoff,
|
|
1415
1539
|
next_action: nextAction,
|
|
1416
1540
|
file_changes: fileChanges,
|
|
1417
1541
|
commands,
|
|
@@ -1862,7 +1986,49 @@ function ensureNotRolledBack(job, stageName) {
|
|
|
1862
1986
|
}
|
|
1863
1987
|
}
|
|
1864
1988
|
|
|
1865
|
-
function
|
|
1989
|
+
function buildStudioTaskKey(stageName = '') {
|
|
1990
|
+
const normalizedStage = normalizeString(stageName) || 'task';
|
|
1991
|
+
return `studio:${normalizedStage}`;
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
async function resolveTaskReference(mode, job, options = {}) {
|
|
1995
|
+
const explicitTaskRef = normalizeString(options.taskRef);
|
|
1996
|
+
if (explicitTaskRef) {
|
|
1997
|
+
return explicitTaskRef;
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
const sceneId = normalizeString(job?.scene?.id);
|
|
2001
|
+
const specId = normalizeString(job?.scene?.spec_id) || normalizeString(job?.source?.spec_id);
|
|
2002
|
+
if (!sceneId || !specId) {
|
|
2003
|
+
return null;
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
const stageName = resolveTaskStage(mode, job, options.stageName);
|
|
2007
|
+
const taskKey = normalizeString(options.taskKey) || buildStudioTaskKey(stageName);
|
|
2008
|
+
const projectPath = normalizeString(options.projectPath) || process.cwd();
|
|
2009
|
+
const fileSystem = options.fileSystem || fs;
|
|
2010
|
+
const taskRefRegistry = options.taskRefRegistry || new TaskRefRegistry(projectPath, { fileSystem });
|
|
2011
|
+
|
|
2012
|
+
try {
|
|
2013
|
+
const taskRef = await taskRefRegistry.resolveOrCreateRef({
|
|
2014
|
+
sceneId,
|
|
2015
|
+
specId,
|
|
2016
|
+
taskKey,
|
|
2017
|
+
source: 'studio-stage',
|
|
2018
|
+
metadata: {
|
|
2019
|
+
mode: normalizeString(mode) || null,
|
|
2020
|
+
stage: stageName || null,
|
|
2021
|
+
job_id: normalizeString(job?.job_id) || null
|
|
2022
|
+
}
|
|
2023
|
+
});
|
|
2024
|
+
return taskRef.task_ref;
|
|
2025
|
+
} catch (_error) {
|
|
2026
|
+
return null;
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
async function buildCommandPayload(mode, job, options = {}) {
|
|
2031
|
+
const taskRef = await resolveTaskReference(mode, job, options);
|
|
1866
2032
|
const base = {
|
|
1867
2033
|
mode,
|
|
1868
2034
|
success: true,
|
|
@@ -1874,7 +2040,10 @@ function buildCommandPayload(mode, job, options = {}) {
|
|
|
1874
2040
|
};
|
|
1875
2041
|
return {
|
|
1876
2042
|
...base,
|
|
1877
|
-
...buildTaskEnvelope(mode, job,
|
|
2043
|
+
...buildTaskEnvelope(mode, job, {
|
|
2044
|
+
...options,
|
|
2045
|
+
taskRef
|
|
2046
|
+
})
|
|
1878
2047
|
};
|
|
1879
2048
|
}
|
|
1880
2049
|
|
|
@@ -2367,9 +2536,11 @@ async function runStudioPlanCommand(options = {}, dependencies = {}) {
|
|
|
2367
2536
|
}, fileSystem);
|
|
2368
2537
|
await writeLatestJob(paths, jobId, fileSystem);
|
|
2369
2538
|
|
|
2370
|
-
const payload = buildCommandPayload('studio-plan', job, {
|
|
2539
|
+
const payload = await buildCommandPayload('studio-plan', job, {
|
|
2371
2540
|
stageName: 'plan',
|
|
2372
|
-
event: planEvent
|
|
2541
|
+
event: planEvent,
|
|
2542
|
+
projectPath,
|
|
2543
|
+
fileSystem
|
|
2373
2544
|
});
|
|
2374
2545
|
payload.scene = {
|
|
2375
2546
|
id: sceneId,
|
|
@@ -2465,9 +2636,11 @@ async function runStudioGenerateCommand(options = {}, dependencies = {}) {
|
|
|
2465
2636
|
}, fileSystem);
|
|
2466
2637
|
await writeLatestJob(paths, jobId, fileSystem);
|
|
2467
2638
|
|
|
2468
|
-
const payload = buildCommandPayload('studio-generate', job, {
|
|
2639
|
+
const payload = await buildCommandPayload('studio-generate', job, {
|
|
2469
2640
|
stageName: 'generate',
|
|
2470
|
-
event: generateEvent
|
|
2641
|
+
event: generateEvent,
|
|
2642
|
+
projectPath,
|
|
2643
|
+
fileSystem
|
|
2471
2644
|
});
|
|
2472
2645
|
printStudioPayload(payload, options);
|
|
2473
2646
|
return payload;
|
|
@@ -2535,9 +2708,11 @@ async function runStudioApplyCommand(options = {}, dependencies = {}) {
|
|
|
2535
2708
|
}, fileSystem);
|
|
2536
2709
|
await writeLatestJob(paths, jobId, fileSystem);
|
|
2537
2710
|
|
|
2538
|
-
const payload = buildCommandPayload('studio-apply', job, {
|
|
2711
|
+
const payload = await buildCommandPayload('studio-apply', job, {
|
|
2539
2712
|
stageName: 'apply',
|
|
2540
|
-
event: applyEvent
|
|
2713
|
+
event: applyEvent,
|
|
2714
|
+
projectPath,
|
|
2715
|
+
fileSystem
|
|
2541
2716
|
});
|
|
2542
2717
|
printStudioPayload(payload, options);
|
|
2543
2718
|
return payload;
|
|
@@ -2685,9 +2860,11 @@ async function runStudioVerifyCommand(options = {}, dependencies = {}) {
|
|
|
2685
2860
|
}, fileSystem);
|
|
2686
2861
|
await writeLatestJob(paths, jobId, fileSystem);
|
|
2687
2862
|
|
|
2688
|
-
const payload = buildCommandPayload('studio-verify', job, {
|
|
2863
|
+
const payload = await buildCommandPayload('studio-verify', job, {
|
|
2689
2864
|
stageName: 'verify',
|
|
2690
|
-
event: verifyEvent
|
|
2865
|
+
event: verifyEvent,
|
|
2866
|
+
projectPath,
|
|
2867
|
+
fileSystem
|
|
2691
2868
|
});
|
|
2692
2869
|
printStudioPayload(payload, options);
|
|
2693
2870
|
return payload;
|
|
@@ -2894,9 +3071,11 @@ async function runStudioReleaseCommand(options = {}, dependencies = {}) {
|
|
|
2894
3071
|
}, fileSystem);
|
|
2895
3072
|
await writeLatestJob(paths, jobId, fileSystem);
|
|
2896
3073
|
|
|
2897
|
-
const payload = buildCommandPayload('studio-release', job, {
|
|
3074
|
+
const payload = await buildCommandPayload('studio-release', job, {
|
|
2898
3075
|
stageName: 'release',
|
|
2899
|
-
event: releaseEvent
|
|
3076
|
+
event: releaseEvent,
|
|
3077
|
+
projectPath,
|
|
3078
|
+
fileSystem
|
|
2900
3079
|
});
|
|
2901
3080
|
printStudioPayload(payload, options);
|
|
2902
3081
|
return payload;
|
|
@@ -2916,8 +3095,10 @@ async function runStudioResumeCommand(options = {}, dependencies = {}) {
|
|
|
2916
3095
|
|
|
2917
3096
|
const job = await loadJob(paths, jobId, fileSystem);
|
|
2918
3097
|
const events = await readStudioEvents(paths, jobId, { limit: 20 }, fileSystem);
|
|
2919
|
-
const payload = buildCommandPayload('studio-resume', job, {
|
|
2920
|
-
events
|
|
3098
|
+
const payload = await buildCommandPayload('studio-resume', job, {
|
|
3099
|
+
events,
|
|
3100
|
+
projectPath,
|
|
3101
|
+
fileSystem
|
|
2921
3102
|
});
|
|
2922
3103
|
payload.success = true;
|
|
2923
3104
|
printStudioPayload(payload, options);
|
|
@@ -2975,9 +3156,11 @@ async function runStudioRollbackCommand(options = {}, dependencies = {}) {
|
|
|
2975
3156
|
}, fileSystem);
|
|
2976
3157
|
await writeLatestJob(paths, jobId, fileSystem);
|
|
2977
3158
|
|
|
2978
|
-
const payload = buildCommandPayload('studio-rollback', job, {
|
|
3159
|
+
const payload = await buildCommandPayload('studio-rollback', job, {
|
|
2979
3160
|
stageName: 'rollback',
|
|
2980
|
-
event: rollbackEvent
|
|
3161
|
+
event: rollbackEvent,
|
|
3162
|
+
projectPath,
|
|
3163
|
+
fileSystem
|
|
2981
3164
|
});
|
|
2982
3165
|
payload.rollback = { ...job.rollback };
|
|
2983
3166
|
printStudioPayload(payload, options);
|
|
@@ -3035,7 +3218,11 @@ async function runStudioEventsCommand(options = {}, dependencies = {}) {
|
|
|
3035
3218
|
sourceStream = 'openhands';
|
|
3036
3219
|
}
|
|
3037
3220
|
|
|
3038
|
-
const payload = buildCommandPayload('studio-events', job, {
|
|
3221
|
+
const payload = await buildCommandPayload('studio-events', job, {
|
|
3222
|
+
events,
|
|
3223
|
+
projectPath,
|
|
3224
|
+
fileSystem
|
|
3225
|
+
});
|
|
3039
3226
|
payload.limit = limit;
|
|
3040
3227
|
payload.source_stream = sourceStream;
|
|
3041
3228
|
if (sourceStream === 'openhands') {
|