wraithd 0.0.1__tar.gz

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. wraithd-0.0.1/.gitignore +19 -0
  2. wraithd-0.0.1/LICENSE +21 -0
  3. wraithd-0.0.1/PKG-INFO +161 -0
  4. wraithd-0.0.1/README.md +118 -0
  5. wraithd-0.0.1/docs/README.md +82 -0
  6. wraithd-0.0.1/docs/api.md +359 -0
  7. wraithd-0.0.1/docs/browser.md +59 -0
  8. wraithd-0.0.1/docs/caching.md +78 -0
  9. wraithd-0.0.1/docs/channels.md +64 -0
  10. wraithd-0.0.1/docs/compaction.md +38 -0
  11. wraithd-0.0.1/docs/daemon.md +64 -0
  12. wraithd-0.0.1/docs/ec2-to-laptop.md +47 -0
  13. wraithd-0.0.1/docs/evals.md +250 -0
  14. wraithd-0.0.1/docs/event-log.md +58 -0
  15. wraithd-0.0.1/docs/files.md +72 -0
  16. wraithd-0.0.1/docs/first-launch.md +251 -0
  17. wraithd-0.0.1/docs/heartbeat.md +34 -0
  18. wraithd-0.0.1/docs/install.md +103 -0
  19. wraithd-0.0.1/docs/keys.md +96 -0
  20. wraithd-0.0.1/docs/lockdown.md +248 -0
  21. wraithd-0.0.1/docs/mcp.md +95 -0
  22. wraithd-0.0.1/docs/memory-provenance.md +57 -0
  23. wraithd-0.0.1/docs/memory.md +65 -0
  24. wraithd-0.0.1/docs/models.md +36 -0
  25. wraithd-0.0.1/docs/one-loop.md +45 -0
  26. wraithd-0.0.1/docs/progressive-disclosure.md +47 -0
  27. wraithd-0.0.1/docs/proof.md +40 -0
  28. wraithd-0.0.1/docs/release.md +72 -0
  29. wraithd-0.0.1/docs/reminders.md +81 -0
  30. wraithd-0.0.1/docs/remote-access.md +84 -0
  31. wraithd-0.0.1/docs/review-queue.md +60 -0
  32. wraithd-0.0.1/docs/run.md +70 -0
  33. wraithd-0.0.1/docs/sandbox.md +118 -0
  34. wraithd-0.0.1/docs/scheduler.md +29 -0
  35. wraithd-0.0.1/docs/schedules.md +34 -0
  36. wraithd-0.0.1/docs/seams.md +163 -0
  37. wraithd-0.0.1/docs/security.md +116 -0
  38. wraithd-0.0.1/docs/shell.md +39 -0
  39. wraithd-0.0.1/docs/skill-proposals.md +24 -0
  40. wraithd-0.0.1/docs/skills.md +76 -0
  41. wraithd-0.0.1/docs/spill.md +56 -0
  42. wraithd-0.0.1/docs/subagents.md +36 -0
  43. wraithd-0.0.1/docs/telegram.md +77 -0
  44. wraithd-0.0.1/docs/tokens.md +77 -0
  45. wraithd-0.0.1/docs/web.md +67 -0
  46. wraithd-0.0.1/docs/whatsapp.md +156 -0
  47. wraithd-0.0.1/pyproject.toml +89 -0
  48. wraithd-0.0.1/scripts/release.sh +49 -0
  49. wraithd-0.0.1/src/wraithd/__init__.py +5 -0
  50. wraithd-0.0.1/src/wraithd/__main__.py +5 -0
  51. wraithd-0.0.1/src/wraithd/audit.py +251 -0
  52. wraithd-0.0.1/src/wraithd/channels/__init__.py +1 -0
  53. wraithd-0.0.1/src/wraithd/channels/base.py +318 -0
  54. wraithd-0.0.1/src/wraithd/channels/conversation.py +26 -0
  55. wraithd-0.0.1/src/wraithd/channels/telegram.py +238 -0
  56. wraithd-0.0.1/src/wraithd/channels/terminal.py +111 -0
  57. wraithd-0.0.1/src/wraithd/cli.py +319 -0
  58. wraithd-0.0.1/src/wraithd/config.py +414 -0
  59. wraithd-0.0.1/src/wraithd/core/__init__.py +13 -0
  60. wraithd-0.0.1/src/wraithd/core/compaction.py +64 -0
  61. wraithd-0.0.1/src/wraithd/core/delegate.py +116 -0
  62. wraithd-0.0.1/src/wraithd/core/disclosure.py +261 -0
  63. wraithd-0.0.1/src/wraithd/core/egress.py +115 -0
  64. wraithd-0.0.1/src/wraithd/core/events.py +150 -0
  65. wraithd-0.0.1/src/wraithd/core/gate.py +748 -0
  66. wraithd-0.0.1/src/wraithd/core/hooks.py +59 -0
  67. wraithd-0.0.1/src/wraithd/core/inspector.py +180 -0
  68. wraithd-0.0.1/src/wraithd/core/loop.py +99 -0
  69. wraithd-0.0.1/src/wraithd/core/reminders.py +279 -0
  70. wraithd-0.0.1/src/wraithd/core/render.py +91 -0
  71. wraithd-0.0.1/src/wraithd/core/replay.py +87 -0
  72. wraithd-0.0.1/src/wraithd/core/secrets.py +87 -0
  73. wraithd-0.0.1/src/wraithd/core/stop.py +90 -0
  74. wraithd-0.0.1/src/wraithd/core/tokens.py +303 -0
  75. wraithd-0.0.1/src/wraithd/core/tool_results.py +57 -0
  76. wraithd-0.0.1/src/wraithd/core/views.py +93 -0
  77. wraithd-0.0.1/src/wraithd/daemon/__init__.py +4 -0
  78. wraithd-0.0.1/src/wraithd/daemon/api.py +537 -0
  79. wraithd-0.0.1/src/wraithd/daemon/app.py +111 -0
  80. wraithd-0.0.1/src/wraithd/daemon/commands.py +150 -0
  81. wraithd-0.0.1/src/wraithd/daemon/heartbeat.py +213 -0
  82. wraithd-0.0.1/src/wraithd/daemon/jobs.py +88 -0
  83. wraithd-0.0.1/src/wraithd/daemon/scheduler.py +51 -0
  84. wraithd-0.0.1/src/wraithd/daemon/security.py +112 -0
  85. wraithd-0.0.1/src/wraithd/daemon/service.py +316 -0
  86. wraithd-0.0.1/src/wraithd/doctor.py +184 -0
  87. wraithd-0.0.1/src/wraithd/evals/__init__.py +0 -0
  88. wraithd-0.0.1/src/wraithd/evals/__main__.py +75 -0
  89. wraithd-0.0.1/src/wraithd/evals/meter.py +129 -0
  90. wraithd-0.0.1/src/wraithd/evals/runner.py +451 -0
  91. wraithd-0.0.1/src/wraithd/evals/scripted.py +210 -0
  92. wraithd-0.0.1/src/wraithd/evals/site.py +50 -0
  93. wraithd-0.0.1/src/wraithd/evals/tasks.py +302 -0
  94. wraithd-0.0.1/src/wraithd/evals/world.py +207 -0
  95. wraithd-0.0.1/src/wraithd/mcp/__init__.py +4 -0
  96. wraithd-0.0.1/src/wraithd/mcp/client.py +194 -0
  97. wraithd-0.0.1/src/wraithd/mcp/commands.py +262 -0
  98. wraithd-0.0.1/src/wraithd/mcp/config.py +210 -0
  99. wraithd-0.0.1/src/wraithd/mcp/pinning.py +245 -0
  100. wraithd-0.0.1/src/wraithd/memory/__init__.py +6 -0
  101. wraithd-0.0.1/src/wraithd/memory/distill.py +119 -0
  102. wraithd-0.0.1/src/wraithd/memory/notes.py +135 -0
  103. wraithd-0.0.1/src/wraithd/memory/review.py +98 -0
  104. wraithd-0.0.1/src/wraithd/memory/tools.py +207 -0
  105. wraithd-0.0.1/src/wraithd/memory/vault.py +233 -0
  106. wraithd-0.0.1/src/wraithd/onboard.py +337 -0
  107. wraithd-0.0.1/src/wraithd/providers.py +230 -0
  108. wraithd-0.0.1/src/wraithd/rename.py +130 -0
  109. wraithd-0.0.1/src/wraithd/review/__init__.py +1 -0
  110. wraithd-0.0.1/src/wraithd/review/api.py +70 -0
  111. wraithd-0.0.1/src/wraithd/review/cli.py +91 -0
  112. wraithd-0.0.1/src/wraithd/review/queue.py +262 -0
  113. wraithd-0.0.1/src/wraithd/run.py +392 -0
  114. wraithd-0.0.1/src/wraithd/sandbox/__init__.py +90 -0
  115. wraithd-0.0.1/src/wraithd/sandbox/audit.py +69 -0
  116. wraithd-0.0.1/src/wraithd/sandbox/docker.py +87 -0
  117. wraithd-0.0.1/src/wraithd/sandbox/settings.py +61 -0
  118. wraithd-0.0.1/src/wraithd/schedules.py +112 -0
  119. wraithd-0.0.1/src/wraithd/skills/__init__.py +4 -0
  120. wraithd-0.0.1/src/wraithd/skills/library/inbox-triage/SKILL.md +24 -0
  121. wraithd-0.0.1/src/wraithd/skills/library/meeting-prep/SKILL.md +20 -0
  122. wraithd-0.0.1/src/wraithd/skills/library/morning-brief/SKILL.md +20 -0
  123. wraithd-0.0.1/src/wraithd/skills/library/research-report/SKILL.md +16 -0
  124. wraithd-0.0.1/src/wraithd/skills/library/research-report/report-template.md +16 -0
  125. wraithd-0.0.1/src/wraithd/skills/library/skill-writer/SKILL.md +19 -0
  126. wraithd-0.0.1/src/wraithd/skills/library/weekly-review/SKILL.md +18 -0
  127. wraithd-0.0.1/src/wraithd/skills/registry.py +227 -0
  128. wraithd-0.0.1/src/wraithd/skills/review.py +166 -0
  129. wraithd-0.0.1/src/wraithd/skills/tools.py +138 -0
  130. wraithd-0.0.1/src/wraithd/spill/__init__.py +91 -0
  131. wraithd-0.0.1/src/wraithd/store/__init__.py +22 -0
  132. wraithd-0.0.1/src/wraithd/store/base.py +184 -0
  133. wraithd-0.0.1/src/wraithd/store/modules.py +115 -0
  134. wraithd-0.0.1/src/wraithd/store/sqlite.py +383 -0
  135. wraithd-0.0.1/src/wraithd/tools/__init__.py +95 -0
  136. wraithd-0.0.1/src/wraithd/tools/base.py +46 -0
  137. wraithd-0.0.1/src/wraithd/tools/browser.py +485 -0
  138. wraithd-0.0.1/src/wraithd/tools/documents.py +214 -0
  139. wraithd-0.0.1/src/wraithd/tools/files.py +350 -0
  140. wraithd-0.0.1/src/wraithd/tools/notify.py +45 -0
  141. wraithd-0.0.1/src/wraithd/tools/schedules.py +64 -0
  142. wraithd-0.0.1/src/wraithd/tools/shell.py +97 -0
  143. wraithd-0.0.1/src/wraithd/tools/web.py +426 -0
  144. wraithd-0.0.1/src/wraithd/ui/assets/index-B9FtiVGr.css +1 -0
  145. wraithd-0.0.1/src/wraithd/ui/assets/index-E7uVIjF7.js +15 -0
  146. wraithd-0.0.1/src/wraithd/ui/assets/instrument-serif-latin-400-italic-DKMiL14s.woff2 +0 -0
  147. wraithd-0.0.1/src/wraithd/ui/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  148. wraithd-0.0.1/src/wraithd/ui/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  149. wraithd-0.0.1/src/wraithd/ui/assets/inter-tight-latin-wght-normal-DX-nOvPD.woff2 +0 -0
  150. wraithd-0.0.1/src/wraithd/ui/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  151. wraithd-0.0.1/src/wraithd/ui/assets/server-DdTQ3pZ0.js +22 -0
  152. wraithd-0.0.1/src/wraithd/ui/favicon.svg +1 -0
  153. wraithd-0.0.1/src/wraithd/ui/index.html +17 -0
  154. wraithd-0.0.1/src/wraithd/update.py +59 -0
  155. wraithd-0.0.1/src/wraithd/voice.py +157 -0
  156. wraithd-0.0.1/tests/__init__.py +0 -0
  157. wraithd-0.0.1/tests/attacks/__init__.py +0 -0
  158. wraithd-0.0.1/tests/attacks/conftest.py +1 -0
  159. wraithd-0.0.1/tests/attacks/test_attacks.py +249 -0
  160. wraithd-0.0.1/tests/attacks/test_capabilities_browser.py +191 -0
  161. wraithd-0.0.1/tests/attacks/test_efficiency_spill.py +60 -0
  162. wraithd-0.0.1/tests/attacks/test_evals_empty_result.py +37 -0
  163. wraithd-0.0.1/tests/attacks/test_reach_remote.py +47 -0
  164. wraithd-0.0.1/tests/attacks/test_sandbox_escape.py +97 -0
  165. wraithd-0.0.1/tests/attacks/test_security_memory.py +140 -0
  166. wraithd-0.0.1/tests/capabilities/__init__.py +0 -0
  167. wraithd-0.0.1/tests/capabilities/fakes.py +55 -0
  168. wraithd-0.0.1/tests/capabilities/test_browser.py +98 -0
  169. wraithd-0.0.1/tests/capabilities/test_delegate.py +177 -0
  170. wraithd-0.0.1/tests/capabilities/test_heartbeat.py +172 -0
  171. wraithd-0.0.1/tests/capabilities/test_inspector_and_prefix.py +71 -0
  172. wraithd-0.0.1/tests/capabilities/test_skill_review.py +146 -0
  173. wraithd-0.0.1/tests/channels/__init__.py +0 -0
  174. wraithd-0.0.1/tests/channels/test_terminal.py +115 -0
  175. wraithd-0.0.1/tests/conftest.py +118 -0
  176. wraithd-0.0.1/tests/core/__init__.py +0 -0
  177. wraithd-0.0.1/tests/core/record_runs.py +57 -0
  178. wraithd-0.0.1/tests/core/runs/clean_run.json +123 -0
  179. wraithd-0.0.1/tests/core/runs/loop_stop.json +227 -0
  180. wraithd-0.0.1/tests/core/runs/third_party_content.json +129 -0
  181. wraithd-0.0.1/tests/core/runs/tool_errors_stop.json +227 -0
  182. wraithd-0.0.1/tests/core/test_compaction.py +66 -0
  183. wraithd-0.0.1/tests/core/test_disclosure.py +178 -0
  184. wraithd-0.0.1/tests/core/test_gate.py +226 -0
  185. wraithd-0.0.1/tests/core/test_image_input.py +31 -0
  186. wraithd-0.0.1/tests/core/test_loop.py +252 -0
  187. wraithd-0.0.1/tests/core/test_reminders.py +194 -0
  188. wraithd-0.0.1/tests/core/test_replay.py +52 -0
  189. wraithd-0.0.1/tests/core/test_security.py +260 -0
  190. wraithd-0.0.1/tests/core/test_views_and_stop.py +90 -0
  191. wraithd-0.0.1/tests/daemon/__init__.py +0 -0
  192. wraithd-0.0.1/tests/daemon/conftest.py +25 -0
  193. wraithd-0.0.1/tests/daemon/test_api.py +344 -0
  194. wraithd-0.0.1/tests/daemon/test_api_pinning.py +31 -0
  195. wraithd-0.0.1/tests/daemon/test_security.py +94 -0
  196. wraithd-0.0.1/tests/daemon/test_service.py +189 -0
  197. wraithd-0.0.1/tests/daemon/test_telegram.py +262 -0
  198. wraithd-0.0.1/tests/daemon/test_telegram_attachments.py +271 -0
  199. wraithd-0.0.1/tests/efficiency/__init__.py +0 -0
  200. wraithd-0.0.1/tests/efficiency/fakes.py +75 -0
  201. wraithd-0.0.1/tests/efficiency/record_runs.py +27 -0
  202. wraithd-0.0.1/tests/efficiency/runs/conversation_run.json +109 -0
  203. wraithd-0.0.1/tests/efficiency/runs/tool_run.json +177 -0
  204. wraithd-0.0.1/tests/efficiency/scenarios.py +39 -0
  205. wraithd-0.0.1/tests/efficiency/test_caching.py +195 -0
  206. wraithd-0.0.1/tests/efficiency/test_models.py +175 -0
  207. wraithd-0.0.1/tests/efficiency/test_spill.py +146 -0
  208. wraithd-0.0.1/tests/efficiency/test_tokens.py +111 -0
  209. wraithd-0.0.1/tests/evals/__init__.py +0 -0
  210. wraithd-0.0.1/tests/evals/fake_openai.py +147 -0
  211. wraithd-0.0.1/tests/evals/test_empty_result.py +87 -0
  212. wraithd-0.0.1/tests/evals/test_evals.py +190 -0
  213. wraithd-0.0.1/tests/evals/test_ollama_path.py +45 -0
  214. wraithd-0.0.1/tests/evals/test_phase9_tasks.py +117 -0
  215. wraithd-0.0.1/tests/evals/test_regressions.py +71 -0
  216. wraithd-0.0.1/tests/evals/test_runs_and_judges.py +120 -0
  217. wraithd-0.0.1/tests/fixtures/fake_calendar_mcp.py +110 -0
  218. wraithd-0.0.1/tests/fixtures/fake_mcp.py +130 -0
  219. wraithd-0.0.1/tests/fixtures/services.py +62 -0
  220. wraithd-0.0.1/tests/mcp/__init__.py +0 -0
  221. wraithd-0.0.1/tests/mcp/test_mcp.py +342 -0
  222. wraithd-0.0.1/tests/memory/__init__.py +0 -0
  223. wraithd-0.0.1/tests/memory/test_memory_runs.py +167 -0
  224. wraithd-0.0.1/tests/memory/test_notes.py +72 -0
  225. wraithd-0.0.1/tests/memory/test_vault.py +87 -0
  226. wraithd-0.0.1/tests/reach/__init__.py +0 -0
  227. wraithd-0.0.1/tests/reach/test_channel.py +129 -0
  228. wraithd-0.0.1/tests/reach/test_log_rotation.py +107 -0
  229. wraithd-0.0.1/tests/reach/test_remote.py +106 -0
  230. wraithd-0.0.1/tests/sandbox/__init__.py +0 -0
  231. wraithd-0.0.1/tests/sandbox/fakes.py +21 -0
  232. wraithd-0.0.1/tests/sandbox/test_audit.py +106 -0
  233. wraithd-0.0.1/tests/sandbox/test_mcp_sandbox.py +103 -0
  234. wraithd-0.0.1/tests/sandbox/test_real_docker.py +67 -0
  235. wraithd-0.0.1/tests/sandbox/test_shell_docker.py +174 -0
  236. wraithd-0.0.1/tests/scripted.py +167 -0
  237. wraithd-0.0.1/tests/seams/__init__.py +0 -0
  238. wraithd-0.0.1/tests/seams/test_config_sections.py +69 -0
  239. wraithd-0.0.1/tests/seams/test_jobs.py +58 -0
  240. wraithd-0.0.1/tests/seams/test_marked_blocks.py +88 -0
  241. wraithd-0.0.1/tests/seams/test_models_and_run_options.py +106 -0
  242. wraithd-0.0.1/tests/seams/test_store_modules.py +79 -0
  243. wraithd-0.0.1/tests/seams/test_tool_results.py +74 -0
  244. wraithd-0.0.1/tests/security/__init__.py +0 -0
  245. wraithd-0.0.1/tests/security/test_audit_rules.py +99 -0
  246. wraithd-0.0.1/tests/security/test_mcp_commands.py +78 -0
  247. wraithd-0.0.1/tests/security/test_mcp_pinning.py +182 -0
  248. wraithd-0.0.1/tests/security/test_review_queue.py +227 -0
  249. wraithd-0.0.1/tests/skills/__init__.py +0 -0
  250. wraithd-0.0.1/tests/skills/test_adjustments.py +129 -0
  251. wraithd-0.0.1/tests/skills/test_skills.py +139 -0
  252. wraithd-0.0.1/tests/store/__init__.py +0 -0
  253. wraithd-0.0.1/tests/store/test_sqlite.py +163 -0
  254. wraithd-0.0.1/tests/test_audit.py +96 -0
  255. wraithd-0.0.1/tests/test_config.py +121 -0
  256. wraithd-0.0.1/tests/test_doctor_and_update.py +203 -0
  257. wraithd-0.0.1/tests/test_first_launch.py +202 -0
  258. wraithd-0.0.1/tests/test_keys_from_environment.py +79 -0
  259. wraithd-0.0.1/tests/test_onboard.py +231 -0
  260. wraithd-0.0.1/tests/test_rename.py +206 -0
  261. wraithd-0.0.1/tests/test_smoke.py +34 -0
  262. wraithd-0.0.1/tests/test_voice.py +115 -0
  263. wraithd-0.0.1/tests/tools/__init__.py +0 -0
  264. wraithd-0.0.1/tests/tools/test_documents.py +206 -0
  265. wraithd-0.0.1/tests/tools/test_files.py +340 -0
  266. wraithd-0.0.1/tests/tools/test_schedules.py +187 -0
  267. wraithd-0.0.1/tests/tools/test_shell.py +113 -0
  268. wraithd-0.0.1/tests/tools/test_web.py +434 -0
  269. wraithd-0.0.1/uv.lock +3022 -0
@@ -0,0 +1,19 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ .venv/
5
+ build/
6
+ dist/
7
+ *.egg-info/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .coverage
11
+
12
+ # The built web UI, copied in by scripts/release.sh
13
+ src/wraithd/ui/
14
+
15
+ # Claude Code worktrees (sessions working in isolation)
16
+ .claude/worktrees/
17
+
18
+ # Eval reports and run homes (python -m wraithd.evals)
19
+ eval-results/
wraithd-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shahar Ishay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
wraithd-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,161 @@
1
+ Metadata-Version: 2.5
2
+ Name: wraithd
3
+ Version: 0.0.1
4
+ Summary: A personal agent that runs on your own machine.
5
+ Project-URL: Homepage, https://github.com/shaharishay14/wraithd
6
+ Project-URL: Documentation, https://github.com/shaharishay14/wraithd/tree/main/docs
7
+ Project-URL: Source, https://github.com/shaharishay14/wraithd
8
+ Project-URL: Issues, https://github.com/shaharishay14/wraithd/issues
9
+ Project-URL: Changelog, https://github.com/shaharishay14/wraithd/releases
10
+ Author: Shahar Ishay
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: agent,ai,assistant,daemon,llm,local-first,mcp,self-hosted,telegram
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Environment :: Console
16
+ Classifier: Environment :: Web Environment
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Intended Audience :: End Users/Desktop
19
+ Classifier: Operating System :: MacOS
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3 :: Only
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Topic :: Communications :: Chat
25
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
26
+ Classifier: Topic :: Utilities
27
+ Requires-Python: >=3.12
28
+ Requires-Dist: croniter>=6
29
+ Requires-Dist: httpx>=0.28.1
30
+ Requires-Dist: keyring>=25
31
+ Requires-Dist: openai-agents[litellm]>=0.24.0
32
+ Requires-Dist: openpyxl>=3.1
33
+ Requires-Dist: pypdf>=5
34
+ Requires-Dist: pyyaml>=6
35
+ Requires-Dist: starlette>=0.40
36
+ Requires-Dist: tiktoken>=0.14
37
+ Requires-Dist: uvicorn>=0.30
38
+ Provides-Extra: browser
39
+ Requires-Dist: playwright>=1.48; extra == 'browser'
40
+ Provides-Extra: whisper
41
+ Requires-Dist: faster-whisper>=1.1; extra == 'whisper'
42
+ Description-Content-Type: text/markdown
43
+
44
+ <p align="center">
45
+ <picture>
46
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/shaharishay14/wraithd/main/docs/assets/hero-dark.webp">
47
+ <img alt="wraithd." src="https://raw.githubusercontent.com/shaharishay14/wraithd/main/docs/assets/hero-light.webp" width="100%">
48
+ </picture>
49
+ </p>
50
+
51
+ <p align="center">
52
+ <strong>A personal AI agent that runs on your own machine.</strong><br>
53
+ One package, your model, and you talk to it from the terminal, a local web page or Telegram.
54
+ </p>
55
+
56
+ <p align="center">
57
+ <a href="https://github.com/shaharishay14/wraithd/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/shaharishay14/wraithd/actions/workflows/ci.yml/badge.svg"></a>
58
+ <a href="https://github.com/shaharishay14/wraithd/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-111111.svg"></a>
59
+ <img alt="Python 3.12+" src="https://img.shields.io/badge/python-3.12%2B-111111.svg">
60
+ <img alt="macOS and Linux" src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux-111111.svg">
61
+ </p>
62
+
63
+ wraithd is an agent you own, the way you own your notes: one process on your Mac or Linux machine, its state as
64
+ plain files and one SQLite file in `~/.wraithd/`, nothing sent anywhere but your model provider (or nowhere, with a
65
+ local model through Ollama), Telegram if you pair it, and web searches. The rules that must hold (the permission
66
+ gate, taint tracking, the egress guard, budgets) live in code, not in the prompt, and every step of every run is an
67
+ event you can inspect.
68
+
69
+ > **Status:** v0.0.1, in development. The package installs below work after the first PyPI release; until then,
70
+ > [install from a checkout](#from-a-checkout).
71
+
72
+ ## Install
73
+
74
+ Needs macOS or Linux. *After the first release:*
75
+
76
+ ```sh
77
+ curl -LsSf https://raw.githubusercontent.com/shaharishay14/wraithd/main/scripts/install.sh | sh
78
+ ```
79
+
80
+ The script ([read it first](https://github.com/shaharishay14/wraithd/blob/main/scripts/install.sh)) installs
81
+ [uv](https://docs.astral.sh/uv/) if it's missing, then wraithd, without sudo. Or pick your tool:
82
+
83
+ ```sh
84
+ uv tool install --python 3.12 wraithd # uv (downloads Python 3.12 if needed)
85
+ pipx install wraithd # pipx, with a Python 3.12+
86
+ brew install shaharishay14/tap/wraithd # Homebrew
87
+ pip install wraithd # into a venv you manage, Python 3.12+
88
+ ```
89
+
90
+ Extras: `wraithd[whisper]` transcribes voice notes locally, `wraithd[browser]` adds a real browser.
91
+
92
+ ### From a checkout
93
+
94
+ ```sh
95
+ git clone https://github.com/shaharishay14/wraithd
96
+ cd wraithd
97
+ uv sync
98
+ uv run wraithd onboard
99
+ ```
100
+
101
+ ## Quick start
102
+
103
+ ```sh
104
+ wraithd onboard # model and key, Telegram, the background service, the web UI link
105
+ wraithd chat # talk to it in the terminal
106
+ wraithd doctor # check everything, with a fix for anything wrong
107
+ ```
108
+
109
+ `onboard` asks for a provider (OpenAI, Anthropic, Ollama or any OpenAI-compatible endpoint), stores the key in your
110
+ OS keychain, optionally sets up your own Telegram bot and installs a background service that starts at login. Run
111
+ it again any time: Enter keeps what's set.
112
+
113
+ ## What it does
114
+
115
+ - **Chat where you are.** The terminal, a local web page, and a Telegram bot that answers only you: photos, voice
116
+ notes and files included.
117
+ - **Memory you can read.** Markdown notes you can open and edit, and a short profile of you in every conversation.
118
+ - **Skills.** Morning brief, inbox triage, research report, meeting prep, weekly review, loaded only when a request
119
+ matches, plus your own rules.
120
+ - **Your apps as MCP servers.** Mail, calendar, notes, anything: `wraithd mcp add`. Read-only tools run; anything
121
+ else asks first, in the terminal, the web UI or Telegram.
122
+ - **Schedules and reminders.** Cron or one-time, in your timezone, firing with the terminal closed.
123
+ - **The web and files.** Searches with your model provider's own search (no extra key) and reads PDF, Word and
124
+ spreadsheets.
125
+ - **Safe by construction.** Unattended runs only do writes you pre-approved; text from an email or page can't
126
+ redirect them; keys stay in the keychain and out of the model's sight; the API listens on 127.0.0.1 with a
127
+ token. `wraithd audit` checks the live setup against these rules.
128
+ - **Every step inspectable.** `wraithd runs show <id>` prints a run's timeline: each model call, tool call,
129
+ approval and result.
130
+
131
+ ## Docs
132
+
133
+ [All docs](https://github.com/shaharishay14/wraithd/blob/main/docs/README.md) ·
134
+ [Install and run](https://github.com/shaharishay14/wraithd/blob/main/docs/install.md) ·
135
+ [Connect your apps](https://github.com/shaharishay14/wraithd/blob/main/docs/mcp.md) ·
136
+ [Security](https://github.com/shaharishay14/wraithd/blob/main/docs/security.md) ·
137
+ [Evals](https://github.com/shaharishay14/wraithd/blob/main/docs/evals.md) ·
138
+ [Releasing](https://github.com/shaharishay14/wraithd/blob/main/docs/release.md) ·
139
+ [Roadmap](https://github.com/shaharishay14/wraithd/blob/main/PLAN.md)
140
+
141
+ ## Development
142
+
143
+ ```sh
144
+ uv sync
145
+ uv run pytest # offline: no model, key, ~/.wraithd, keychain or service is touched
146
+ uv run ruff check
147
+ scripts/release.sh # the web UI (frontend/) built into the wheel, in dist/
148
+ ```
149
+
150
+ The web UI is in `frontend/` and the landing page in `site/` (`npm ci && npm run dev` in either). Issues and pull
151
+ requests are welcome; please keep tests offline.
152
+
153
+ The harness design follows Michael Livshits' writing on agent harnesses
154
+ ([michaellivs.com/blog](https://michaellivs.com/blog)). [MIT](https://github.com/shaharishay14/wraithd/blob/main/LICENSE) © 2026 Shahar Ishay
155
+
156
+ <p align="center">
157
+ <picture>
158
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/shaharishay14/wraithd/main/docs/assets/fog-dark.webp">
159
+ <img alt="" src="https://raw.githubusercontent.com/shaharishay14/wraithd/main/docs/assets/fog-light.webp" width="100%">
160
+ </picture>
161
+ </p>
@@ -0,0 +1,118 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/shaharishay14/wraithd/main/docs/assets/hero-dark.webp">
4
+ <img alt="wraithd." src="https://raw.githubusercontent.com/shaharishay14/wraithd/main/docs/assets/hero-light.webp" width="100%">
5
+ </picture>
6
+ </p>
7
+
8
+ <p align="center">
9
+ <strong>A personal AI agent that runs on your own machine.</strong><br>
10
+ One package, your model, and you talk to it from the terminal, a local web page or Telegram.
11
+ </p>
12
+
13
+ <p align="center">
14
+ <a href="https://github.com/shaharishay14/wraithd/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/shaharishay14/wraithd/actions/workflows/ci.yml/badge.svg"></a>
15
+ <a href="https://github.com/shaharishay14/wraithd/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-111111.svg"></a>
16
+ <img alt="Python 3.12+" src="https://img.shields.io/badge/python-3.12%2B-111111.svg">
17
+ <img alt="macOS and Linux" src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux-111111.svg">
18
+ </p>
19
+
20
+ wraithd is an agent you own, the way you own your notes: one process on your Mac or Linux machine, its state as
21
+ plain files and one SQLite file in `~/.wraithd/`, nothing sent anywhere but your model provider (or nowhere, with a
22
+ local model through Ollama), Telegram if you pair it, and web searches. The rules that must hold (the permission
23
+ gate, taint tracking, the egress guard, budgets) live in code, not in the prompt, and every step of every run is an
24
+ event you can inspect.
25
+
26
+ > **Status:** v0.0.1, in development. The package installs below work after the first PyPI release; until then,
27
+ > [install from a checkout](#from-a-checkout).
28
+
29
+ ## Install
30
+
31
+ Needs macOS or Linux. *After the first release:*
32
+
33
+ ```sh
34
+ curl -LsSf https://raw.githubusercontent.com/shaharishay14/wraithd/main/scripts/install.sh | sh
35
+ ```
36
+
37
+ The script ([read it first](https://github.com/shaharishay14/wraithd/blob/main/scripts/install.sh)) installs
38
+ [uv](https://docs.astral.sh/uv/) if it's missing, then wraithd, without sudo. Or pick your tool:
39
+
40
+ ```sh
41
+ uv tool install --python 3.12 wraithd # uv (downloads Python 3.12 if needed)
42
+ pipx install wraithd # pipx, with a Python 3.12+
43
+ brew install shaharishay14/tap/wraithd # Homebrew
44
+ pip install wraithd # into a venv you manage, Python 3.12+
45
+ ```
46
+
47
+ Extras: `wraithd[whisper]` transcribes voice notes locally, `wraithd[browser]` adds a real browser.
48
+
49
+ ### From a checkout
50
+
51
+ ```sh
52
+ git clone https://github.com/shaharishay14/wraithd
53
+ cd wraithd
54
+ uv sync
55
+ uv run wraithd onboard
56
+ ```
57
+
58
+ ## Quick start
59
+
60
+ ```sh
61
+ wraithd onboard # model and key, Telegram, the background service, the web UI link
62
+ wraithd chat # talk to it in the terminal
63
+ wraithd doctor # check everything, with a fix for anything wrong
64
+ ```
65
+
66
+ `onboard` asks for a provider (OpenAI, Anthropic, Ollama or any OpenAI-compatible endpoint), stores the key in your
67
+ OS keychain, optionally sets up your own Telegram bot and installs a background service that starts at login. Run
68
+ it again any time: Enter keeps what's set.
69
+
70
+ ## What it does
71
+
72
+ - **Chat where you are.** The terminal, a local web page, and a Telegram bot that answers only you: photos, voice
73
+ notes and files included.
74
+ - **Memory you can read.** Markdown notes you can open and edit, and a short profile of you in every conversation.
75
+ - **Skills.** Morning brief, inbox triage, research report, meeting prep, weekly review, loaded only when a request
76
+ matches, plus your own rules.
77
+ - **Your apps as MCP servers.** Mail, calendar, notes, anything: `wraithd mcp add`. Read-only tools run; anything
78
+ else asks first, in the terminal, the web UI or Telegram.
79
+ - **Schedules and reminders.** Cron or one-time, in your timezone, firing with the terminal closed.
80
+ - **The web and files.** Searches with your model provider's own search (no extra key) and reads PDF, Word and
81
+ spreadsheets.
82
+ - **Safe by construction.** Unattended runs only do writes you pre-approved; text from an email or page can't
83
+ redirect them; keys stay in the keychain and out of the model's sight; the API listens on 127.0.0.1 with a
84
+ token. `wraithd audit` checks the live setup against these rules.
85
+ - **Every step inspectable.** `wraithd runs show <id>` prints a run's timeline: each model call, tool call,
86
+ approval and result.
87
+
88
+ ## Docs
89
+
90
+ [All docs](https://github.com/shaharishay14/wraithd/blob/main/docs/README.md) ·
91
+ [Install and run](https://github.com/shaharishay14/wraithd/blob/main/docs/install.md) ·
92
+ [Connect your apps](https://github.com/shaharishay14/wraithd/blob/main/docs/mcp.md) ·
93
+ [Security](https://github.com/shaharishay14/wraithd/blob/main/docs/security.md) ·
94
+ [Evals](https://github.com/shaharishay14/wraithd/blob/main/docs/evals.md) ·
95
+ [Releasing](https://github.com/shaharishay14/wraithd/blob/main/docs/release.md) ·
96
+ [Roadmap](https://github.com/shaharishay14/wraithd/blob/main/PLAN.md)
97
+
98
+ ## Development
99
+
100
+ ```sh
101
+ uv sync
102
+ uv run pytest # offline: no model, key, ~/.wraithd, keychain or service is touched
103
+ uv run ruff check
104
+ scripts/release.sh # the web UI (frontend/) built into the wheel, in dist/
105
+ ```
106
+
107
+ The web UI is in `frontend/` and the landing page in `site/` (`npm ci && npm run dev` in either). Issues and pull
108
+ requests are welcome; please keep tests offline.
109
+
110
+ The harness design follows Michael Livshits' writing on agent harnesses
111
+ ([michaellivs.com/blog](https://michaellivs.com/blog)). [MIT](https://github.com/shaharishay14/wraithd/blob/main/LICENSE) © 2026 Shahar Ishay
112
+
113
+ <p align="center">
114
+ <picture>
115
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/shaharishay14/wraithd/main/docs/assets/fog-dark.webp">
116
+ <img alt="" src="https://raw.githubusercontent.com/shaharishay14/wraithd/main/docs/assets/fog-light.webp" width="100%">
117
+ </picture>
118
+ </p>
@@ -0,0 +1,82 @@
1
+ # The harness
2
+
3
+ The Agents SDK runs the loop: call the model, run the tools it asks for, feed the results back. Everything
4
+ around that loop is the harness: what the model is given, what it may do, when it stops, what it remembers,
5
+ and how we know what happened. These notes explain each part and why it's built that way.
6
+
7
+ The harness is ported from agent-studio (a multi-user web app on EC2), where these notes started. Each note
8
+ says what changed for running on one person's laptop.
9
+
10
+ ## One-liner
11
+
12
+ > wraithd's harness logs every step of a run as an event, derives the run's state from that log, and uses
13
+ > it to stop runaway runs, steer the model with short reminders, and enforce safety rules in code. The model
14
+ > gets a small prompt and pulls in tools, memory and skills only when it needs them.
15
+
16
+ ## The picture
17
+
18
+ ```
19
+ ┌──────────────────────── Harness (src/wraithd/core/) ──────────────────────┐
20
+ input ───▶ │ Event log ──▶ Views ──▶ Stop rules / Reminders ──▶ what the model sees next │ ──▶ model
21
+ (terminal, │ ▲ │ │
22
+ Telegram, │ └──────────────── tool calls and results ◀─────────────────┘ │
23
+ schedule) │ │
24
+ │ Permission gate (hard rules) Disclosure (app actions, memory, skills, web) │
25
+ │ Secret redaction · Egress checks · Budgets │
26
+ └────────────────────────────────────────────────────────────────────────────────┘
27
+ │
28
+ ▼
29
+ Store (src/wraithd/store/): events, conversations, schedules, approvals in one SQLite file
30
+ ```
31
+
32
+ ## The notes
33
+
34
+ | Note | In one line |
35
+ |---|---|
36
+ | [First launch](first-launch.md) | Start here: on your Mac, a Google Calendar, Telegram, locked down; stop and remove it all. |
37
+ | [Lockdown](lockdown.md) | The safest setup: a separate macOS user, one config block, two tool lists, approvals, and what's not protected. |
38
+ | [One run](run.md) | `run()`, config and keys, providers, the terminal chat. |
39
+ | [Keys](keys.md) | Keychain, else environment variables: an env file, systemd or a password manager such as 1Password. |
40
+ | [Event log](event-log.md) | Every step is an event; the run's state is a query over them. |
41
+ | [Security](security.md) | Hard rules in code: the gate, taint tracking, egress, redaction, budgets. |
42
+ | [From EC2 to laptop](ec2-to-laptop.md) | What changed in the threat model, the mechanism and test for each, and `audit`. |
43
+ | [Compaction](compaction.md) | The newest 10 messages word for word, older ones folded into a stored summary. |
44
+ | [System reminders](reminders.md) | Short hints at the moment they're relevant; nudges, not rules. |
45
+ | [Progressive disclosure](progressive-disclosure.md) | Search → View → Use, so the prompt doesn't grow with every tool. |
46
+ | [Memory](memory.md) | Markdown files, a keyword map instead of vectors, BM25, distill, trust labels. |
47
+ | [Skills](skills.md) | One line in the prompt, instructions on demand, the owner's rules on top, `model: strong`. |
48
+ | [Workspace files](files.md) | List, read (PDF, Word, spreadsheets too), write, edit in one folder; real-path checks keep everything else out. |
49
+ | [The shell](shell.md) | Off by default; every command asks y/N; never unattended. |
50
+ | [Sandbox](sandbox.md) | Optional Docker sandbox for the shell and opted-in MCP servers: only workspace/files/, no network. |
51
+ | [The web](web.md) | Pages through the egress guard, search through the model provider's own (no extra key), all third-party content. |
52
+ | [Schedules](schedules.md) | Cron or one time in the owner's timezone, approved, fired at most once per slot. |
53
+ | [MCP](mcp.md) | Your apps as MCP servers: secrets per server, discovery, read-only runs, the rest asks. |
54
+ | [Installing and running](install.md) | The release build, `onboard`, the background service, `doctor`, `update`. |
55
+ | [The daemon](daemon.md) | One process: the API and UI, the scheduler, Telegram, MCP, background distill. |
56
+ | [The local API](api.md) | The contract the web UI is built on: token, Origin and Host checks, endpoints. |
57
+ | [Telegram](telegram.md) | A paired owner chat only; strangers ignored; approvals as buttons; photos, voice notes, files. |
58
+ | [The scheduler](scheduler.md) | Due schedules run unattended every minute; the answer goes to the owner. |
59
+ | [One loop, not a team](one-loop.md) | Why there's one agent, and when a sub-agent would be worth it. |
60
+ | [Proof](proof.md) | Unit tests, scripted runs through the real SDK, and replay of recorded runs. |
61
+ | [Evals](evals.md) | Ten golden tasks in a fake world of MCP servers, graded by checks and a judge, cost-capped. |
62
+ | [Seams](seams.md) | The extension points Phase 9 workers plug into: model per purpose, run options, marked blocks, module migrations, periodic jobs, tool-result hooks. |
63
+ | [Review queue](review-queue.md) | Items waiting for the owner (third-party memory writes, later skills and changed MCP tools): `wraithd review`, the API, one short notice. |
64
+ | [Memory provenance](memory-provenance.md) | Where each memory note came from, and why a tainted run's memory writes wait for review. |
65
+ | [Token breakdown](tokens.md) | `wraithd runs tokens <id>`: where a run's input tokens go, part by part. |
66
+ | [Prompt caching](caching.md) | A byte-identical prefix first, everything that changes after it; cache tokens in events and budgets. |
67
+ | [Model per purpose](models.md) | `[models]`: a cheaper model for distill, compaction, heartbeat or subagents; unset means today's model. |
68
+ | [Spilling big output](spill.md) | Big tool results go to a redacted file; the model gets today's preview plus the path. |
69
+ | [Channels](channels.md) | The interface Telegram is built on: owner and pairing, receive, send, approvals. |
70
+ | [WhatsApp options](whatsapp.md) | The Cloud API, a Web bridge or a bridge process: setup, ban risk, and the pick. Not built yet. |
71
+ | [Remote access](remote-access.md) | `tailscale serve` in front of the API on an always-on box; `[remote] allowed_hosts`; the token still required. |
72
+ | [The browser](browser.md) | Headless Chromium behind the egress guard: reads taint, clicks and submits ask, a fresh profile per run. Off by default. |
73
+ | [Subagents](subagents.md) | `delegate`: a child run with its own context, the parent's budget and taint both ways, depth 1. Off by default. |
74
+ | [Skill proposals](skill-proposals.md) | Skills the agent proposes wait in the review queue; tainted ones are flagged. |
75
+ | [Heartbeat](heartbeat.md) | A periodic, read-only check that messages the owner only when something is worth it. Off by default. |
76
+
77
+ ## Where the ideas come from
78
+
79
+ Most of the design follows Michael Livshits' writing on agent harnesses ([michaellivs.com/blog](https://michaellivs.com/blog)):
80
+ the harness as the layer around the loop, the conversation as an event stream, Search → View → Use, skills as
81
+ progressive disclosure, napkin's memory design, and system reminders. The "one loop" decision follows
82
+ Anthropic's guidance on folding sub-agents into the main loop. Each note links the posts it uses.