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
package/README.md ADDED
@@ -0,0 +1,519 @@
1
+ # Shreni
2
+
3
+ [![License: Apache 2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
4
+ [![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)](#status)
5
+ [![Node ≥ 20](https://img.shields.io/badge/node-%E2%89%A520-brightgreen.svg)](#prerequisites)
6
+ [![Built with TypeScript](https://img.shields.io/badge/built%20with-TypeScript-3178c6.svg)](https://www.typescriptlang.org/)
7
+
8
+ **Shreni turns a backlog into merged code.** You file tasks; a team of AI agents
9
+ picks them up, writes and reviews the code, runs the tests, and merges what passes
10
+ — on your own machine, using the model you choose. You steer by outcome, not by
11
+ babysitting every keystroke.
12
+
13
+ It is built around three convictions that set it apart from most agent frameworks:
14
+
15
+ - **Bring your own model.** Shreni drives the provider CLI you already pay for
16
+ (Claude today; Codex/Gemini experimental). No hosted middleman, no per-seat
17
+ markup, no lock-in to one vendor's model.
18
+ - **Local-first.** The orchestrator, the git repos, the task database, and the
19
+ dashboard all run on your machine and loopback. Your code never has to leave it.
20
+ - **An explicit merge policy.** Shreni is honest about the scariest question up
21
+ front: *does a bot push to `main`?* You decide — auto-merge for speed, or a
22
+ pull-request gate for a human/team sign-off. See [Merge policy](#merge-policy-push-vs-pr).
23
+
24
+ ## How it works
25
+
26
+ Think of Shreni as a small, tireless engineering team you run locally:
27
+
28
+ - An **orchestrator** watches your task list. When a task is ready and its
29
+ dependencies are met, it assigns it, sets up an isolated branch, and manages the
30
+ whole lifecycle — including recovering cleanly if the machine restarts mid-task.
31
+ - A **coding agent** does the work: writes the implementation and unit tests, runs
32
+ lint and the test suite, and submits the result.
33
+ - A **reviewer agent** judges that result against the task's acceptance criteria,
34
+ code quality, and coverage — and either approves it or sends it back with
35
+ specific feedback. The coder and reviewer iterate for a few rounds until the work
36
+ is approved or the task is flagged for you.
37
+
38
+ When the reviewer approves, the change lands on `main` (or opens a pull request —
39
+ your choice), and the orchestrator moves to the next task. A separate **test agent**
40
+ runs afterward to backfill coverage. The whole inner loop runs without you in it —
41
+ you steer by *outcome*: the review verdicts, a green-base health gate that refuses
42
+ to start new work on a broken build, and the merged result.
43
+
44
+ > **Does Shreni push to `main` without me reviewing?** By default, **yes — that's
45
+ > the point**: when the reviewer approves, the change is squash-merged straight to
46
+ > `main`. There is no human pull-request gate in the inner loop; every task still
47
+ > passes the automated coder ↔ reviewer review first. If you want a human gate, set
48
+ > **`mergePolicy: pr`** and Shreni opens a pull request on approval instead of
49
+ > merging — ideal for cautious solo devs and teams. See
50
+ > [Merge policy](#merge-policy-push-vs-pr).
51
+
52
+ ## Why Shreni (vs. the alternatives)
53
+
54
+ Most tools in this space are either an IDE autocomplete, a Python library for
55
+ *building* an agent graph, or a hosted product that runs your code on someone
56
+ else's servers. Shreni is a **ready-to-run harness** for *autonomous, reviewed,
57
+ task-driven* delivery on your own machine.
58
+
59
+ | | **Shreni** | Copilot / Cursor / Augment | CrewAI / AutoGen | LangGraph | Roll your own |
60
+ |---|:---:|:---:|:---:|:---:|:---:|
61
+ | Runs autonomously from a backlog | ✅ | ✋ you drive each edit | ⚙️ you build the loop | ⚙️ you build the loop | ⚙️ |
62
+ | Built-in AI code review before merge | ✅ | ❌ | ⚙️ DIY | ⚙️ DIY | ⚙️ |
63
+ | Owns the git + merge workflow | ✅ | ❌ | ❌ | ❌ | ⚙️ |
64
+ | Task-graph driven (dependencies, priorities) | ✅ | ❌ | partial | ✅ (you wire it) | ⚙️ |
65
+ | Bring your own model / CLI | ✅ | ❌ (their model) | ✅ | ✅ | ✅ |
66
+ | Local-first (code stays on your machine) | ✅ | ❌ (mostly cloud) | ✅ | ✅ | depends |
67
+ | Explicit auto-merge **and** PR-gate modes | ✅ | n/a | ❌ | ❌ | ⚙️ |
68
+
69
+ ✅ built-in · ⚙️ possible but you build it · ✋ manual · ❌ not the model
70
+
71
+ If you want a copilot that suggests lines while *you* type, use a copilot. If you
72
+ want to *assemble* a bespoke agent graph in Python, use CrewAI or LangGraph. If you
73
+ want to hand a backlog to a local, self-reviewing team and get merged commits back,
74
+ that's Shreni.
75
+
76
+ ## Quickstart
77
+
78
+ > Prefer a zero-setup taste first? See [Prerequisites](#prerequisites) — you need a
79
+ > provider CLI (e.g. Claude) authenticated, plus `bd`, `gh`, and Node ≥ 20.
80
+
81
+ Install the CLI from source:
82
+
83
+ ```bash
84
+ git clone https://github.com/TeakWood/Shreni.git /projects/shreni
85
+ cd /projects/shreni
86
+ pnpm install
87
+ pnpm build
88
+ npm install -g . # installs the `shreni` CLI globally
89
+ shreni --version
90
+ ```
91
+
92
+ Register a project (a **Kshetra**) and file your first task:
93
+
94
+ ```bash
95
+ # Your project repo must already exist with a GitHub remote configured.
96
+ shreni init-kshetra --slug myapp --path /projects/myapp
97
+
98
+ cd /projects/myapp
99
+ bd create "Add user authentication" -p 2 \
100
+ --description "Email + password login with JWT sessions"
101
+ ```
102
+
103
+ Start the harness and watch it work:
104
+
105
+ ```bash
106
+ shreni start # orchestrator begins polling for ready tasks
107
+ shreni agents # see which agent is active and on what
108
+ shreni phalaka start # optional: local dashboard on 127.0.0.1
109
+ ```
110
+
111
+ Sthapathi polls each registered project every 30 seconds. When your task is ready,
112
+ the coder ↔ reviewer loop runs and — on approval — the change merges to `main`.
113
+
114
+ ## Prerequisites
115
+
116
+ - **Node.js** ≥ 20 and **pnpm** (`npm install -g pnpm`)
117
+ - **`bd` (Beads) CLI** — the task database — `npm install -g @beads/bd`
118
+ - **A provider CLI, authenticated** — **Anthropic API key** (`ANTHROPIC_API_KEY`)
119
+ for the default Claude provider. The agent still calls a model, so this is
120
+ required; Shreni does not host one for you.
121
+ - **GitHub CLI** (`gh`) — authenticated for the account/org where your projects
122
+ live. Used to create the task database repo and (in `pr` merge mode) to open PRs.
123
+
124
+ ## Status
125
+
126
+ Shreni is **alpha**: the core loop, recovery/watchdog machinery, and merge policies
127
+ are implemented and tested (800+ unit tests), but the install path is source-only
128
+ and the provider story beyond Claude is experimental. Expect rough edges around
129
+ onboarding and distribution — those are the current focus. Feedback and issues
130
+ welcome.
131
+
132
+ ## The team, by name (architecture)
133
+
134
+ Under the hood, each role above has a Sanskrit name — they are the vocabulary you
135
+ will see in logs, config, and the dashboard:
136
+
137
+ | Component | Plain-English role |
138
+ |---|---|
139
+ | **Sthapathi** (architect) | Orchestrator. Polls `bd` for tasks, dispatches agents, drives the review loop, and owns the task lifecycle and git workflow. |
140
+ | **Silpi** (craftsman) | Coding agent. Writes implementation code and unit tests, runs lint and tests, submits for review. |
141
+ | **Viharapala** (guardian) | Review agent. Judges Silpi's output against acceptance criteria, quality, and coverage; returns `APPROVE` or `REJECT` with structured feedback. |
142
+ | **Parikshaka** (examiner) | Test agent. Runs asynchronously after each merge; backfills tests and surfaces coverage gaps. |
143
+ | **Phalaka** (panel) | Local dashboard. Loopback web UI to watch worker status, task progress, and stuck-state alerts. |
144
+
145
+ Each project managed by Shreni is a **Kshetra** (field) — its own git repo, `bd`
146
+ task database, RAG index, and agent queue, fully isolated from every other project.
147
+
148
+ ```
149
+ Developer machine
150
+ ├── Sthapathi (Node.js process)
151
+ │ ├── polls bd ready every 30s per Kshetra
152
+ │ ├── dispatches Silpi → Viharapala loop (up to 3 rounds)
153
+ │ ├── squash-merges approved branches to main (or opens a PR)
154
+ │ └── dispatches the test agent async post-merge
155
+ ├── Phalaka server (Fastify, loopback)
156
+ │ └── serves the local dashboard at 127.0.0.1
157
+ └── Kshetras/
158
+ ├── myapp/ ← project repo
159
+ │ ├── .beads/ ← symlink to myapp-beads/
160
+ │ └── .shreni/kshetra.yaml
161
+ └── myapp-beads/ ← bd Dolt database (git repo)
162
+ ```
163
+
164
+ **Key design constraint:** Sthapathi is the sole caller of `bd update --claim` and
165
+ `bd close`. Agents (Silpi, Viharapala, Parikshaka) never call `bd` directly — they
166
+ receive task context as injected prompt data. Interactive Claude Code sessions can
167
+ file tasks (`bd create`) but cannot claim or close them.
168
+
169
+ > For a deeper walkthrough — the worker lifecycle and phase machine, the git
170
+ > workflow, the provider abstraction, and the watchdog/self-heal resilience
171
+ > machinery — see [ARCHITECTURE.md](ARCHITECTURE.md).
172
+
173
+ ## Setting up a Project (Kshetra) in detail
174
+
175
+ Before running `shreni init-kshetra`, the project git repo must already exist and
176
+ have a GitHub remote configured. `init-kshetra` reads the remote URL from the repo
177
+ (`git remote get-url origin`) to populate `kshetra.yaml` — it does not create the
178
+ project repo for you.
179
+
180
+ ```bash
181
+ # Create and push the project repo first (if it doesn't exist yet)
182
+ gh repo create <your-org>/myapp --private --clone
183
+ cd myapp
184
+ git remote -v # confirm origin is set
185
+ ```
186
+
187
+ Then register the project. This is a one-time setup per project:
188
+
189
+ ```bash
190
+ shreni init-kshetra --slug myapp --path /projects/myapp
191
+ ```
192
+
193
+ This command runs 10 steps automatically:
194
+
195
+ 1. Creates `<your-org>/myapp-beads` on GitHub
196
+ 2. Clones the beads repo to `/projects/myapp-beads`
197
+ 3. Initialises the `bd` database (`bd init --stealth`)
198
+ 4. Creates symlink: `/projects/myapp/.beads → /projects/myapp-beads`
199
+ 5. Appends `.beads` to `/projects/myapp/.gitignore`
200
+ 6. Installs Claude Code hooks (`bd setup claude`) — auto-injects project context at session start
201
+ 7. Generates `.shreni/kshetra.yaml` from the project template
202
+ 8. Appends a `SHRENI INTEGRATION` section to `CLAUDE.md` defining the interactive session role boundary
203
+ 9. Builds the initial RAG index for codebase search
204
+ 10. Registers the Kshetra with Sthapathi
205
+
206
+ After init, edit `.shreni/kshetra.yaml` to set your stack and conventions:
207
+
208
+ ```yaml
209
+ stack:
210
+ language: typescript
211
+ framework: nextjs
212
+ testRunner: vitest
213
+ linter: eslint
214
+
215
+ agents:
216
+ provider: claude # supported provider; codex / gemini are experimental
217
+ model: claude-sonnet-4-6
218
+ maxRoundsPerBead: 3
219
+ ```
220
+
221
+ > **Agent providers.** **Claude** (`claude`) is the supported, default provider.
222
+ > Adapters for **Codex** (`codex`) and **Gemini** (`gemini`) are wired but
223
+ > **experimental** — draft and not verified end-to-end — and ship with no default
224
+ > model, so they require an explicit `agents.model`. `shreni init-kshetra` warns
225
+ > you if you pick one. If you want a reliable first run, use Claude.
226
+
227
+ ### Config source of truth
228
+
229
+ There is **exactly one config per Kshetra**, at `<repo>/.shreni/kshetra.yaml`, and
230
+ `~/.shreni/registry.json` is the only thing that resolves `id → configPath`. The
231
+ `.shreni/` directory is the Kshetra's home for all Shreni-owned assets (the config
232
+ plus the `style-guide.md` / `arch.md` conventions docs it references), which keeps
233
+ the target repo root clean.
234
+
235
+ - **Absolute paths only.** `repo.path` and `beads.path` are used verbatim as the
236
+ cwd for git and exec — the loader does **not** expand `~` or resolve relative
237
+ paths. `init` writes absolute paths; `migrate` absolutizes them.
238
+ - **Resolution.** `shreni register <dir>` prefers `<dir>/.shreni/kshetra.yaml` and
239
+ falls back to a legacy root `<dir>/kshetra.yaml`.
240
+ - **Migrating a legacy layout.** If a project still has a root `kshetra.yaml`, run
241
+ `shreni migrate <dir>` to move it into `.shreni/`, absolutize its paths,
242
+ re-register it, and remove the root file. It is idempotent — safe to re-run.
243
+
244
+ ### Merge policy (push vs pr)
245
+
246
+ `repo.mergePolicy` decides **where approved work lands** — independently of *when*
247
+ the next task starts (that is always driven by the `bd` dependency graph):
248
+
249
+ | Policy | On APPROVE | Task closes | Use when |
250
+ |---|---|---|---|
251
+ | `push` (default) | Squash-merge the bead branch straight to `main` and push | Immediately | Solo, high-trust, fastest loop |
252
+ | `pr` | Push the branch and open a **pull request** (`bead-…` → `main`); do **not** merge | Only when the PR actually merges | You want a human gate, or a team merge queue |
253
+
254
+ In `pr` mode the bead is kept **open** (labelled `awaiting-merge`) so anything that
255
+ depends on it stays blocked until the code is really on `main`. Sthapathi does not
256
+ wait around: it immediately picks the next ready bead branching from the current
257
+ `main`. A background reconcile pass closes the bead when its PR merges, or blocks it
258
+ for review if the PR is closed unmerged. The Silpi ↔ Viharapala AI review runs in
259
+ both modes — `pr` mode adds a human merge gate *on top of* it, it does not replace it.
260
+
261
+ Set it at init or in `kshetra.yaml`, and override per run with an env var:
262
+
263
+ ```bash
264
+ shreni init-kshetra --slug myapp --path /projects/myapp --merge-policy pr
265
+ ```
266
+
267
+ ```yaml
268
+ repo:
269
+ path: /projects/myapp
270
+ remote: git@github.com:your-org/myapp.git
271
+ mainBranch: main
272
+ mergePolicy: pr # omit for the default 'push'
273
+ ```
274
+
275
+ ```bash
276
+ SHRENI_MERGE_POLICY=pr shreni start # runtime override of the config, all Kshetras
277
+ ```
278
+
279
+ > `pr` mode uses the `gh` CLI (already a prerequisite) to open and inspect PRs, so
280
+ > `gh` must be authenticated for the account that owns the project repo.
281
+
282
+ ## Running the Harness
283
+
284
+ ### Start / Stop
285
+
286
+ ```bash
287
+ shreni start # start the Sthapathi orchestration loop
288
+ shreni stop # graceful shutdown (waits for active round to finish)
289
+ ```
290
+
291
+ Sthapathi polls each registered Kshetra every 30 seconds for ready tasks. P0-priority tasks interrupt the queue immediately.
292
+
293
+ ### Check Status
294
+
295
+ ```bash
296
+ shreni status # current Kshetra (auto-detected from cwd)
297
+ shreni status --all # all Kshetras
298
+ shreni agents # which agent is active per Kshetra and what it's working on
299
+ ```
300
+
301
+ ### Kshetra States
302
+
303
+ | State | Meaning | Next action |
304
+ |---|---|---|
305
+ | `idle` | No pending tasks, loop is running | File a task via `bd create` |
306
+ | `running` | Sthapathi is actively processing a bead | Wait, or `shreni agents` for detail |
307
+ | `paused` | Manually paused or paused due to an error | `shreni resume --kshetra <slug>` |
308
+ | `error` | Unrecoverable state, loop stopped | Check logs, resolve the issue, then `shreni resume` |
309
+
310
+ ### Bead (Task) States
311
+
312
+ | State | Meaning |
313
+ |---|---|
314
+ | `pending` | Filed, waiting to be picked up |
315
+ | `in_progress` | Claimed by Sthapathi, agents are working on it |
316
+ | `blocked` | Exceeded max rounds, or a hard failure occurred — needs human review |
317
+ | `complete` | Merged to `main`, `bd close` called |
318
+
319
+ ### Per-Kshetra Controls
320
+
321
+ ```bash
322
+ shreni pause --kshetra myapp # pause without stopping other Kshetras
323
+ shreni resume --kshetra myapp # resume a paused Kshetra
324
+ shreni run --kshetra myapp # force one cycle immediately (useful for testing)
325
+ shreni sync --kshetra myapp # force beads git pull + push
326
+ ```
327
+
328
+ ### Logs
329
+
330
+ ```bash
331
+ shreni logs --kshetra myapp
332
+ shreni logs --kshetra myapp --bead bd-f3a2 # logs for a specific bead
333
+ shreni logs --all
334
+ ```
335
+
336
+ ### Phalaka (Local Dashboard)
337
+
338
+ ```bash
339
+ shreni phalaka start # start the local dashboard server
340
+ shreni phalaka stop
341
+ shreni phalaka status # server URL
342
+ ```
343
+
344
+ Once started, the dashboard is served on loopback (`127.0.0.1`) — open the printed URL in your browser to watch worker status, task progress, and stuck-state alerts across all Kshetras.
345
+
346
+ ## Telemetry (opt-in, anonymous)
347
+
348
+ Shreni collects **no telemetry by default**. If you opt in, it sends a small,
349
+ anonymous signal that helps us understand activation (did a clone reach a first
350
+ merged task?) and retention — nothing else.
351
+
352
+ ```bash
353
+ shreni telemetry status # show the current setting
354
+ shreni telemetry enable # opt in (prints exactly what is sent)
355
+ shreni telemetry disable # opt back out any time
356
+ ```
357
+
358
+ When enabled, an event carries only: a random anonymous id, the event name
359
+ (`session_start`, `kshetra_init`, `task_merged`), the Shreni version, and your OS
360
+ platform. It **never** sends your code, file paths, repo names, task contents, or
361
+ any personal identifier. Set `DO_NOT_TRACK=1` (or `SHRENI_TELEMETRY=0`) to hard-
362
+ disable it regardless of config; `SHRENI_TELEMETRY=1` opts in for one run. Until a
363
+ collector endpoint is configured, opted-in events are written to a local file
364
+ (`~/.shreni/telemetry-local.jsonl`) and never leave your machine.
365
+
366
+ ## Troubleshooting
367
+
368
+ ### Harness won't start — `registry.json` missing
369
+
370
+ ```
371
+ Error: ~/.shreni/registry.json not found
372
+ ```
373
+
374
+ No Kshetras are registered. Either run `shreni init-kshetra` for a new project or `shreni register /path/to/project` for an existing one.
375
+
376
+ ---
377
+
378
+ ### Task stuck in `in_progress` after restart
379
+
380
+ Sthapathi automatically recovers in-flight tasks on startup by reading `bd` round notes and the git branch state. If a task remains stuck after restart:
381
+
382
+ ```bash
383
+ bd show <id> # read the last round note to see where it stopped
384
+ shreni logs --bead <id> # check harness logs for the error
385
+ ```
386
+
387
+ If recovery failed, unblock manually and let Sthapathi retry:
388
+
389
+ ```bash
390
+ bd update <id> --unblock
391
+ ```
392
+
393
+ ---
394
+
395
+ ### Kshetra is paused with `requiresManualResume: true`
396
+
397
+ This happens after a git failure or `bd` database error. The harness will not auto-resume these.
398
+
399
+ ```bash
400
+ shreni status --all # identify the paused Kshetra and reason
401
+ bd show <blocked-bead-id> # read the error detail in round notes
402
+ # Fix the underlying issue (resolve git conflict, free disk space, etc.)
403
+ shreni resume --kshetra <slug> # clear the pause and restart the loop
404
+ ```
405
+
406
+ ---
407
+
408
+ ### Push rejected — non-fast-forward
409
+
410
+ Sthapathi retries once automatically with a pull-rebase. If it fails twice, it blocks the bead and pauses the Kshetra. Resolve manually:
411
+
412
+ ```bash
413
+ cd /projects/<slug>
414
+ git pull --rebase origin main
415
+ git push origin main
416
+ shreni resume --kshetra <slug>
417
+ bd update <blocked-bead-id> --unblock
418
+ ```
419
+
420
+ ---
421
+
422
+ ### Merge conflict outside task scope
423
+
424
+ Silpi touched files it wasn't supposed to. The bead is blocked and the Kshetra is paused for human review.
425
+
426
+ ```bash
427
+ bd show <id> # see which files conflicted
428
+ git diff bead-<id>/<slug> # inspect Silpi's changes
429
+ # Resolve the conflict manually, or close the bead and re-file a cleaner task
430
+ bd update <id> --unblock # let Sthapathi retry
431
+ shreni resume --kshetra <slug>
432
+ ```
433
+
434
+ ---
435
+
436
+ ### Agent output malformed / JSON parse error
437
+
438
+ Sthapathi retries the round once automatically. If it fails again, the bead is blocked:
439
+
440
+ ```bash
441
+ bd show <id> # round note shows the parse error detail
442
+ bd update <id> --unblock # let Sthapathi retry from round 1
443
+ ```
444
+
445
+ If this recurs for the same task, the task description may be too ambiguous:
446
+
447
+ ```bash
448
+ bd update <id> --description "More precise acceptance criteria"
449
+ bd update <id> --unblock
450
+ ```
451
+
452
+ ---
453
+
454
+ ### Anthropic API rate limit (429) or overloaded (529)
455
+
456
+ Sthapathi retries with exponential backoff (up to 3×, max 60s between retries). If all retries are exhausted, the Kshetra pauses for 5 minutes and auto-resumes. No action is needed unless the outage is prolonged.
457
+
458
+ ---
459
+
460
+ ### `bd` database locked
461
+
462
+ `bd` uses embedded Dolt which is single-writer. If another process holds the lock:
463
+
464
+ ```bash
465
+ lsof +D /projects/<slug>-beads/embeddeddolt # find the lock holder
466
+ # kill the blocking process, then:
467
+ shreni resume --kshetra <slug>
468
+ ```
469
+
470
+ ---
471
+
472
+ ### RAG search returning stale results
473
+
474
+ The index rebuilds incrementally on every merged bead. To force a full rebuild:
475
+
476
+ ```bash
477
+ shreni index rebuild --kshetra <slug>
478
+ shreni index status
479
+ ```
480
+
481
+ ---
482
+
483
+ ### Interactive Claude Code session not seeing project tasks
484
+
485
+ The `SessionStart` hook (`bd prime`) should run automatically when you open a Claude Code session in the project directory. If it's not firing:
486
+
487
+ ```bash
488
+ bd doctor # check hook installation
489
+ bd setup claude # reinstall the hooks
490
+ ```
491
+
492
+ Verify hooks are present in `~/.claude/settings.json`:
493
+
494
+ ```json
495
+ {
496
+ "hooks": {
497
+ "SessionStart": ["bd prime"],
498
+ "PreCompact": ["bd prime"]
499
+ }
500
+ }
501
+ ```
502
+
503
+ ## License & Trademark
504
+
505
+ Shreni's source code is licensed under the [Apache License 2.0](LICENSE) — free to
506
+ use, modify, and redistribute, including commercially.
507
+
508
+ **Shreni™** and **TeakWood™** are trademarks of TeakWood. An open-source license
509
+ covers the *code*, not the *name* (Apache-2.0 §6 grants no trademark rights). See
510
+ [TRADEMARK.md](TRADEMARK.md) for how you may use the names and logos — short
511
+ version: use the software freely; just don't name your fork "Shreni" or imply our
512
+ endorsement.
513
+
514
+ ## Contributing
515
+
516
+ Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) (contributions
517
+ are under the Developer Certificate of Origin) and our
518
+ [Code of Conduct](CODE_OF_CONDUCT.md). To report a security issue, see
519
+ [SECURITY.md](SECURITY.md).
package/TRADEMARK.md ADDED
@@ -0,0 +1,97 @@
1
+ # Trademark Policy
2
+
3
+ **Shreni™** and **TeakWood™** are trademarks of TeakWood ("we", "us"). This policy
4
+ explains how you may — and may not — use these names and any associated logos.
5
+
6
+ > This is a plain-language summary of our trademark policy, not legal advice. It
7
+ > does not grant any rights beyond those described here.
8
+
9
+ ## Why this exists
10
+
11
+ Shreni's **source code** is free and open under the
12
+ [Apache License 2.0](LICENSE) — you may use, modify, and redistribute it, including
13
+ commercially. But an open-source license covers *copyright*, not *trademarks*.
14
+ Apache-2.0 says so explicitly (Section 6: it grants no trademark rights).
15
+
16
+ Trademarks exist to protect **users**, not to restrict the code. When someone sees
17
+ "Shreni," they should be able to trust it refers to *this* project — the software
18
+ we publish — and not a modified fork, an unrelated product, or something that
19
+ merely claims a connection to us. This policy keeps the name trustworthy while the
20
+ code stays free.
21
+
22
+ **The guiding principle:** use that could confuse people about the origin of the
23
+ software, or imply our sponsorship or endorsement when there is none, is not
24
+ allowed. Honest, accurate references are fine.
25
+
26
+ ## Uses that do NOT require permission
27
+
28
+ You may, without asking us:
29
+
30
+ - **Use the software.** Running, evaluating, and building on Shreni under the
31
+ Apache-2.0 license needs no trademark permission at all.
32
+ - **Redistribute unmodified copies** under the name "Shreni," provided you don't
33
+ remove or alter our notices and you don't imply we endorse your distribution.
34
+ - **Refer to the project accurately** — in articles, talks, documentation,
35
+ tutorials, book titles, and social media. E.g. "a guide to Shreni,"
36
+ "deployed with Shreni," "benchmarking Shreni."
37
+ - **State compatibility or integration** truthfully — "works with Shreni,"
38
+ "compatible with Shreni," "a plugin for Shreni" — as long as it doesn't suggest
39
+ your product *is* Shreni or is official.
40
+ - **Run community activities** (user groups, meetups, discussion forums) that use
41
+ the name descriptively, provided it's clear you speak for the community, not for
42
+ TeakWood.
43
+
44
+ When you use the name referentially, use it as an adjective followed by a common
45
+ noun ("the Shreni harness," "a Shreni deployment"), keep the spelling and
46
+ capitalization as **Shreni**, and don't make it the most prominent element of your
47
+ own branding.
48
+
49
+ ## Uses that DO require our written permission
50
+
51
+ Please ask us first before you:
52
+
53
+ - **Name a modified version, fork, product, or service "Shreni"** (or a
54
+ confusingly similar name). If you distribute a modified version, give it a
55
+ **different name** — you may state that it is "based on Shreni" or "a fork of
56
+ Shreni." (See below.)
57
+ - Use "Shreni" or "TeakWood" in the name of your **company, product, service,
58
+ app, domain name, or social-media account** in a way that could suggest
59
+ affiliation or endorsement.
60
+ - Use the names or logos on **merchandise** (shirts, stickers, swag) for
61
+ distribution or sale.
62
+ - Use the names in a manner that **states or implies TeakWood's sponsorship,
63
+ affiliation, or endorsement** of your project, product, event, or organization.
64
+ - Use the **logo** in a modified form, or in any context beyond an accurate,
65
+ unaltered reference to the project.
66
+
67
+ ## Modified versions and forks
68
+
69
+ The Apache-2.0 license lets you fork and modify freely — that's encouraged. But a
70
+ modified version is **not** the software we publish, so it must not carry our name
71
+ as its identity. If you distribute a modified build:
72
+
73
+ - Choose your own name for it, and
74
+ - You may accurately describe its lineage: "a fork of Shreni,"
75
+ "based on Shreni by TeakWood," or "derived from Shreni."
76
+
77
+ This lets users tell official releases from third-party modifications — which is
78
+ the whole point.
79
+
80
+ ## Logos
81
+
82
+ Any Shreni or TeakWood logos are also trademarks. You may use an **unaltered** logo
83
+ solely to make an accurate reference to the project (e.g. linking to this
84
+ repository). Do not modify a logo, change its colors, or use it as the icon for
85
+ your own product without written permission.
86
+
87
+ ## Requesting permission
88
+
89
+ For any use that requires permission, or if you're unsure, email
90
+ **teakwood.dev@gmail.com** with a short description of the intended use. We aim to
91
+ be reasonable and quick — the goal is to prevent confusion, not to say no to
92
+ good-faith use.
93
+
94
+ ## Changes
95
+
96
+ We may update this policy as the project evolves. The current version always lives
97
+ in this file in the [Shreni repository](https://github.com/TeakWood/Shreni).
@@ -0,0 +1,11 @@
1
+ import type { KshetraConfig } from '../kshetra/config.js';
2
+ import type { Task, ParikshakaOutput } from '../sthapathi/types.js';
3
+ export interface ParikshakaContext {
4
+ kshetra: KshetraConfig;
5
+ task: Task;
6
+ mergedDiff: string;
7
+ existingTestFiles: string[];
8
+ personas?: string;
9
+ }
10
+ export declare function runParikshaka(ctx: ParikshakaContext): Promise<ParikshakaOutput>;
11
+ //# sourceMappingURL=parikshaka.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parikshaka.d.ts","sourceRoot":"","sources":["../../src/agents/parikshaka.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIpE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAqED,wBAAsB,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsBrF"}