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.
Files changed (269) hide show
  1. package/ARCHITECTURE.md +260 -0
  2. package/LICENSE +201 -0
  3. package/README.md +519 -0
  4. package/TRADEMARK.md +97 -0
  5. package/dist/agents/parikshaka.d.ts +11 -0
  6. package/dist/agents/parikshaka.d.ts.map +1 -0
  7. package/dist/agents/parikshaka.js +80 -0
  8. package/dist/agents/parikshaka.js.map +1 -0
  9. package/dist/agents/providers/claude.d.ts +3 -0
  10. package/dist/agents/providers/claude.d.ts.map +1 -0
  11. package/dist/agents/providers/claude.js +100 -0
  12. package/dist/agents/providers/claude.js.map +1 -0
  13. package/dist/agents/providers/codex.d.ts +3 -0
  14. package/dist/agents/providers/codex.d.ts.map +1 -0
  15. package/dist/agents/providers/codex.js +123 -0
  16. package/dist/agents/providers/codex.js.map +1 -0
  17. package/dist/agents/providers/gemini.d.ts +3 -0
  18. package/dist/agents/providers/gemini.d.ts.map +1 -0
  19. package/dist/agents/providers/gemini.js +77 -0
  20. package/dist/agents/providers/gemini.js.map +1 -0
  21. package/dist/agents/providers/index.d.ts +6 -0
  22. package/dist/agents/providers/index.d.ts.map +1 -0
  23. package/dist/agents/providers/index.js +35 -0
  24. package/dist/agents/providers/index.js.map +1 -0
  25. package/dist/agents/providers/registry.d.ts +20 -0
  26. package/dist/agents/providers/registry.d.ts.map +1 -0
  27. package/dist/agents/providers/registry.js +91 -0
  28. package/dist/agents/providers/registry.js.map +1 -0
  29. package/dist/agents/providers/types.d.ts +42 -0
  30. package/dist/agents/providers/types.d.ts.map +1 -0
  31. package/dist/agents/providers/types.js +61 -0
  32. package/dist/agents/providers/types.js.map +1 -0
  33. package/dist/agents/runner.d.ts +6 -0
  34. package/dist/agents/runner.d.ts.map +1 -0
  35. package/dist/agents/runner.js +159 -0
  36. package/dist/agents/runner.js.map +1 -0
  37. package/dist/agents/silpi.d.ts +3 -0
  38. package/dist/agents/silpi.d.ts.map +1 -0
  39. package/dist/agents/silpi.js +101 -0
  40. package/dist/agents/silpi.js.map +1 -0
  41. package/dist/agents/viharapala.d.ts +5 -0
  42. package/dist/agents/viharapala.d.ts.map +1 -0
  43. package/dist/agents/viharapala.js +128 -0
  44. package/dist/agents/viharapala.js.map +1 -0
  45. package/dist/cli/agents.d.ts +14 -0
  46. package/dist/cli/agents.d.ts.map +1 -0
  47. package/dist/cli/agents.js +47 -0
  48. package/dist/cli/agents.js.map +1 -0
  49. package/dist/cli/detect-toolchain.d.ts +10 -0
  50. package/dist/cli/detect-toolchain.d.ts.map +1 -0
  51. package/dist/cli/detect-toolchain.js +77 -0
  52. package/dist/cli/detect-toolchain.js.map +1 -0
  53. package/dist/cli/index.d.ts +3 -0
  54. package/dist/cli/index.d.ts.map +1 -0
  55. package/dist/cli/index.js +342 -0
  56. package/dist/cli/index.js.map +1 -0
  57. package/dist/cli/init-kshetra.d.ts +59 -0
  58. package/dist/cli/init-kshetra.d.ts.map +1 -0
  59. package/dist/cli/init-kshetra.js +531 -0
  60. package/dist/cli/init-kshetra.js.map +1 -0
  61. package/dist/cli/list.d.ts +11 -0
  62. package/dist/cli/list.d.ts.map +1 -0
  63. package/dist/cli/list.js +45 -0
  64. package/dist/cli/list.js.map +1 -0
  65. package/dist/cli/logs.d.ts +20 -0
  66. package/dist/cli/logs.d.ts.map +1 -0
  67. package/dist/cli/logs.js +144 -0
  68. package/dist/cli/logs.js.map +1 -0
  69. package/dist/cli/migrate.d.ts +8 -0
  70. package/dist/cli/migrate.d.ts.map +1 -0
  71. package/dist/cli/migrate.js +116 -0
  72. package/dist/cli/migrate.js.map +1 -0
  73. package/dist/cli/pause.d.ts +24 -0
  74. package/dist/cli/pause.d.ts.map +1 -0
  75. package/dist/cli/pause.js +41 -0
  76. package/dist/cli/pause.js.map +1 -0
  77. package/dist/cli/phalaka-autostart.d.ts +11 -0
  78. package/dist/cli/phalaka-autostart.d.ts.map +1 -0
  79. package/dist/cli/phalaka-autostart.js +28 -0
  80. package/dist/cli/phalaka-autostart.js.map +1 -0
  81. package/dist/cli/phalaka-server.d.ts +2 -0
  82. package/dist/cli/phalaka-server.d.ts.map +1 -0
  83. package/dist/cli/phalaka-server.js +20 -0
  84. package/dist/cli/phalaka-server.js.map +1 -0
  85. package/dist/cli/phalaka.d.ts +30 -0
  86. package/dist/cli/phalaka.d.ts.map +1 -0
  87. package/dist/cli/phalaka.js +60 -0
  88. package/dist/cli/phalaka.js.map +1 -0
  89. package/dist/cli/pid.d.ts +9 -0
  90. package/dist/cli/pid.d.ts.map +1 -0
  91. package/dist/cli/pid.js +66 -0
  92. package/dist/cli/pid.js.map +1 -0
  93. package/dist/cli/provider-preflight.d.ts +11 -0
  94. package/dist/cli/provider-preflight.d.ts.map +1 -0
  95. package/dist/cli/provider-preflight.js +70 -0
  96. package/dist/cli/provider-preflight.js.map +1 -0
  97. package/dist/cli/register.d.ts +8 -0
  98. package/dist/cli/register.d.ts.map +1 -0
  99. package/dist/cli/register.js +34 -0
  100. package/dist/cli/register.js.map +1 -0
  101. package/dist/cli/run.d.ts +3 -0
  102. package/dist/cli/run.d.ts.map +1 -0
  103. package/dist/cli/run.js +40 -0
  104. package/dist/cli/run.js.map +1 -0
  105. package/dist/cli/start.d.ts +11 -0
  106. package/dist/cli/start.d.ts.map +1 -0
  107. package/dist/cli/start.js +26 -0
  108. package/dist/cli/start.js.map +1 -0
  109. package/dist/cli/status.d.ts +39 -0
  110. package/dist/cli/status.d.ts.map +1 -0
  111. package/dist/cli/status.js +207 -0
  112. package/dist/cli/status.js.map +1 -0
  113. package/dist/cli/stop.d.ts +13 -0
  114. package/dist/cli/stop.d.ts.map +1 -0
  115. package/dist/cli/stop.js +18 -0
  116. package/dist/cli/stop.js.map +1 -0
  117. package/dist/cli/sync.d.ts +6 -0
  118. package/dist/cli/sync.d.ts.map +1 -0
  119. package/dist/cli/sync.js +31 -0
  120. package/dist/cli/sync.js.map +1 -0
  121. package/dist/cli/tail.d.ts +6 -0
  122. package/dist/cli/tail.d.ts.map +1 -0
  123. package/dist/cli/tail.js +170 -0
  124. package/dist/cli/tail.js.map +1 -0
  125. package/dist/cli/telemetry.d.ts +2 -0
  126. package/dist/cli/telemetry.d.ts.map +1 -0
  127. package/dist/cli/telemetry.js +42 -0
  128. package/dist/cli/telemetry.js.map +1 -0
  129. package/dist/cli/verify-hooks.d.ts +12 -0
  130. package/dist/cli/verify-hooks.d.ts.map +1 -0
  131. package/dist/cli/verify-hooks.js +38 -0
  132. package/dist/cli/verify-hooks.js.map +1 -0
  133. package/dist/cli/worker.d.ts +2 -0
  134. package/dist/cli/worker.d.ts.map +1 -0
  135. package/dist/cli/worker.js +211 -0
  136. package/dist/cli/worker.js.map +1 -0
  137. package/dist/kshetra/config.d.ts +64 -0
  138. package/dist/kshetra/config.d.ts.map +1 -0
  139. package/dist/kshetra/config.js +173 -0
  140. package/dist/kshetra/config.js.map +1 -0
  141. package/dist/kshetra/registry.d.ts +5 -0
  142. package/dist/kshetra/registry.d.ts.map +1 -0
  143. package/dist/kshetra/registry.js +69 -0
  144. package/dist/kshetra/registry.js.map +1 -0
  145. package/dist/kshetra/state.d.ts +57 -0
  146. package/dist/kshetra/state.d.ts.map +1 -0
  147. package/dist/kshetra/state.js +195 -0
  148. package/dist/kshetra/state.js.map +1 -0
  149. package/dist/kshetra/toolchain.d.ts +20 -0
  150. package/dist/kshetra/toolchain.d.ts.map +1 -0
  151. package/dist/kshetra/toolchain.js +146 -0
  152. package/dist/kshetra/toolchain.js.map +1 -0
  153. package/dist/phalaka/api.d.ts +123 -0
  154. package/dist/phalaka/api.d.ts.map +1 -0
  155. package/dist/phalaka/api.js +196 -0
  156. package/dist/phalaka/api.js.map +1 -0
  157. package/dist/phalaka/beads-read.d.ts +49 -0
  158. package/dist/phalaka/beads-read.d.ts.map +1 -0
  159. package/dist/phalaka/beads-read.js +174 -0
  160. package/dist/phalaka/beads-read.js.map +1 -0
  161. package/dist/phalaka/pid.d.ts +6 -0
  162. package/dist/phalaka/pid.d.ts.map +1 -0
  163. package/dist/phalaka/pid.js +48 -0
  164. package/dist/phalaka/pid.js.map +1 -0
  165. package/dist/phalaka/server.d.ts +10 -0
  166. package/dist/phalaka/server.d.ts.map +1 -0
  167. package/dist/phalaka/server.js +30 -0
  168. package/dist/phalaka/server.js.map +1 -0
  169. package/dist/phalaka/token.d.ts +5 -0
  170. package/dist/phalaka/token.d.ts.map +1 -0
  171. package/dist/phalaka/token.js +40 -0
  172. package/dist/phalaka/token.js.map +1 -0
  173. package/dist/phalaka/ui.d.ts +15 -0
  174. package/dist/phalaka/ui.d.ts.map +1 -0
  175. package/dist/phalaka/ui.js +233 -0
  176. package/dist/phalaka/ui.js.map +1 -0
  177. package/dist/sthapathi/activity-log.d.ts +68 -0
  178. package/dist/sthapathi/activity-log.d.ts.map +1 -0
  179. package/dist/sthapathi/activity-log.js +57 -0
  180. package/dist/sthapathi/activity-log.js.map +1 -0
  181. package/dist/sthapathi/beads.d.ts +27 -0
  182. package/dist/sthapathi/beads.d.ts.map +1 -0
  183. package/dist/sthapathi/beads.js +153 -0
  184. package/dist/sthapathi/beads.js.map +1 -0
  185. package/dist/sthapathi/branch.d.ts +5 -0
  186. package/dist/sthapathi/branch.d.ts.map +1 -0
  187. package/dist/sthapathi/branch.js +20 -0
  188. package/dist/sthapathi/branch.js.map +1 -0
  189. package/dist/sthapathi/dispatch.d.ts +14 -0
  190. package/dist/sthapathi/dispatch.d.ts.map +1 -0
  191. package/dist/sthapathi/dispatch.js +326 -0
  192. package/dist/sthapathi/dispatch.js.map +1 -0
  193. package/dist/sthapathi/errors.d.ts +27 -0
  194. package/dist/sthapathi/errors.d.ts.map +1 -0
  195. package/dist/sthapathi/errors.js +174 -0
  196. package/dist/sthapathi/errors.js.map +1 -0
  197. package/dist/sthapathi/gh.d.ts +19 -0
  198. package/dist/sthapathi/gh.d.ts.map +1 -0
  199. package/dist/sthapathi/gh.js +69 -0
  200. package/dist/sthapathi/gh.js.map +1 -0
  201. package/dist/sthapathi/git.d.ts +41 -0
  202. package/dist/sthapathi/git.d.ts.map +1 -0
  203. package/dist/sthapathi/git.js +199 -0
  204. package/dist/sthapathi/git.js.map +1 -0
  205. package/dist/sthapathi/guard.d.ts +24 -0
  206. package/dist/sthapathi/guard.d.ts.map +1 -0
  207. package/dist/sthapathi/guard.js +64 -0
  208. package/dist/sthapathi/guard.js.map +1 -0
  209. package/dist/sthapathi/health.d.ts +23 -0
  210. package/dist/sthapathi/health.d.ts.map +1 -0
  211. package/dist/sthapathi/health.js +142 -0
  212. package/dist/sthapathi/health.js.map +1 -0
  213. package/dist/sthapathi/index.d.ts +21 -0
  214. package/dist/sthapathi/index.d.ts.map +1 -0
  215. package/dist/sthapathi/index.js +88 -0
  216. package/dist/sthapathi/index.js.map +1 -0
  217. package/dist/sthapathi/lifecycle.d.ts +7 -0
  218. package/dist/sthapathi/lifecycle.d.ts.map +1 -0
  219. package/dist/sthapathi/lifecycle.js +43 -0
  220. package/dist/sthapathi/lifecycle.js.map +1 -0
  221. package/dist/sthapathi/lint.d.ts +8 -0
  222. package/dist/sthapathi/lint.d.ts.map +1 -0
  223. package/dist/sthapathi/lint.js +33 -0
  224. package/dist/sthapathi/lint.js.map +1 -0
  225. package/dist/sthapathi/merge.d.ts +18 -0
  226. package/dist/sthapathi/merge.d.ts.map +1 -0
  227. package/dist/sthapathi/merge.js +259 -0
  228. package/dist/sthapathi/merge.js.map +1 -0
  229. package/dist/sthapathi/notifications.d.ts +14 -0
  230. package/dist/sthapathi/notifications.d.ts.map +1 -0
  231. package/dist/sthapathi/notifications.js +57 -0
  232. package/dist/sthapathi/notifications.js.map +1 -0
  233. package/dist/sthapathi/parikshaka-dispatch.d.ts +12 -0
  234. package/dist/sthapathi/parikshaka-dispatch.d.ts.map +1 -0
  235. package/dist/sthapathi/parikshaka-dispatch.js +0 -0
  236. package/dist/sthapathi/parikshaka-dispatch.js.map +1 -0
  237. package/dist/sthapathi/pickup.d.ts +13 -0
  238. package/dist/sthapathi/pickup.d.ts.map +1 -0
  239. package/dist/sthapathi/pickup.js +144 -0
  240. package/dist/sthapathi/pickup.js.map +1 -0
  241. package/dist/sthapathi/recover.d.ts +16 -0
  242. package/dist/sthapathi/recover.d.ts.map +1 -0
  243. package/dist/sthapathi/recover.js +149 -0
  244. package/dist/sthapathi/recover.js.map +1 -0
  245. package/dist/sthapathi/retry.d.ts +11 -0
  246. package/dist/sthapathi/retry.d.ts.map +1 -0
  247. package/dist/sthapathi/retry.js +42 -0
  248. package/dist/sthapathi/retry.js.map +1 -0
  249. package/dist/sthapathi/self-heal.d.ts +19 -0
  250. package/dist/sthapathi/self-heal.d.ts.map +1 -0
  251. package/dist/sthapathi/self-heal.js +46 -0
  252. package/dist/sthapathi/self-heal.js.map +1 -0
  253. package/dist/sthapathi/types.d.ts +56 -0
  254. package/dist/sthapathi/types.d.ts.map +1 -0
  255. package/dist/sthapathi/types.js +4 -0
  256. package/dist/sthapathi/types.js.map +1 -0
  257. package/dist/sthapathi/watchdog.d.ts +27 -0
  258. package/dist/sthapathi/watchdog.d.ts.map +1 -0
  259. package/dist/sthapathi/watchdog.js +145 -0
  260. package/dist/sthapathi/watchdog.js.map +1 -0
  261. package/dist/telemetry/telemetry.d.ts +42 -0
  262. package/dist/telemetry/telemetry.d.ts.map +1 -0
  263. package/dist/telemetry/telemetry.js +189 -0
  264. package/dist/telemetry/telemetry.js.map +1 -0
  265. package/dist/test-setup.d.ts +2 -0
  266. package/dist/test-setup.d.ts.map +1 -0
  267. package/dist/test-setup.js +16 -0
  268. package/dist/test-setup.js.map +1 -0
  269. package/package.json +71 -0
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_OUTCOME_REPEAT = exports.STUCK_THRESHOLD_MS = void 0;
4
+ exports.remediationFor = remediationFor;
5
+ exports.evaluateStuck = evaluateStuck;
6
+ exports.runWatchdogOnce = runWatchdogOnce;
7
+ const fs_1 = require("fs");
8
+ const state_js_1 = require("../kshetra/state.js");
9
+ const activity_log_js_1 = require("./activity-log.js");
10
+ const errors_js_1 = require("./errors.js");
11
+ // Defaults per the Sthapathi workflow design §4.4 / D1. Made configurable
12
+ // per-Kshetra later.
13
+ exports.STUCK_THRESHOLD_MS = 20 * 60 * 1000; // 20m of no liveness while busy
14
+ exports.MAX_OUTCOME_REPEAT = 5; // same non-advancing outcome this many times
15
+ // Human-facing remediation steps for a given stall outcome. Generic fallback
16
+ // covers a hung agent / unknown stall.
17
+ function remediationFor(outcome) {
18
+ const o = outcome ?? '';
19
+ if (o.includes('branch already exists')) {
20
+ return [
21
+ ' 1) Delete the stale bead branch, then resume:',
22
+ ' git -C <repo> branch -D <bead-branch>',
23
+ ' shreni resume --kshetra <id>',
24
+ ' 2) If it recurs, the worker will RECOVER it on next start (shreni stop/start).',
25
+ ].join('\n');
26
+ }
27
+ if (o.includes('dirty working tree')) {
28
+ return [
29
+ ' 1) Inspect, then discard the interrupted changes:',
30
+ ' git -C <repo> status',
31
+ ' git -C <repo> checkout main && git -C <repo> clean -fd',
32
+ ' 2) shreni resume --kshetra <id> (RECOVER also cleans this on restart)',
33
+ ].join('\n');
34
+ }
35
+ if (o.includes('cycle:GIT_FAILED') || o.includes('cycle:BD_FAILED')) {
36
+ return [
37
+ ' 1) Read the error in the worker log; fix the underlying git/bd issue.',
38
+ ' 2) shreni resume --kshetra <id>',
39
+ ].join('\n');
40
+ }
41
+ if (o.includes('base suite red') || o.includes('health')) {
42
+ return [
43
+ ' 1) A [shreni-health] repair bead should be queued — let it run, or',
44
+ ' 2) fix the failing tests manually, then shreni resume --kshetra <id>.',
45
+ ].join('\n');
46
+ }
47
+ // One honest clearing verb — ACK — named everywhere (the watchdog design §3.3 /
48
+ // RC3). The latch clears only on an explicit human acknowledgment, exposed two
49
+ // ways that both funnel to resumeKshetra: the CLI, and a deliberate stop/start
50
+ // (RECOVER acknowledges the drift, then clears it).
51
+ return [
52
+ ' 1) Inspect the worker log and the active bead for a genuinely hung agent.',
53
+ ' 2) ACK to clear the latch and resume — either of:',
54
+ ' shreni resume --kshetra <id> (CLI ACK)',
55
+ ' shreni stop --kshetra <id> && shreni start --kshetra <id> (RECOVER acknowledges)',
56
+ ' 3) If a specific bead keeps failing, mark it blocked for manual work.',
57
+ ].join('\n');
58
+ }
59
+ // Pure decision: is the worker stuck? Two independent trip conditions — a fast
60
+ // stall loop (same outcome repeated) and a liveness timeout (no activity while
61
+ // the worker should be busy). A manually-paused Kshetra is never "stuck" (it is
62
+ // already awaiting a human).
63
+ function evaluateStuck(input) {
64
+ if (input.manuallyPaused)
65
+ return { stuck: false };
66
+ // Idle by design: an empty ready queue with nothing in flight. "No activity"
67
+ // here means "nothing to do", not "hung" — never trip, so the watchdog never
68
+ // escalates an idle worker to Phalaka. A genuine
69
+ // hang while WORKING/PREPARING, or a repeat-stall with ready work waiting, is
70
+ // not idle (idleNoWork is false there) and still trips below.
71
+ if (input.idleNoWork)
72
+ return { stuck: false };
73
+ const stuckMs = input.thresholds?.stuckMs ?? exports.STUCK_THRESHOLD_MS;
74
+ const maxRepeat = input.thresholds?.maxRepeat ?? exports.MAX_OUTCOME_REPEAT;
75
+ if (input.outcomeRepeatCount >= maxRepeat) {
76
+ return {
77
+ stuck: true,
78
+ reason: `the same outcome "${input.lastOutcome ?? 'unknown'}" repeated ${input.outcomeRepeatCount}× without forward progress`,
79
+ remediation: remediationFor(input.lastOutcome),
80
+ };
81
+ }
82
+ if (input.phase !== 'IDLE' && input.heartbeatAgeMs !== null && input.heartbeatAgeMs > stuckMs) {
83
+ const mins = Math.round(input.heartbeatAgeMs / 60_000);
84
+ return {
85
+ stuck: true,
86
+ reason: `no worker heartbeat for ${mins}m while phase=${input.phase} — the worker appears hung`,
87
+ remediation: remediationFor(undefined),
88
+ };
89
+ }
90
+ return { stuck: false };
91
+ }
92
+ // Worker liveness = age of the heartbeat file's mtime (the watchdog design §3.1).
93
+ // Falls back to the legacy activity.jsonl mtime only when no heartbeat exists yet, so
94
+ // an old worker (or the first tick before the first stamp) degrades gracefully rather
95
+ // than reading as a fresh worker that can never trip.
96
+ function heartbeatAge(kshetraId, now) {
97
+ try {
98
+ return now - (0, fs_1.statSync)((0, activity_log_js_1.heartbeatPath)(kshetraId)).mtimeMs;
99
+ }
100
+ catch {
101
+ // no heartbeat file — fall back to agent-emit liveness (legacy behavior)
102
+ }
103
+ try {
104
+ return now - (0, fs_1.statSync)((0, activity_log_js_1.logPath)(kshetraId)).mtimeMs;
105
+ }
106
+ catch {
107
+ return null;
108
+ }
109
+ }
110
+ // Evaluate once and, on a fresh trip, escalate: set the stuck banner (Phalaka),
111
+ // pause for manual resume, and push an operator notification with remediation.
112
+ // Idempotent — does not re-notify while already flagged stuck.
113
+ async function runWatchdogOnce(kshetra, getPhase, now = Date.now(), opts) {
114
+ const progress = (0, state_js_1.getProgressState)(kshetra);
115
+ if (progress.stuck)
116
+ return { stuck: true, reason: progress.stuck.reason };
117
+ const phase = getPhase();
118
+ // Distinguish "idle because there's nothing to do" from "hung". Only IDLE and
119
+ // SELECTING can be idle-by-design; PREPARING/WORKING always have a task in
120
+ // flight, so we skip the ready-queue probe (and its bd call) on busy ticks.
121
+ // When the probe reports an empty queue, inactivity is expected — not stuck.
122
+ let idleNoWork = false;
123
+ if ((phase === 'IDLE' || phase === 'SELECTING') && opts?.hasReadyWork) {
124
+ idleNoWork = !(await opts.hasReadyWork());
125
+ }
126
+ const verdict = evaluateStuck({
127
+ phase,
128
+ manuallyPaused: (0, state_js_1.isKshetraManuallyPaused)(kshetra),
129
+ heartbeatAgeMs: heartbeatAge(kshetra.id, now),
130
+ outcomeRepeatCount: progress.outcomeRepeatCount,
131
+ lastOutcome: progress.lastOutcome,
132
+ idleNoWork,
133
+ thresholds: {
134
+ stuckMs: kshetra.watchdog?.stuckThresholdMs,
135
+ maxRepeat: kshetra.watchdog?.maxOutcomeRepeat,
136
+ },
137
+ });
138
+ if (verdict.stuck && verdict.reason && verdict.remediation) {
139
+ (0, state_js_1.setStuck)(kshetra, { reason: verdict.reason, remediation: verdict.remediation, phase });
140
+ (0, state_js_1.pauseKshetra)(kshetra, { reason: 'stuck', message: verdict.reason, manual: true });
141
+ await (0, errors_js_1.notifyOperator)(kshetra, null, 'stuck', verdict.reason, verdict.remediation);
142
+ }
143
+ return verdict;
144
+ }
145
+ //# sourceMappingURL=watchdog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchdog.js","sourceRoot":"","sources":["../../src/sthapathi/watchdog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export declare const TELEMETRY_ENDPOINT: string | null;
2
+ export declare const CONSENT_NOTICE: string;
3
+ export type TelemetryEventName = 'session_start' | 'kshetra_init' | 'task_merged';
4
+ export interface TelemetryEvent {
5
+ name: TelemetryEventName;
6
+ ts: string;
7
+ anonymousId: string;
8
+ version: string;
9
+ platform: string;
10
+ props?: Record<string, string | number | boolean>;
11
+ }
12
+ export interface TelemetryConfig {
13
+ enabled: boolean;
14
+ anonymousId?: string;
15
+ consentedAt?: string;
16
+ endpoint?: string | null;
17
+ }
18
+ declare function configPath(dir: string): string;
19
+ declare function localSinkPath(dir: string): string;
20
+ export declare function loadTelemetryConfig(dir?: string): TelemetryConfig;
21
+ export declare function isTelemetryEnabled(cfg: TelemetryConfig, env?: NodeJS.ProcessEnv): boolean;
22
+ export interface EmitOpts {
23
+ dir?: string;
24
+ env?: NodeJS.ProcessEnv;
25
+ }
26
+ export declare function emit(name: TelemetryEventName, props?: Record<string, string | number | boolean>, opts?: EmitOpts): void;
27
+ export declare function enableTelemetry(dir?: string): TelemetryConfig;
28
+ export declare function disableTelemetry(dir?: string): TelemetryConfig;
29
+ export interface TelemetryStatus {
30
+ enabled: boolean;
31
+ hardOptOut: boolean;
32
+ anonymousId?: string;
33
+ endpoint: string | null;
34
+ localSink: string;
35
+ }
36
+ export declare function telemetryStatus(dir?: string, env?: NodeJS.ProcessEnv): TelemetryStatus;
37
+ export declare const _internal: {
38
+ configPath: typeof configPath;
39
+ localSinkPath: typeof localSinkPath;
40
+ };
41
+ export {};
42
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/telemetry/telemetry.ts"],"names":[],"mappings":"AAgCA,eAAO,MAAM,kBAAkB,EAAE,MAAM,GAAG,IAAW,CAAC;AAGtD,eAAO,MAAM,cAAc,QAUf,CAAC;AAGb,MAAM,MAAM,kBAAkB,GAC1B,eAAe,GACf,cAAc,GACd,aAAa,CAAC;AAElB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IAEjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAMD,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED,iBAAS,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAqB,GAAG,eAAe,CAO/E;AAUD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,eAAe,EACpB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAKT;AA2CD,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAMD,wBAAgB,IAAI,CAClB,IAAI,EAAE,kBAAkB,EACxB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EACjD,IAAI,GAAE,QAAa,GAClB,IAAI,CAsBN;AAID,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAqB,GAAG,eAAe,CAU3E;AAID,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAqB,GAAG,eAAe,CAK5E;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAC7B,GAAG,GAAE,MAAqB,EAC1B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,eAAe,CAWjB;AAGD,eAAO,MAAM,SAAS;;;CAAgC,CAAC"}
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._internal = exports.CONSENT_NOTICE = exports.TELEMETRY_ENDPOINT = void 0;
4
+ exports.loadTelemetryConfig = loadTelemetryConfig;
5
+ exports.isTelemetryEnabled = isTelemetryEnabled;
6
+ exports.emit = emit;
7
+ exports.enableTelemetry = enableTelemetry;
8
+ exports.disableTelemetry = disableTelemetry;
9
+ exports.telemetryStatus = telemetryStatus;
10
+ const fs_1 = require("fs");
11
+ const path_1 = require("path");
12
+ const os_1 = require("os");
13
+ const crypto_1 = require("crypto");
14
+ // Opt-in, privacy-respecting telemetry (yds.5).
15
+ //
16
+ // Purpose: measure clone→first-merge *activation* and 7-day *retention* so the
17
+ // team/monetization decisions after launch aren't made blind. Nothing else.
18
+ //
19
+ // Guarantees:
20
+ // • OFF by default. Nothing is sent until the user explicitly opts in
21
+ // (`shreni telemetry enable`) or sets SHRENI_TELEMETRY=1.
22
+ // • Respects a hard opt-out (DO_NOT_TRACK=1 or SHRENI_TELEMETRY=0), which wins
23
+ // over any config.
24
+ // • No PII, ever: no repo names, no paths, no code, no task content, no user
25
+ // identity. Only an anonymous random id, the event name, a coarse OS
26
+ // platform, the Shreni version, and whitelisted primitive props the caller
27
+ // passes explicitly.
28
+ // • emit() never throws and never blocks — a telemetry failure must never
29
+ // affect the harness.
30
+ //
31
+ // ─── FOUNDER DECISIONS (fill these in before relying on the data) ───
32
+ // 1. TELEMETRY_ENDPOINT below is null: with no endpoint, an opted-in client
33
+ // writes events to a LOCAL jsonl file only (nothing leaves the machine).
34
+ // Set a real collector URL here (or via SHRENI_TELEMETRY_ENDPOINT) to
35
+ // actually gather activation/retention.
36
+ // 2. CONSENT_NOTICE copy — the exact disclosure shown on `telemetry enable`.
37
+ // 3. The set of event names (below) and any props — keep them non-identifying.
38
+ // null → local-only sink (see above). A founder sets this to the collector URL,
39
+ // or overrides per-run with SHRENI_TELEMETRY_ENDPOINT.
40
+ exports.TELEMETRY_ENDPOINT = null;
41
+ // Shown when a user runs `shreni telemetry enable`. FOUNDER: finalize this copy.
42
+ exports.CONSENT_NOTICE = [
43
+ 'Shreni telemetry is OPT-IN and anonymous.',
44
+ '',
45
+ 'If you enable it, Shreni sends a random anonymous id plus coarse events',
46
+ '(e.g. "a project was initialised", "a task merged", "the harness started")',
47
+ 'with the Shreni version and your OS platform. It NEVER sends your code, file',
48
+ 'paths, repo names, task contents, or any personal identifier.',
49
+ '',
50
+ 'This helps us understand activation and retention. You can turn it off any',
51
+ 'time with `shreni telemetry disable`, or set DO_NOT_TRACK=1 to hard-disable it.',
52
+ ].join('\n');
53
+ function defaultDir() {
54
+ return (0, path_1.resolve)((0, os_1.homedir)(), '.shreni');
55
+ }
56
+ function configPath(dir) {
57
+ return (0, path_1.join)(dir, 'telemetry.json');
58
+ }
59
+ function localSinkPath(dir) {
60
+ return (0, path_1.join)(dir, 'telemetry-local.jsonl');
61
+ }
62
+ function loadTelemetryConfig(dir = defaultDir()) {
63
+ try {
64
+ return JSON.parse((0, fs_1.readFileSync)(configPath(dir), 'utf8'));
65
+ }
66
+ catch {
67
+ // Missing / unreadable config ⇒ the default: disabled (opt-in).
68
+ return { enabled: false };
69
+ }
70
+ }
71
+ function saveTelemetryConfig(cfg, dir = defaultDir()) {
72
+ (0, fs_1.mkdirSync)(dir, { recursive: true });
73
+ (0, fs_1.writeFileSync)(configPath(dir), JSON.stringify(cfg, null, 2), 'utf8');
74
+ }
75
+ // Resolve the effective on/off state. A hard opt-out (DO_NOT_TRACK=1 or
76
+ // SHRENI_TELEMETRY in {0,off,false}) always wins; an env opt-in
77
+ // (SHRENI_TELEMETRY in {1,on,true}) forces on; otherwise the persisted config.
78
+ function isTelemetryEnabled(cfg, env = process.env) {
79
+ const flag = (env.SHRENI_TELEMETRY ?? '').toLowerCase();
80
+ if (env.DO_NOT_TRACK === '1' || flag === '0' || flag === 'off' || flag === 'false')
81
+ return false;
82
+ if (flag === '1' || flag === 'on' || flag === 'true')
83
+ return true;
84
+ return cfg.enabled === true;
85
+ }
86
+ function resolveEndpoint(cfg, env) {
87
+ return env.SHRENI_TELEMETRY_ENDPOINT ?? cfg.endpoint ?? exports.TELEMETRY_ENDPOINT;
88
+ }
89
+ function readVersion() {
90
+ try {
91
+ const raw = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', '..', 'package.json'), 'utf8');
92
+ return JSON.parse(raw).version ?? '0.0.0';
93
+ }
94
+ catch {
95
+ return '0.0.0';
96
+ }
97
+ }
98
+ // Deliver one event. With an endpoint set, POST it (best-effort, short timeout,
99
+ // failures swallowed). With no endpoint, append it to a local jsonl file so an
100
+ // opted-in user can inspect exactly what would be sent — and nothing leaves the
101
+ // machine until a collector URL is configured.
102
+ async function deliver(event, endpoint, dir) {
103
+ if (!endpoint) {
104
+ try {
105
+ (0, fs_1.appendFileSync)(localSinkPath(dir), JSON.stringify(event) + '\n', 'utf8');
106
+ }
107
+ catch {
108
+ /* local sink is best-effort */
109
+ }
110
+ return;
111
+ }
112
+ try {
113
+ const controller = new AbortController();
114
+ const timer = setTimeout(() => controller.abort(), 3000);
115
+ await fetch(endpoint, {
116
+ method: 'POST',
117
+ headers: { 'content-type': 'application/json' },
118
+ body: JSON.stringify(event),
119
+ signal: controller.signal,
120
+ });
121
+ clearTimeout(timer);
122
+ }
123
+ catch {
124
+ /* telemetry must never surface a failure to the caller */
125
+ }
126
+ }
127
+ // Record an event. A no-op (and a synchronous early return) when telemetry is
128
+ // disabled — the default — so the hot path pays almost nothing. Fully guarded:
129
+ // never throws, never blocks (network delivery is fire-and-forget; the local
130
+ // sink write is synchronous but cheap).
131
+ function emit(name, props, opts = {}) {
132
+ try {
133
+ const dir = opts.dir ?? defaultDir();
134
+ const env = opts.env ?? process.env;
135
+ const cfg = loadTelemetryConfig(dir);
136
+ if (!isTelemetryEnabled(cfg, env))
137
+ return;
138
+ const event = {
139
+ name,
140
+ ts: new Date().toISOString(),
141
+ anonymousId: cfg.anonymousId ?? 'anonymous',
142
+ version: readVersion(),
143
+ platform: process.platform,
144
+ ...(props ? { props } : {}),
145
+ };
146
+ // Fire-and-forget: swallow the promise so a slow/failed POST never blocks or
147
+ // rejects into the caller. (The no-endpoint local-sink path runs
148
+ // synchronously before the promise is returned.)
149
+ void deliver(event, resolveEndpoint(cfg, env), dir);
150
+ }
151
+ catch {
152
+ /* telemetry must never break the caller */
153
+ }
154
+ }
155
+ // Turn telemetry on: persist enabled=true, mint a stable anonymous id on first
156
+ // opt-in (reused thereafter), and stamp the consent time. Returns the new config.
157
+ function enableTelemetry(dir = defaultDir()) {
158
+ const cfg = loadTelemetryConfig(dir);
159
+ const next = {
160
+ ...cfg,
161
+ enabled: true,
162
+ anonymousId: cfg.anonymousId ?? (0, crypto_1.randomUUID)(),
163
+ consentedAt: new Date().toISOString(),
164
+ };
165
+ saveTelemetryConfig(next, dir);
166
+ return next;
167
+ }
168
+ // Turn telemetry off. Keeps the anonymous id so a later re-opt-in is the same
169
+ // install (not a new one), but stops all sending.
170
+ function disableTelemetry(dir = defaultDir()) {
171
+ const cfg = loadTelemetryConfig(dir);
172
+ const next = { ...cfg, enabled: false };
173
+ saveTelemetryConfig(next, dir);
174
+ return next;
175
+ }
176
+ function telemetryStatus(dir = defaultDir(), env = process.env) {
177
+ const cfg = loadTelemetryConfig(dir);
178
+ const hardOptOut = env.DO_NOT_TRACK === '1' || ['0', 'off', 'false'].includes((env.SHRENI_TELEMETRY ?? '').toLowerCase());
179
+ return {
180
+ enabled: isTelemetryEnabled(cfg, env),
181
+ hardOptOut,
182
+ anonymousId: cfg.anonymousId,
183
+ endpoint: resolveEndpoint(cfg, env),
184
+ localSink: localSinkPath(dir),
185
+ };
186
+ }
187
+ // Exposed for tests (config path + local sink path resolution).
188
+ exports._internal = { configPath, localSinkPath };
189
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/telemetry/telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../src/test-setup.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fs_1 = require("fs");
4
+ const os_1 = require("os");
5
+ const path_1 = require("path");
6
+ // Isolate the home directory for the whole test process so nothing can write
7
+ // into the developer's real `~/.shreni` (activity logs, kshetra state, etc.).
8
+ //
9
+ // `os.homedir()` reads the HOME (POSIX) / USERPROFILE (Windows) env var first,
10
+ // so overriding them here redirects every homedir()-derived path — e.g.
11
+ // activity-log.ts's emit() — into a throwaway temp dir. Without this, fixture
12
+ // events (the `myapp` kshetra, `proj-42` task) leaked into the real log.
13
+ const fakeHome = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'shreni-test-home-'));
14
+ process.env.HOME = fakeHome;
15
+ process.env.USERPROFILE = fakeHome;
16
+ //# sourceMappingURL=test-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-setup.js","sourceRoot":"","sources":["../src/test-setup.ts"],"names":[],"mappings":";;AAAA,2BAAiC;AACjC,2BAA4B;AAC5B,+BAA4B;AAE5B,6EAA6E;AAC7E,8EAA8E;AAC9E,EAAE;AACF,+EAA+E;AAC/E,wEAAwE;AACxE,8EAA8E;AAC9E,yEAAyE;AACzE,MAAM,QAAQ,GAAG,IAAA,gBAAW,EAAC,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAClE,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAC;AAC5B,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,QAAQ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "shreni",
3
+ "version": "0.1.0",
4
+ "description": "Local-first, bring-your-own-model agent harness that turns a backlog into reviewed, merged code",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "shreni": "dist/cli/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "typecheck": "tsc --noEmit",
12
+ "dev": "tsx src/index.ts",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest",
15
+ "test:coverage": "vitest run --coverage",
16
+ "prepublishOnly": "pnpm build"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "ARCHITECTURE.md",
22
+ "LICENSE",
23
+ "TRADEMARK.md"
24
+ ],
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/TeakWood/Shreni.git"
31
+ },
32
+ "keywords": [
33
+ "ai-agents",
34
+ "autonomous-agents",
35
+ "coding-agent",
36
+ "code-review",
37
+ "orchestrator",
38
+ "agent-harness",
39
+ "local-first",
40
+ "bring-your-own-model"
41
+ ],
42
+ "author": "TeakWood <teakwood.dev@gmail.com>",
43
+ "license": "Apache-2.0",
44
+ "type": "commonjs",
45
+ "packageManager": "pnpm@10.12.1",
46
+ "engines": {
47
+ "node": ">=20",
48
+ "npm": "please-use-pnpm",
49
+ "yarn": "please-use-pnpm"
50
+ },
51
+ "bugs": {
52
+ "url": "https://github.com/TeakWood/Shreni/issues"
53
+ },
54
+ "homepage": "https://github.com/TeakWood/Shreni#readme",
55
+ "devDependencies": {
56
+ "@types/node": "^25.9.2",
57
+ "@vitest/coverage-v8": "^4.1.8",
58
+ "tsx": "^4.22.4",
59
+ "typescript": "^6.0.3",
60
+ "vitest": "^4.1.8"
61
+ },
62
+ "dependencies": {
63
+ "@anthropic-ai/sdk": "^0.102.0",
64
+ "@fastify/static": "^9.1.3",
65
+ "@fastify/websocket": "^11.2.0",
66
+ "@types/js-yaml": "^4.0.9",
67
+ "fastify": "^5.8.5",
68
+ "js-yaml": "^4.2.0",
69
+ "zod": "^4.4.3"
70
+ }
71
+ }