shreni 0.1.0
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/ARCHITECTURE.md +260 -0
- package/LICENSE +201 -0
- package/README.md +519 -0
- package/TRADEMARK.md +97 -0
- package/dist/agents/parikshaka.d.ts +11 -0
- package/dist/agents/parikshaka.d.ts.map +1 -0
- package/dist/agents/parikshaka.js +80 -0
- package/dist/agents/parikshaka.js.map +1 -0
- package/dist/agents/providers/claude.d.ts +3 -0
- package/dist/agents/providers/claude.d.ts.map +1 -0
- package/dist/agents/providers/claude.js +100 -0
- package/dist/agents/providers/claude.js.map +1 -0
- package/dist/agents/providers/codex.d.ts +3 -0
- package/dist/agents/providers/codex.d.ts.map +1 -0
- package/dist/agents/providers/codex.js +123 -0
- package/dist/agents/providers/codex.js.map +1 -0
- package/dist/agents/providers/gemini.d.ts +3 -0
- package/dist/agents/providers/gemini.d.ts.map +1 -0
- package/dist/agents/providers/gemini.js +77 -0
- package/dist/agents/providers/gemini.js.map +1 -0
- package/dist/agents/providers/index.d.ts +6 -0
- package/dist/agents/providers/index.d.ts.map +1 -0
- package/dist/agents/providers/index.js +35 -0
- package/dist/agents/providers/index.js.map +1 -0
- package/dist/agents/providers/registry.d.ts +20 -0
- package/dist/agents/providers/registry.d.ts.map +1 -0
- package/dist/agents/providers/registry.js +91 -0
- package/dist/agents/providers/registry.js.map +1 -0
- package/dist/agents/providers/types.d.ts +42 -0
- package/dist/agents/providers/types.d.ts.map +1 -0
- package/dist/agents/providers/types.js +61 -0
- package/dist/agents/providers/types.js.map +1 -0
- package/dist/agents/runner.d.ts +6 -0
- package/dist/agents/runner.d.ts.map +1 -0
- package/dist/agents/runner.js +159 -0
- package/dist/agents/runner.js.map +1 -0
- package/dist/agents/silpi.d.ts +3 -0
- package/dist/agents/silpi.d.ts.map +1 -0
- package/dist/agents/silpi.js +101 -0
- package/dist/agents/silpi.js.map +1 -0
- package/dist/agents/viharapala.d.ts +5 -0
- package/dist/agents/viharapala.d.ts.map +1 -0
- package/dist/agents/viharapala.js +128 -0
- package/dist/agents/viharapala.js.map +1 -0
- package/dist/cli/agents.d.ts +14 -0
- package/dist/cli/agents.d.ts.map +1 -0
- package/dist/cli/agents.js +47 -0
- package/dist/cli/agents.js.map +1 -0
- package/dist/cli/detect-toolchain.d.ts +10 -0
- package/dist/cli/detect-toolchain.d.ts.map +1 -0
- package/dist/cli/detect-toolchain.js +77 -0
- package/dist/cli/detect-toolchain.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +342 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-kshetra.d.ts +59 -0
- package/dist/cli/init-kshetra.d.ts.map +1 -0
- package/dist/cli/init-kshetra.js +531 -0
- package/dist/cli/init-kshetra.js.map +1 -0
- package/dist/cli/list.d.ts +11 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +45 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/logs.d.ts +20 -0
- package/dist/cli/logs.d.ts.map +1 -0
- package/dist/cli/logs.js +144 -0
- package/dist/cli/logs.js.map +1 -0
- package/dist/cli/migrate.d.ts +8 -0
- package/dist/cli/migrate.d.ts.map +1 -0
- package/dist/cli/migrate.js +116 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/pause.d.ts +24 -0
- package/dist/cli/pause.d.ts.map +1 -0
- package/dist/cli/pause.js +41 -0
- package/dist/cli/pause.js.map +1 -0
- package/dist/cli/phalaka-autostart.d.ts +11 -0
- package/dist/cli/phalaka-autostart.d.ts.map +1 -0
- package/dist/cli/phalaka-autostart.js +28 -0
- package/dist/cli/phalaka-autostart.js.map +1 -0
- package/dist/cli/phalaka-server.d.ts +2 -0
- package/dist/cli/phalaka-server.d.ts.map +1 -0
- package/dist/cli/phalaka-server.js +20 -0
- package/dist/cli/phalaka-server.js.map +1 -0
- package/dist/cli/phalaka.d.ts +30 -0
- package/dist/cli/phalaka.d.ts.map +1 -0
- package/dist/cli/phalaka.js +60 -0
- package/dist/cli/phalaka.js.map +1 -0
- package/dist/cli/pid.d.ts +9 -0
- package/dist/cli/pid.d.ts.map +1 -0
- package/dist/cli/pid.js +66 -0
- package/dist/cli/pid.js.map +1 -0
- package/dist/cli/provider-preflight.d.ts +11 -0
- package/dist/cli/provider-preflight.d.ts.map +1 -0
- package/dist/cli/provider-preflight.js +70 -0
- package/dist/cli/provider-preflight.js.map +1 -0
- package/dist/cli/register.d.ts +8 -0
- package/dist/cli/register.d.ts.map +1 -0
- package/dist/cli/register.js +34 -0
- package/dist/cli/register.js.map +1 -0
- package/dist/cli/run.d.ts +3 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +40 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/start.d.ts +11 -0
- package/dist/cli/start.d.ts.map +1 -0
- package/dist/cli/start.js +26 -0
- package/dist/cli/start.js.map +1 -0
- package/dist/cli/status.d.ts +39 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +207 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/stop.d.ts +13 -0
- package/dist/cli/stop.d.ts.map +1 -0
- package/dist/cli/stop.js +18 -0
- package/dist/cli/stop.js.map +1 -0
- package/dist/cli/sync.d.ts +6 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +31 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli/tail.d.ts +6 -0
- package/dist/cli/tail.d.ts.map +1 -0
- package/dist/cli/tail.js +170 -0
- package/dist/cli/tail.js.map +1 -0
- package/dist/cli/telemetry.d.ts +2 -0
- package/dist/cli/telemetry.d.ts.map +1 -0
- package/dist/cli/telemetry.js +42 -0
- package/dist/cli/telemetry.js.map +1 -0
- package/dist/cli/verify-hooks.d.ts +12 -0
- package/dist/cli/verify-hooks.d.ts.map +1 -0
- package/dist/cli/verify-hooks.js +38 -0
- package/dist/cli/verify-hooks.js.map +1 -0
- package/dist/cli/worker.d.ts +2 -0
- package/dist/cli/worker.d.ts.map +1 -0
- package/dist/cli/worker.js +211 -0
- package/dist/cli/worker.js.map +1 -0
- package/dist/kshetra/config.d.ts +64 -0
- package/dist/kshetra/config.d.ts.map +1 -0
- package/dist/kshetra/config.js +173 -0
- package/dist/kshetra/config.js.map +1 -0
- package/dist/kshetra/registry.d.ts +5 -0
- package/dist/kshetra/registry.d.ts.map +1 -0
- package/dist/kshetra/registry.js +69 -0
- package/dist/kshetra/registry.js.map +1 -0
- package/dist/kshetra/state.d.ts +57 -0
- package/dist/kshetra/state.d.ts.map +1 -0
- package/dist/kshetra/state.js +195 -0
- package/dist/kshetra/state.js.map +1 -0
- package/dist/kshetra/toolchain.d.ts +20 -0
- package/dist/kshetra/toolchain.d.ts.map +1 -0
- package/dist/kshetra/toolchain.js +146 -0
- package/dist/kshetra/toolchain.js.map +1 -0
- package/dist/phalaka/api.d.ts +123 -0
- package/dist/phalaka/api.d.ts.map +1 -0
- package/dist/phalaka/api.js +196 -0
- package/dist/phalaka/api.js.map +1 -0
- package/dist/phalaka/beads-read.d.ts +49 -0
- package/dist/phalaka/beads-read.d.ts.map +1 -0
- package/dist/phalaka/beads-read.js +174 -0
- package/dist/phalaka/beads-read.js.map +1 -0
- package/dist/phalaka/pid.d.ts +6 -0
- package/dist/phalaka/pid.d.ts.map +1 -0
- package/dist/phalaka/pid.js +48 -0
- package/dist/phalaka/pid.js.map +1 -0
- package/dist/phalaka/server.d.ts +10 -0
- package/dist/phalaka/server.d.ts.map +1 -0
- package/dist/phalaka/server.js +30 -0
- package/dist/phalaka/server.js.map +1 -0
- package/dist/phalaka/token.d.ts +5 -0
- package/dist/phalaka/token.d.ts.map +1 -0
- package/dist/phalaka/token.js +40 -0
- package/dist/phalaka/token.js.map +1 -0
- package/dist/phalaka/ui.d.ts +15 -0
- package/dist/phalaka/ui.d.ts.map +1 -0
- package/dist/phalaka/ui.js +233 -0
- package/dist/phalaka/ui.js.map +1 -0
- package/dist/sthapathi/activity-log.d.ts +68 -0
- package/dist/sthapathi/activity-log.d.ts.map +1 -0
- package/dist/sthapathi/activity-log.js +57 -0
- package/dist/sthapathi/activity-log.js.map +1 -0
- package/dist/sthapathi/beads.d.ts +27 -0
- package/dist/sthapathi/beads.d.ts.map +1 -0
- package/dist/sthapathi/beads.js +153 -0
- package/dist/sthapathi/beads.js.map +1 -0
- package/dist/sthapathi/branch.d.ts +5 -0
- package/dist/sthapathi/branch.d.ts.map +1 -0
- package/dist/sthapathi/branch.js +20 -0
- package/dist/sthapathi/branch.js.map +1 -0
- package/dist/sthapathi/dispatch.d.ts +14 -0
- package/dist/sthapathi/dispatch.d.ts.map +1 -0
- package/dist/sthapathi/dispatch.js +326 -0
- package/dist/sthapathi/dispatch.js.map +1 -0
- package/dist/sthapathi/errors.d.ts +27 -0
- package/dist/sthapathi/errors.d.ts.map +1 -0
- package/dist/sthapathi/errors.js +174 -0
- package/dist/sthapathi/errors.js.map +1 -0
- package/dist/sthapathi/gh.d.ts +19 -0
- package/dist/sthapathi/gh.d.ts.map +1 -0
- package/dist/sthapathi/gh.js +69 -0
- package/dist/sthapathi/gh.js.map +1 -0
- package/dist/sthapathi/git.d.ts +41 -0
- package/dist/sthapathi/git.d.ts.map +1 -0
- package/dist/sthapathi/git.js +199 -0
- package/dist/sthapathi/git.js.map +1 -0
- package/dist/sthapathi/guard.d.ts +24 -0
- package/dist/sthapathi/guard.d.ts.map +1 -0
- package/dist/sthapathi/guard.js +64 -0
- package/dist/sthapathi/guard.js.map +1 -0
- package/dist/sthapathi/health.d.ts +23 -0
- package/dist/sthapathi/health.d.ts.map +1 -0
- package/dist/sthapathi/health.js +142 -0
- package/dist/sthapathi/health.js.map +1 -0
- package/dist/sthapathi/index.d.ts +21 -0
- package/dist/sthapathi/index.d.ts.map +1 -0
- package/dist/sthapathi/index.js +88 -0
- package/dist/sthapathi/index.js.map +1 -0
- package/dist/sthapathi/lifecycle.d.ts +7 -0
- package/dist/sthapathi/lifecycle.d.ts.map +1 -0
- package/dist/sthapathi/lifecycle.js +43 -0
- package/dist/sthapathi/lifecycle.js.map +1 -0
- package/dist/sthapathi/lint.d.ts +8 -0
- package/dist/sthapathi/lint.d.ts.map +1 -0
- package/dist/sthapathi/lint.js +33 -0
- package/dist/sthapathi/lint.js.map +1 -0
- package/dist/sthapathi/merge.d.ts +18 -0
- package/dist/sthapathi/merge.d.ts.map +1 -0
- package/dist/sthapathi/merge.js +259 -0
- package/dist/sthapathi/merge.js.map +1 -0
- package/dist/sthapathi/notifications.d.ts +14 -0
- package/dist/sthapathi/notifications.d.ts.map +1 -0
- package/dist/sthapathi/notifications.js +57 -0
- package/dist/sthapathi/notifications.js.map +1 -0
- package/dist/sthapathi/parikshaka-dispatch.d.ts +12 -0
- package/dist/sthapathi/parikshaka-dispatch.d.ts.map +1 -0
- package/dist/sthapathi/parikshaka-dispatch.js +0 -0
- package/dist/sthapathi/parikshaka-dispatch.js.map +1 -0
- package/dist/sthapathi/pickup.d.ts +13 -0
- package/dist/sthapathi/pickup.d.ts.map +1 -0
- package/dist/sthapathi/pickup.js +144 -0
- package/dist/sthapathi/pickup.js.map +1 -0
- package/dist/sthapathi/recover.d.ts +16 -0
- package/dist/sthapathi/recover.d.ts.map +1 -0
- package/dist/sthapathi/recover.js +149 -0
- package/dist/sthapathi/recover.js.map +1 -0
- package/dist/sthapathi/retry.d.ts +11 -0
- package/dist/sthapathi/retry.d.ts.map +1 -0
- package/dist/sthapathi/retry.js +42 -0
- package/dist/sthapathi/retry.js.map +1 -0
- package/dist/sthapathi/self-heal.d.ts +19 -0
- package/dist/sthapathi/self-heal.d.ts.map +1 -0
- package/dist/sthapathi/self-heal.js +46 -0
- package/dist/sthapathi/self-heal.js.map +1 -0
- package/dist/sthapathi/types.d.ts +56 -0
- package/dist/sthapathi/types.d.ts.map +1 -0
- package/dist/sthapathi/types.js +4 -0
- package/dist/sthapathi/types.js.map +1 -0
- package/dist/sthapathi/watchdog.d.ts +27 -0
- package/dist/sthapathi/watchdog.d.ts.map +1 -0
- package/dist/sthapathi/watchdog.js +145 -0
- package/dist/sthapathi/watchdog.js.map +1 -0
- package/dist/telemetry/telemetry.d.ts +42 -0
- package/dist/telemetry/telemetry.d.ts.map +1 -0
- package/dist/telemetry/telemetry.js +189 -0
- package/dist/telemetry/telemetry.js.map +1 -0
- package/dist/test-setup.d.ts +2 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +16 -0
- package/dist/test-setup.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { KshetraConfig } from '../kshetra/config.js';
|
|
2
|
+
import type { Task } from './types.js';
|
|
3
|
+
export declare class PreFlightError extends Error {
|
|
4
|
+
readonly task: Task;
|
|
5
|
+
constructor(task: Task, message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare function toSlug(title: string): string;
|
|
8
|
+
export declare function parseReadyOutput(raw: string): Task[];
|
|
9
|
+
export declare function pickNext(tasks: Task[]): Task | null;
|
|
10
|
+
export declare function preFlightCheck(task: Task, kshetra: KshetraConfig): Promise<void>;
|
|
11
|
+
export declare function selectNext(kshetra: KshetraConfig): Promise<Task | null>;
|
|
12
|
+
export declare function prepareTask(task: Task, kshetra: KshetraConfig): Promise<Task | null>;
|
|
13
|
+
//# sourceMappingURL=pickup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickup.d.ts","sourceRoot":"","sources":["../../src/sthapathi/pickup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAMvC,qBAAa,cAAe,SAAQ,KAAK;aAErB,IAAI,EAAE,IAAI;gBAAV,IAAI,EAAE,IAAI,EAC1B,OAAO,EAAE,MAAM;CAKlB;AAcD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,CAwBpD;AAGD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAInD;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBtF;AAOD,wBAAsB,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAG7E;AAMD,wBAAsB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAyC1F"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PreFlightError = void 0;
|
|
4
|
+
exports.toSlug = toSlug;
|
|
5
|
+
exports.parseReadyOutput = parseReadyOutput;
|
|
6
|
+
exports.pickNext = pickNext;
|
|
7
|
+
exports.preFlightCheck = preFlightCheck;
|
|
8
|
+
exports.selectNext = selectNext;
|
|
9
|
+
exports.prepareTask = prepareTask;
|
|
10
|
+
const zod_1 = require("zod");
|
|
11
|
+
const beads_js_1 = require("./beads.js");
|
|
12
|
+
const git_js_1 = require("./git.js");
|
|
13
|
+
const health_js_1 = require("./health.js");
|
|
14
|
+
const state_js_1 = require("../kshetra/state.js");
|
|
15
|
+
class PreFlightError extends Error {
|
|
16
|
+
task;
|
|
17
|
+
constructor(task, message) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.task = task;
|
|
20
|
+
this.name = 'PreFlightError';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.PreFlightError = PreFlightError;
|
|
24
|
+
const BeadsIssueSchema = zod_1.z.object({
|
|
25
|
+
id: zod_1.z.string(),
|
|
26
|
+
title: zod_1.z.string(),
|
|
27
|
+
priority: zod_1.z.number().int().min(0).max(4),
|
|
28
|
+
status: zod_1.z.string(),
|
|
29
|
+
description: zod_1.z.string().optional(),
|
|
30
|
+
notes: zod_1.z.string().optional(),
|
|
31
|
+
});
|
|
32
|
+
// Deterministic slug from a bead title — the same function that names bead
|
|
33
|
+
// branches at creation, exported so reconcilePullRequests can reconstruct a
|
|
34
|
+
// bead's branch name from its title (bd list --json carries no slug field).
|
|
35
|
+
function toSlug(title) {
|
|
36
|
+
return title
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
39
|
+
.replace(/^-+|-+$/g, '')
|
|
40
|
+
.slice(0, 50);
|
|
41
|
+
}
|
|
42
|
+
function parseReadyOutput(raw) {
|
|
43
|
+
let parsed;
|
|
44
|
+
try {
|
|
45
|
+
parsed = JSON.parse(raw);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
if (!Array.isArray(parsed))
|
|
51
|
+
return [];
|
|
52
|
+
const tasks = [];
|
|
53
|
+
for (const item of parsed) {
|
|
54
|
+
const result = BeadsIssueSchema.safeParse(item);
|
|
55
|
+
if (!result.success)
|
|
56
|
+
continue;
|
|
57
|
+
const r = result.data;
|
|
58
|
+
tasks.push({
|
|
59
|
+
id: r.id,
|
|
60
|
+
slug: toSlug(r.title),
|
|
61
|
+
title: r.title,
|
|
62
|
+
description: r.description,
|
|
63
|
+
status: 'pending',
|
|
64
|
+
priority: r.priority,
|
|
65
|
+
notes: r.notes,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return tasks;
|
|
69
|
+
}
|
|
70
|
+
// Stable sort: P0 first, then preserve arrival order (FIFO) within same priority
|
|
71
|
+
function pickNext(tasks) {
|
|
72
|
+
if (tasks.length === 0)
|
|
73
|
+
return null;
|
|
74
|
+
const sorted = tasks.slice().sort((a, b) => a.priority - b.priority);
|
|
75
|
+
return sorted[0] ?? null;
|
|
76
|
+
}
|
|
77
|
+
async function preFlightCheck(task, kshetra) {
|
|
78
|
+
const g = (0, git_js_1.git)(kshetra);
|
|
79
|
+
const main = kshetra.repo.mainBranch;
|
|
80
|
+
await g.checkout(main);
|
|
81
|
+
const status = await g.status();
|
|
82
|
+
const dirty = [...status.modified, ...status.staged];
|
|
83
|
+
if (dirty.length > 0) {
|
|
84
|
+
throw new PreFlightError(task, `dirty working tree: ${dirty.join(', ')}`);
|
|
85
|
+
}
|
|
86
|
+
await g.pull('--rebase', 'origin', main);
|
|
87
|
+
const branch = `bead-${task.id}/${task.slug}`;
|
|
88
|
+
if (await g.branchExists(branch)) {
|
|
89
|
+
throw new PreFlightError(task, `branch already exists: ${branch}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// SELECT (read-only). Picks the highest-priority ready bead. Performs NO git ops
|
|
93
|
+
// and NO claim, so it is safe to call on every poll — the scheduler only commits
|
|
94
|
+
// to mutating the work tree once it advances a selected task into PREPARE. This
|
|
95
|
+
// separation is what stops a poll from checking out main under an in-flight agent
|
|
96
|
+
// (see the Sthapathi workflow design §4.2).
|
|
97
|
+
async function selectNext(kshetra) {
|
|
98
|
+
const raw = await (0, beads_js_1.bd)(kshetra).ready();
|
|
99
|
+
return pickNext(parseReadyOutput(raw));
|
|
100
|
+
}
|
|
101
|
+
// PREPARE (the ONLY mutator in the pickup path) + bd claim. Syncs beads, runs
|
|
102
|
+
// preFlightCheck (checkout main, pull, branch guard) and the health gate, then
|
|
103
|
+
// claims. Returns the task when it is ready to work, or null when preflight
|
|
104
|
+
// rejects or the base suite is red — both logged, so a wedge is never silent.
|
|
105
|
+
async function prepareTask(task, kshetra) {
|
|
106
|
+
await (0, beads_js_1.syncBeads)(kshetra);
|
|
107
|
+
try {
|
|
108
|
+
await preFlightCheck(task, kshetra);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
if (err instanceof PreFlightError) {
|
|
112
|
+
// Surface the rejection — otherwise a leftover branch or persistently
|
|
113
|
+
// dirty tree wedges the worker silently, returning null on every poll
|
|
114
|
+
// with no clue why nothing is progressing. Record the stall so the
|
|
115
|
+
// watchdog trips if the same rejection repeats.
|
|
116
|
+
(0, state_js_1.recordStall)(kshetra, `preflight: ${err.message}`);
|
|
117
|
+
console.warn(`[shreni prepare:${kshetra.id}] preflight rejected ${task.id}: ${err.message}`);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
// Health gate: a fresh feature task only starts when the base suite is green
|
|
123
|
+
// (modulo the accepted baseline). preFlightCheck has put us on a clean, pulled
|
|
124
|
+
// main, so this measures the right tree. A red base does not start the task —
|
|
125
|
+
// it queues a P0 repair bead instead, which is exempt from this gate. This
|
|
126
|
+
// runs at the prepare boundary only, never mid-loop, so it can't interfere with
|
|
127
|
+
// an in-flight Silpi↔Viharapala round.
|
|
128
|
+
if (!(0, health_js_1.isHealthBead)(task)) {
|
|
129
|
+
const health = await (0, health_js_1.checkHealth)(kshetra);
|
|
130
|
+
if (!health.green) {
|
|
131
|
+
const created = await (0, health_js_1.ensureHealthBead)(kshetra, health.failCount);
|
|
132
|
+
(0, state_js_1.recordStall)(kshetra, 'base suite red');
|
|
133
|
+
console.warn(`[shreni prepare:${kshetra.id}] base suite red ` +
|
|
134
|
+
`(${health.failCount} failing > baseline ${health.baseline}); ` +
|
|
135
|
+
`deferring ${task.id}, ${created ? 'queued' : 'awaiting'} health repair`);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
await (0, beads_js_1.bd)(kshetra).claim(task.id);
|
|
140
|
+
// Forward progress: a bead was successfully claimed — clear any stall counter.
|
|
141
|
+
(0, state_js_1.recordProgress)(kshetra);
|
|
142
|
+
return task;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=pickup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pickup.js","sourceRoot":"","sources":["../../src/sthapathi/pickup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { KshetraConfig } from '../kshetra/config.js';
|
|
2
|
+
import type { Task } from './types.js';
|
|
3
|
+
export type ResumeRunner = (kshetra: KshetraConfig, task: Task, branch: string) => Promise<{
|
|
4
|
+
approved: boolean;
|
|
5
|
+
note: string;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const MAX_RECOVER_ATTEMPTS = 3;
|
|
8
|
+
export declare function parseInFlightTasks(raw: string): Task[];
|
|
9
|
+
export declare function recoverKshetra(kshetra: KshetraConfig, opts?: {
|
|
10
|
+
keepBranch?: string;
|
|
11
|
+
}): Promise<Task[]>;
|
|
12
|
+
export declare function scheduleResume(kshetra: KshetraConfig, task: Task, run?: ResumeRunner): Promise<{
|
|
13
|
+
approved: boolean;
|
|
14
|
+
note: string;
|
|
15
|
+
}>;
|
|
16
|
+
//# sourceMappingURL=recover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recover.d.ts","sourceRoot":"","sources":["../../src/sthapathi/recover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAQvC,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,KACX,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAKlD,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,CAsBtD;AASD,wBAAsB,cAAc,CAClC,OAAO,EAAE,aAAa,EACtB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,EAAE,CAAC,CAsDjB;AAgBD,wBAAsB,cAAc,CAClC,OAAO,EAAE,aAAa,EACtB,IAAI,EAAE,IAAI,EACV,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAS9C"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.MAX_RECOVER_ATTEMPTS = void 0;
|
|
37
|
+
exports.parseInFlightTasks = parseInFlightTasks;
|
|
38
|
+
exports.recoverKshetra = recoverKshetra;
|
|
39
|
+
exports.scheduleResume = scheduleResume;
|
|
40
|
+
const beads_js_1 = require("./beads.js");
|
|
41
|
+
const git_js_1 = require("./git.js");
|
|
42
|
+
const branch_js_1 = require("./branch.js");
|
|
43
|
+
const state_js_1 = require("../kshetra/state.js");
|
|
44
|
+
// A bead is reopened after a crash/restart at most this many times before it is
|
|
45
|
+
// left blocked for a human. Prevents the reopen→fail→reopen loop. Default per
|
|
46
|
+
// the Sthapathi workflow design §4.5 (D1); made configurable later (bjo).
|
|
47
|
+
exports.MAX_RECOVER_ATTEMPTS = 3;
|
|
48
|
+
function parseInFlightTasks(raw) {
|
|
49
|
+
let parsed;
|
|
50
|
+
try {
|
|
51
|
+
parsed = JSON.parse(raw);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
if (!Array.isArray(parsed))
|
|
57
|
+
return [];
|
|
58
|
+
const tasks = [];
|
|
59
|
+
for (const item of parsed) {
|
|
60
|
+
if (typeof item.id !== 'string' || typeof item.title !== 'string')
|
|
61
|
+
continue;
|
|
62
|
+
tasks.push({
|
|
63
|
+
id: item.id,
|
|
64
|
+
slug: String(item.slug ?? item.id),
|
|
65
|
+
title: item.title,
|
|
66
|
+
status: 'in_progress',
|
|
67
|
+
priority: typeof item.priority === 'number' ? item.priority : 2,
|
|
68
|
+
round: typeof item.round === 'number' ? item.round : 1,
|
|
69
|
+
notes: typeof item.notes === 'string' ? item.notes : undefined,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return tasks;
|
|
73
|
+
}
|
|
74
|
+
// RECOVER — reconcile the four drifting truths (work tree, git branches, bead
|
|
75
|
+
// status, scheduler phase) back to a clean IDLE after a crash, restart, or a
|
|
76
|
+
// PREPARE that detected drift. We do NOT try to resume a half-done bead from the
|
|
77
|
+
// exact stage it died at (fragile); instead we discard the interrupted work and
|
|
78
|
+
// reopen the bead for a fresh cycle, under an attempt budget. This codifies the
|
|
79
|
+
// manual recovery captured in `bd remember [shreni-worker-recovery]`.
|
|
80
|
+
// See the Sthapathi workflow design §4.3.
|
|
81
|
+
async function recoverKshetra(kshetra, opts = {}) {
|
|
82
|
+
const g = (0, git_js_1.git)(kshetra);
|
|
83
|
+
const main = kshetra.repo.mainBranch;
|
|
84
|
+
// 1. Reset the work tree to a clean main — discard any interrupted, uncommitted
|
|
85
|
+
// work so the next PREPARE starts from a sanctioned point.
|
|
86
|
+
await g.resetHard();
|
|
87
|
+
await g.checkout(main);
|
|
88
|
+
await g.clean();
|
|
89
|
+
// 2. Drop stale bead-* branches. Nothing is active at startup; when invoked
|
|
90
|
+
// mid-run from PREPARE, opts.keepBranch protects the in-flight bead's branch.
|
|
91
|
+
// A leftover branch makes preFlightCheck reject its bead forever
|
|
92
|
+
// ("branch already exists").
|
|
93
|
+
for (const branch of await g.branches('bead-')) {
|
|
94
|
+
if (branch === opts.keepBranch)
|
|
95
|
+
continue;
|
|
96
|
+
await g.deleteBranch(branch, { force: true });
|
|
97
|
+
}
|
|
98
|
+
// 3. Reopen beads stranded in_progress by the interruption — under the attempt
|
|
99
|
+
// budget. Past MAX_RECOVER_ATTEMPTS, leave the bead blocked and escalate to
|
|
100
|
+
// a human rather than loop on it.
|
|
101
|
+
const maxAttempts = kshetra.watchdog?.maxRecoverAttempts ?? exports.MAX_RECOVER_ATTEMPTS;
|
|
102
|
+
// Exclude awaiting-merge beads (mergePolicy 'pr', 3r2): they are intentionally
|
|
103
|
+
// left in_progress with their branch/PR open, NOT stranded by a crash. Reopening
|
|
104
|
+
// and re-working one would discard an already-approved change that is just
|
|
105
|
+
// waiting on a human merge. reconcilePullRequests closes them when the PR lands.
|
|
106
|
+
const inFlight = parseInFlightTasks(await (0, beads_js_1.bd)(kshetra).list({ status: 'in_progress', excludeLabel: 'awaiting-merge' }));
|
|
107
|
+
const resumable = [];
|
|
108
|
+
for (const task of inFlight) {
|
|
109
|
+
const attempts = (0, state_js_1.recordBeadAttempt)(kshetra, task.id);
|
|
110
|
+
if (attempts > maxAttempts) {
|
|
111
|
+
await (0, beads_js_1.bd)(kshetra).flag(task.id, `Recover: exceeded ${maxAttempts} restart attempts — left blocked for human review.`);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
await (0, beads_js_1.bd)(kshetra).reopen(task.id);
|
|
115
|
+
await (0, beads_js_1.bd)(kshetra).addNote(task.id, `Recovered after restart (attempt ${attempts}/${maxAttempts}) — reopened for a fresh cycle.`);
|
|
116
|
+
resumable.push(task);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
await (0, beads_js_1.syncBeads)(kshetra);
|
|
120
|
+
// Hand the reopened beads back to the caller (the worker) so it can RESUME
|
|
121
|
+
// them via the work loop — bypassing the pickup health gate — instead of
|
|
122
|
+
// waiting for the next gated poll to re-select them. See scheduleResume.
|
|
123
|
+
return resumable;
|
|
124
|
+
}
|
|
125
|
+
// RESUME — re-enter the WORK phase for a bead that was already in flight, without
|
|
126
|
+
// going back through SELECT / PREPARE. Used for a bead reopened by RECOVER after a
|
|
127
|
+
// crash/restart (and, in future, the mid-loop merge-conflict re-dispatch).
|
|
128
|
+
//
|
|
129
|
+
// Resume deliberately does NOT run the pickup health gate (checkHealth). That gate
|
|
130
|
+
// is a pickup-only precondition that admits *new* feature work only onto a green
|
|
131
|
+
// base; it runs at the prepare boundary, never mid-loop. A bead that is already in
|
|
132
|
+
// flight was admitted when it was first picked up, so re-gating it on resume would
|
|
133
|
+
// (a) re-run the whole suite inside the work loop — exactly the mid-loop suite run
|
|
134
|
+
// the phase machine forbids (the jhl regression), and (b) let a base that went red
|
|
135
|
+
// *after* admission strand an otherwise-in-progress bead. runSilpiViharapalaLoop
|
|
136
|
+
// routes [shreni-health] beads to the repair loop internally, so this single
|
|
137
|
+
// entrypoint resumes both feature and repair work. See the Sthapathi workflow
|
|
138
|
+
// design §4.2: WIP resumes via the recovery path, bypassing the gate.
|
|
139
|
+
async function scheduleResume(kshetra, task, run) {
|
|
140
|
+
// Re-claim the reopened bead (RECOVER set it back to open). This is the only
|
|
141
|
+
// pickup-side step resume performs — no preFlightCheck, no checkHealth.
|
|
142
|
+
await (0, beads_js_1.bd)(kshetra).claim(task.id);
|
|
143
|
+
(0, state_js_1.recordProgress)(kshetra);
|
|
144
|
+
// Lazy-load the loop so recover.ts's static import graph (and its unit tests)
|
|
145
|
+
// never pull in the agent modules; production callers inject the runner.
|
|
146
|
+
const runTask = run ?? (await Promise.resolve().then(() => __importStar(require('./dispatch.js')))).runSilpiViharapalaLoop;
|
|
147
|
+
return runTask(kshetra, task, (0, branch_js_1.branchName)(task));
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=recover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recover.js","sourceRoot":"","sources":["../../src/sthapathi/recover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const AGENT_RETRY_CONFIG: {
|
|
2
|
+
maxAttempts: number;
|
|
3
|
+
initialDelayMs: number;
|
|
4
|
+
backoffMultiplier: number;
|
|
5
|
+
maxDelayMs: number;
|
|
6
|
+
retryableStatuses: number[];
|
|
7
|
+
retryableErrors: string[];
|
|
8
|
+
};
|
|
9
|
+
export type RetryConfig = typeof AGENT_RETRY_CONFIG;
|
|
10
|
+
export declare function withRetry<T>(label: string, fn: () => Promise<T>, config?: RetryConfig): Promise<T>;
|
|
11
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/sthapathi/retry.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB;;;;;;;CAO9B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,OAAO,kBAAkB,CAAC;AAapD,wBAAsB,SAAS,CAAC,CAAC,EAC/B,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,GAAE,WAAgC,GACvC,OAAO,CAAC,CAAC,CAAC,CAoBZ"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AGENT_RETRY_CONFIG = void 0;
|
|
4
|
+
exports.withRetry = withRetry;
|
|
5
|
+
exports.AGENT_RETRY_CONFIG = {
|
|
6
|
+
maxAttempts: 3,
|
|
7
|
+
initialDelayMs: 5_000,
|
|
8
|
+
backoffMultiplier: 2,
|
|
9
|
+
maxDelayMs: 60_000,
|
|
10
|
+
retryableStatuses: [429, 502, 503, 529],
|
|
11
|
+
retryableErrors: ['ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND'],
|
|
12
|
+
};
|
|
13
|
+
function sleep(ms) {
|
|
14
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
15
|
+
}
|
|
16
|
+
function isRetryable(err, config) {
|
|
17
|
+
const e = err;
|
|
18
|
+
if (e.status !== undefined && config.retryableStatuses.includes(e.status))
|
|
19
|
+
return true;
|
|
20
|
+
const msg = e.message ?? e.code ?? '';
|
|
21
|
+
return config.retryableErrors.some(code => msg.includes(code));
|
|
22
|
+
}
|
|
23
|
+
async function withRetry(label, fn, config = exports.AGENT_RETRY_CONFIG) {
|
|
24
|
+
let attempt = 0;
|
|
25
|
+
let delay = config.initialDelayMs;
|
|
26
|
+
while (attempt < config.maxAttempts) {
|
|
27
|
+
attempt++;
|
|
28
|
+
try {
|
|
29
|
+
return await fn();
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
if (!isRetryable(err, config) || attempt >= config.maxAttempts)
|
|
33
|
+
throw err;
|
|
34
|
+
console.warn(`[retry] ${label} attempt ${attempt} failed (${err.message}). Retry in ${delay}ms`);
|
|
35
|
+
await sleep(delay);
|
|
36
|
+
delay = Math.min(delay * config.backoffMultiplier, config.maxDelayMs);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Unreachable — the while loop always throws before exhausting, but TS needs this
|
|
40
|
+
throw new Error(`${label} exhausted ${config.maxAttempts} attempts`);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/sthapathi/retry.ts"],"names":[],"mappings":";;;AAsBA,8BAwBC;AA9CY,QAAA,kBAAkB,GAAG;IAChC,WAAW,EAAE,CAAC;IACd,cAAc,EAAE,KAAK;IACrB,iBAAiB,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM;IAClB,iBAAiB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACvC,eAAe,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC;CAC1D,CAAC;AAIF,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,WAAW,CAAC,GAAY,EAAE,MAAmB;IACpD,MAAM,CAAC,GAAG,GAA2D,CAAC;IACtE,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACvF,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IACtC,OAAO,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACjE,CAAC;AAEM,KAAK,UAAU,SAAS,CAC7B,KAAa,EACb,EAAoB,EACpB,SAAsB,0BAAkB;IAExC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;IAElC,OAAO,OAAO,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACpC,OAAO,EAAE,CAAC;QACV,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,OAAO,IAAI,MAAM,CAAC,WAAW;gBAAE,MAAM,GAAG,CAAC;YAE1E,OAAO,CAAC,IAAI,CACV,WAAW,KAAK,YAAY,OAAO,YAAa,GAAa,CAAC,OAAO,eAAe,KAAK,IAAI,CAC9F,CAAC;YACF,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;YACnB,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IACD,kFAAkF;IAClF,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,cAAc,MAAM,CAAC,WAAW,WAAW,CAAC,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { KshetraConfig } from '../kshetra/config.js';
|
|
2
|
+
import type { Task } from './types.js';
|
|
3
|
+
export interface ActiveRun {
|
|
4
|
+
controller: AbortController;
|
|
5
|
+
task: Task;
|
|
6
|
+
done: Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export interface PauseSnapshot {
|
|
9
|
+
paused?: boolean;
|
|
10
|
+
reason?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function shouldSelfHeal(prev: PauseSnapshot | undefined, curr: PauseSnapshot | undefined, hasActiveRun: boolean, healing: boolean): boolean;
|
|
13
|
+
export interface SelfHealDeps {
|
|
14
|
+
recover?: (kshetra: KshetraConfig) => Promise<Task[]>;
|
|
15
|
+
recordProgress?: (kshetra: KshetraConfig) => void;
|
|
16
|
+
touchHeartbeat?: (kshetraId: string) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare function selfHeal(kshetra: KshetraConfig, run: ActiveRun, deps?: SelfHealDeps): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=self-heal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-heal.d.ts","sourceRoot":"","sources":["../../src/sthapathi/self-heal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AASvC,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,eAAe,CAAC;IAC5B,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAGD,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAUD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,GAAG,SAAS,EAC/B,IAAI,EAAE,aAAa,GAAG,SAAS,EAC/B,YAAY,EAAE,OAAO,EACrB,OAAO,EAAE,OAAO,GACf,OAAO,CAET;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAClD,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAkBD,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,aAAa,EACtB,GAAG,EAAE,SAAS,EACd,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,IAAI,CAAC,CAYf"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shouldSelfHeal = shouldSelfHeal;
|
|
4
|
+
exports.selfHeal = selfHeal;
|
|
5
|
+
const state_js_1 = require("../kshetra/state.js");
|
|
6
|
+
const activity_log_js_1 = require("./activity-log.js");
|
|
7
|
+
const recover_js_1 = require("./recover.js");
|
|
8
|
+
function isStuckPaused(s) {
|
|
9
|
+
return !!(s?.paused && s.reason === 'stuck');
|
|
10
|
+
}
|
|
11
|
+
// Edge detector: fire self-heal only on a stuck-paused -> resumed TRANSITION,
|
|
12
|
+
// and only when there is an in-flight run to cancel and we are not already
|
|
13
|
+
// healing. Entering the stuck state (prev not stuck, curr stuck) must NOT fire;
|
|
14
|
+
// a resume with no active run is a plain state clear with nothing to recover.
|
|
15
|
+
function shouldSelfHeal(prev, curr, hasActiveRun, healing) {
|
|
16
|
+
return isStuckPaused(prev) && !isStuckPaused(curr) && hasActiveRun && !healing;
|
|
17
|
+
}
|
|
18
|
+
// In-process recovery of a hung (reason:'stuck') worker after `shreni resume`
|
|
19
|
+
// cleared its pause. Ordering is load-bearing:
|
|
20
|
+
// 1. refresh liveness FIRST (heartbeat file mtime + clear the stall counters)
|
|
21
|
+
// so the watchdog can't re-trip mid-heal;
|
|
22
|
+
// 2. abort the hung provider subprocess (SIGKILL via the run's signal);
|
|
23
|
+
// 3. await the run fully unwinding — the scheduler's WORK cycle returns and
|
|
24
|
+
// resets phase to IDLE, and its single-flight latch clears;
|
|
25
|
+
// 4. RECOVER reconciles the four drifting truths (tree, branches, bead status,
|
|
26
|
+
// phase) and reopens the bead for a fresh, gated pickup;
|
|
27
|
+
// 5. refresh liveness once more post-recover.
|
|
28
|
+
// recordProgress stamps state.json (clears outcomeRepeatCount so the stall branch
|
|
29
|
+
// can't re-trip); touchHeartbeat bumps the separate heartbeat FILE the watchdog
|
|
30
|
+
// actually reads for liveness — both are needed. The caller MUST hold a `healing`
|
|
31
|
+
// gate around this that makes selectNext return null, so no poll cycle can mutate
|
|
32
|
+
// the work tree (prepareTask / checkout main) while RECOVER is running — the loop
|
|
33
|
+
// is already armed here, unlike startup.
|
|
34
|
+
async function selfHeal(kshetra, run, deps = {}) {
|
|
35
|
+
const recover = deps.recover ?? recover_js_1.recoverKshetra;
|
|
36
|
+
const recordProgress = deps.recordProgress ?? state_js_1.recordProgress;
|
|
37
|
+
const touchHeartbeat = deps.touchHeartbeat ?? activity_log_js_1.touchHeartbeat;
|
|
38
|
+
recordProgress(kshetra); // 1
|
|
39
|
+
touchHeartbeat(kshetra.id);
|
|
40
|
+
run.controller.abort(); // 2
|
|
41
|
+
await run.done; // 3
|
|
42
|
+
await recover(kshetra); // 4
|
|
43
|
+
recordProgress(kshetra); // 5
|
|
44
|
+
touchHeartbeat(kshetra.id);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=self-heal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-heal.js","sourceRoot":"","sources":["../../src/sthapathi/self-heal.ts"],"names":[],"mappings":";;AA8BA,wCAOC;AAwBD,4BAgBC;AA3ED,kDAA8E;AAC9E,uDAA4E;AAC5E,6CAAgE;AAkBhE,SAAS,aAAa,CAAC,CAA4B;IACjD,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED,8EAA8E;AAC9E,2EAA2E;AAC3E,gFAAgF;AAChF,8EAA8E;AAC9E,SAAgB,cAAc,CAC5B,IAA+B,EAC/B,IAA+B,EAC/B,YAAqB,EACrB,OAAgB;IAEhB,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,OAAO,CAAC;AACjF,CAAC;AAQD,8EAA8E;AAC9E,+CAA+C;AAC/C,gFAAgF;AAChF,+CAA+C;AAC/C,0EAA0E;AAC1E,8EAA8E;AAC9E,iEAAiE;AACjE,iFAAiF;AACjF,8DAA8D;AAC9D,gDAAgD;AAChD,kFAAkF;AAClF,gFAAgF;AAChF,kFAAkF;AAClF,kFAAkF;AAClF,kFAAkF;AAClF,yCAAyC;AAClC,KAAK,UAAU,QAAQ,CAC5B,OAAsB,EACtB,GAAc,EACd,OAAqB,EAAE;IAEvB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,2BAAc,CAAC;IAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,yBAAqB,CAAC;IACpE,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,gCAAqB,CAAC;IAEpE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAQ,IAAI;IACpC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3B,GAAG,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAS,IAAI;IACpC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAiB,IAAI;IACpC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAS,IAAI;IACpC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAQ,IAAI;IACpC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { KshetraConfig } from '../kshetra/config.js';
|
|
2
|
+
export interface AgentContext {
|
|
3
|
+
kshetra: KshetraConfig;
|
|
4
|
+
task: Task;
|
|
5
|
+
projectMemory: string;
|
|
6
|
+
taskDetails: string;
|
|
7
|
+
universalSkills: string;
|
|
8
|
+
reviewGuide: string;
|
|
9
|
+
ragChunks: string;
|
|
10
|
+
}
|
|
11
|
+
export interface Task {
|
|
12
|
+
id: string;
|
|
13
|
+
slug: string;
|
|
14
|
+
title: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
status: 'pending' | 'in_progress' | 'blocked' | 'closed';
|
|
17
|
+
priority: number;
|
|
18
|
+
round?: number;
|
|
19
|
+
notes?: string;
|
|
20
|
+
context?: {
|
|
21
|
+
relatedFiles?: string[];
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface SilpiOutput {
|
|
25
|
+
filesChanged: {
|
|
26
|
+
path: string;
|
|
27
|
+
diff: string;
|
|
28
|
+
}[];
|
|
29
|
+
testFiles: string[];
|
|
30
|
+
summary: string;
|
|
31
|
+
confidenceScore: number;
|
|
32
|
+
questionsForReviewer: string[];
|
|
33
|
+
lintPassed: boolean;
|
|
34
|
+
testsPassed: boolean;
|
|
35
|
+
insights: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface ViharapalaOutput {
|
|
38
|
+
verdict: 'APPROVE' | 'REJECT';
|
|
39
|
+
overallScore: number;
|
|
40
|
+
mustFix: string[];
|
|
41
|
+
suggestions: string[];
|
|
42
|
+
issues: {
|
|
43
|
+
severity: 'blocker' | 'major' | 'minor';
|
|
44
|
+
file?: string;
|
|
45
|
+
description: string;
|
|
46
|
+
}[];
|
|
47
|
+
insights: string[];
|
|
48
|
+
}
|
|
49
|
+
export interface ParikshakaOutput {
|
|
50
|
+
coverageGaps: {
|
|
51
|
+
feature: string;
|
|
52
|
+
description: string;
|
|
53
|
+
priority: number;
|
|
54
|
+
}[];
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sthapathi/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IAMpB,eAAe,EAAE,MAAM,CAAC;IAKxB,WAAW,EAAE,MAAM,CAAC;IAIpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE;QACR,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE;QACN,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;QACxC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;IACJ,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC5E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sthapathi/types.ts"],"names":[],"mappings":";AAAA,6CAA6C"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { KshetraConfig } from '../kshetra/config.js';
|
|
2
|
+
import type { Phase } from './index.js';
|
|
3
|
+
export declare const STUCK_THRESHOLD_MS: number;
|
|
4
|
+
export declare const MAX_OUTCOME_REPEAT = 5;
|
|
5
|
+
export interface StuckInput {
|
|
6
|
+
phase: Phase;
|
|
7
|
+
manuallyPaused: boolean;
|
|
8
|
+
heartbeatAgeMs: number | null;
|
|
9
|
+
outcomeRepeatCount: number;
|
|
10
|
+
lastOutcome?: string;
|
|
11
|
+
idleNoWork?: boolean;
|
|
12
|
+
thresholds?: {
|
|
13
|
+
stuckMs?: number;
|
|
14
|
+
maxRepeat?: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface StuckVerdict {
|
|
18
|
+
stuck: boolean;
|
|
19
|
+
reason?: string;
|
|
20
|
+
remediation?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function remediationFor(outcome: string | undefined): string;
|
|
23
|
+
export declare function evaluateStuck(input: StuckInput): StuckVerdict;
|
|
24
|
+
export declare function runWatchdogOnce(kshetra: KshetraConfig, getPhase: () => Phase, now?: number, opts?: {
|
|
25
|
+
hasReadyWork?: () => boolean | Promise<boolean>;
|
|
26
|
+
}): Promise<StuckVerdict>;
|
|
27
|
+
//# sourceMappingURL=watchdog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watchdog.d.ts","sourceRoot":"","sources":["../../src/sthapathi/watchdog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAOxC,eAAO,MAAM,kBAAkB,QAAiB,CAAC;AACjD,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,OAAO,CAAC;IAIxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAyClE;AAMD,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,CA+B7D;AAsBD,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,MAAM,KAAK,EACrB,GAAG,GAAE,MAAmB,EACxB,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,GACzD,OAAO,CAAC,YAAY,CAAC,CAkCvB"}
|