shraga 0.1.79 → 0.1.80
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shraga",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.80",
|
|
4
4
|
"description": "The teammate you delegate coding to — a self-hostable, multi-user AI coding agent web UI (Claude Code, with a pluggable engine seam).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -208,7 +208,7 @@ export async function runSchedule(
|
|
|
208
208
|
// Tell the run how to report its own truthful outcome (scheduler/outcome.ts). Prompt tasks only:
|
|
209
209
|
// a `bash` task's permission handler allows nothing but the task's own command, so such a run
|
|
210
210
|
// could not write the file even if it wanted to — its exit code is already the truth there.
|
|
211
|
-
if (task.kind === 'prompt') {
|
|
211
|
+
if ((task.kind ?? 'prompt') === 'prompt') {
|
|
212
212
|
// Cleared on RESUME too: a resume reuses the interrupted run's session id, so a declaration left
|
|
213
213
|
// by the attempt that crashed would be adopted as this attempt's verdict. The contract is
|
|
214
214
|
// re-stated for the same reason — the resumed turn must be able to declare for itself.
|
|
@@ -401,7 +401,7 @@ export async function runSchedule(
|
|
|
401
401
|
// The run's OWN verdict beats "the turn returned" — see scheduler/outcome.ts. Deliberately after
|
|
402
402
|
// the finally: the session lock is released by now, so a run that declared `pending` can be closed
|
|
403
403
|
// by a later turn in this session (a background job's wake, a follow-up message) while we wait.
|
|
404
|
-
if (status === 'ok' && task.kind === 'prompt') {
|
|
404
|
+
if (status === 'ok' && (task.kind ?? 'prompt') === 'prompt') {
|
|
405
405
|
const declared = await resolveDeclaredOutcome(sessionId, abortController, schedule.id);
|
|
406
406
|
if (declared) {
|
|
407
407
|
status = declared.status;
|
|
@@ -27,11 +27,28 @@ export function saveThrottleState(state: Record<string, number>): void {
|
|
|
27
27
|
renameSync(tmp, THROTTLE_FILE);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Schedules persisted before `task.kind` existed carry only the payload fields. Everything
|
|
32
|
+
* downstream branches on the discriminant, so infer it from the shape once, on load — a task
|
|
33
|
+
* missing its kind silently skipped the outcome contract and reported every run as `ok`.
|
|
34
|
+
* Only `prompt` is inferable: `bash` and `job` are both `{ command }`, and guessing between them
|
|
35
|
+
* would hand a run the wrong permission handler, so a kindless command task is left alone.
|
|
36
|
+
*/
|
|
37
|
+
function normalizeTask(task: Record<string, unknown>): void {
|
|
38
|
+
if (task.kind) return;
|
|
39
|
+
if (typeof task.prompt === 'string' || typeof task.promptFile === 'string') task.kind = 'prompt';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function normalizeSchedule(s: Schedule): Schedule {
|
|
43
|
+
if (s.task && typeof s.task === 'object') normalizeTask(s.task as unknown as Record<string, unknown>);
|
|
44
|
+
return s;
|
|
45
|
+
}
|
|
46
|
+
|
|
30
47
|
export function loadSchedules(): Schedule[] {
|
|
31
48
|
if (!existsSync(FILE)) return [];
|
|
32
49
|
try {
|
|
33
50
|
const parsed = JSON.parse(readFileSync(FILE, 'utf-8'));
|
|
34
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
51
|
+
return Array.isArray(parsed) ? parsed.map((s) => normalizeSchedule(s as Schedule)) : [];
|
|
35
52
|
} catch (err) {
|
|
36
53
|
console.error('[scheduler] failed to parse schedules.json:', err);
|
|
37
54
|
return [];
|