@worca/ui 0.15.2 → 0.15.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/package.json +1 -1
- package/server/process-manager.js +32 -3
- package/server/project-routes.js +14 -2
package/package.json
CHANGED
|
@@ -422,10 +422,39 @@ export class ProcessManager {
|
|
|
422
422
|
if (opts.resume) {
|
|
423
423
|
args.push('--resume');
|
|
424
424
|
if (opts.runId) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
425
|
+
// The runner derives worca_dir from os.path.dirname(status_path) and
|
|
426
|
+
// builds the per-run dir as <worca_dir>/runs/<run_id>/. We must pass
|
|
427
|
+
// the worca root, not the per-run dir — passing <worca>/runs/<id>
|
|
428
|
+
// would make the runner compute a nested <worca>/runs/<id>/runs/<id>/
|
|
429
|
+
// and write status updates there while the UI keeps reading the
|
|
430
|
+
// original. _find_active_runs(worca_root) then locates the run.
|
|
431
|
+
const statusDir = resumeCtx ? resumeCtx.worcaDir : this.worcaDir;
|
|
428
432
|
args.push('--status-dir', statusDir);
|
|
433
|
+
|
|
434
|
+
// _find_active_runs filters out runs whose pipeline_status is in
|
|
435
|
+
// {completed, interrupted}. To resume an interrupted/failed run, flip
|
|
436
|
+
// the top-level status to "resuming" so the runner can pick it up;
|
|
437
|
+
// it'll transition to "running" once it's processing.
|
|
438
|
+
const statusPath = resumeCtx
|
|
439
|
+
? join(resumeCtx.runDir, 'status.json')
|
|
440
|
+
: join(this.worcaDir, 'runs', opts.runId, 'status.json');
|
|
441
|
+
try {
|
|
442
|
+
const s = JSON.parse(readFileSync(statusPath, 'utf8'));
|
|
443
|
+
if (
|
|
444
|
+
s.pipeline_status === 'interrupted' ||
|
|
445
|
+
s.pipeline_status === 'failed'
|
|
446
|
+
) {
|
|
447
|
+
s.pipeline_status = 'resuming';
|
|
448
|
+
delete s.stop_reason;
|
|
449
|
+
writeFileSync(
|
|
450
|
+
statusPath,
|
|
451
|
+
`${JSON.stringify(s, null, 2)}\n`,
|
|
452
|
+
'utf8',
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
} catch {
|
|
456
|
+
/* non-fatal — runner will surface a clearer error if the file is missing */
|
|
457
|
+
}
|
|
429
458
|
}
|
|
430
459
|
} else if (opts.sourceType !== undefined) {
|
|
431
460
|
// New format: separate source and prompt args
|
package/server/project-routes.js
CHANGED
|
@@ -935,7 +935,14 @@ export function createProjectScopedRoutes({
|
|
|
935
935
|
}
|
|
936
936
|
const { worcaDir, settingsPath } = req.project;
|
|
937
937
|
try {
|
|
938
|
-
|
|
938
|
+
// Worktree runs read control.json from <worktree>/.worca/runs/<id>/.
|
|
939
|
+
// Writing it to the parent project's worcaDir leaves the runner
|
|
940
|
+
// unaware of the stop request — SIGTERM still works, but we lose
|
|
941
|
+
// graceful-shutdown semantics.
|
|
942
|
+
const overlay = readPipelineOverlay(worcaDir, runId);
|
|
943
|
+
const controlDir = overlay?.worktree_path
|
|
944
|
+
? join(overlay.worktree_path, '.worca', 'runs', runId)
|
|
945
|
+
: join(worcaDir, 'runs', runId);
|
|
939
946
|
mkdirSync(controlDir, { recursive: true });
|
|
940
947
|
writeFileSync(
|
|
941
948
|
join(controlDir, 'control.json'),
|
|
@@ -1141,7 +1148,12 @@ export function createProjectScopedRoutes({
|
|
|
1141
1148
|
pipeline_status: st.pipeline_status,
|
|
1142
1149
|
});
|
|
1143
1150
|
}
|
|
1144
|
-
|
|
1151
|
+
// Worktree runs read control.json from <worktree>/.worca/runs/<id>/;
|
|
1152
|
+
// writing to the parent's worcaDir is invisible to the runner.
|
|
1153
|
+
const overlay = readPipelineOverlay(worcaDir, runId);
|
|
1154
|
+
const controlDir = overlay?.worktree_path
|
|
1155
|
+
? join(overlay.worktree_path, '.worca', 'runs', runId)
|
|
1156
|
+
: join(worcaDir, 'runs', runId);
|
|
1145
1157
|
mkdirSync(controlDir, { recursive: true });
|
|
1146
1158
|
writeFileSync(
|
|
1147
1159
|
join(controlDir, 'control.json'),
|