zora-agent 0.9.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 (303) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/LICENSE +21 -0
  3. package/README.md +159 -0
  4. package/dist/cli/audit-commands.d.ts +8 -0
  5. package/dist/cli/audit-commands.d.ts.map +1 -0
  6. package/dist/cli/audit-commands.js +67 -0
  7. package/dist/cli/audit-commands.js.map +1 -0
  8. package/dist/cli/daemon.d.ts +9 -0
  9. package/dist/cli/daemon.d.ts.map +1 -0
  10. package/dist/cli/daemon.js +107 -0
  11. package/dist/cli/daemon.js.map +1 -0
  12. package/dist/cli/doctor.d.ts +21 -0
  13. package/dist/cli/doctor.d.ts.map +1 -0
  14. package/dist/cli/doctor.js +31 -0
  15. package/dist/cli/doctor.js.map +1 -0
  16. package/dist/cli/edit-commands.d.ts +8 -0
  17. package/dist/cli/edit-commands.d.ts.map +1 -0
  18. package/dist/cli/edit-commands.js +46 -0
  19. package/dist/cli/edit-commands.js.map +1 -0
  20. package/dist/cli/index.d.ts +11 -0
  21. package/dist/cli/index.d.ts.map +1 -0
  22. package/dist/cli/index.js +319 -0
  23. package/dist/cli/index.js.map +1 -0
  24. package/dist/cli/init-command.d.ts +30 -0
  25. package/dist/cli/init-command.d.ts.map +1 -0
  26. package/dist/cli/init-command.js +425 -0
  27. package/dist/cli/init-command.js.map +1 -0
  28. package/dist/cli/memory-commands.d.ts +11 -0
  29. package/dist/cli/memory-commands.d.ts.map +1 -0
  30. package/dist/cli/memory-commands.js +57 -0
  31. package/dist/cli/memory-commands.js.map +1 -0
  32. package/dist/cli/presets.d.ts +12 -0
  33. package/dist/cli/presets.d.ts.map +1 -0
  34. package/dist/cli/presets.js +169 -0
  35. package/dist/cli/presets.js.map +1 -0
  36. package/dist/cli/skill-commands.d.ts +10 -0
  37. package/dist/cli/skill-commands.d.ts.map +1 -0
  38. package/dist/cli/skill-commands.js +73 -0
  39. package/dist/cli/skill-commands.js.map +1 -0
  40. package/dist/cli/steer-commands.d.ts +10 -0
  41. package/dist/cli/steer-commands.d.ts.map +1 -0
  42. package/dist/cli/steer-commands.js +92 -0
  43. package/dist/cli/steer-commands.js.map +1 -0
  44. package/dist/cli/team-commands.d.ts +8 -0
  45. package/dist/cli/team-commands.d.ts.map +1 -0
  46. package/dist/cli/team-commands.js +93 -0
  47. package/dist/cli/team-commands.js.map +1 -0
  48. package/dist/config/defaults.d.ts +26 -0
  49. package/dist/config/defaults.d.ts.map +1 -0
  50. package/dist/config/defaults.js +173 -0
  51. package/dist/config/defaults.js.map +1 -0
  52. package/dist/config/index.d.ts +3 -0
  53. package/dist/config/index.d.ts.map +1 -0
  54. package/dist/config/index.js +3 -0
  55. package/dist/config/index.js.map +1 -0
  56. package/dist/config/loader.d.ts +30 -0
  57. package/dist/config/loader.d.ts.map +1 -0
  58. package/dist/config/loader.js +130 -0
  59. package/dist/config/loader.js.map +1 -0
  60. package/dist/config/policy-loader.d.ts +18 -0
  61. package/dist/config/policy-loader.d.ts.map +1 -0
  62. package/dist/config/policy-loader.js +72 -0
  63. package/dist/config/policy-loader.js.map +1 -0
  64. package/dist/dashboard/auth-middleware.d.ts +15 -0
  65. package/dist/dashboard/auth-middleware.d.ts.map +1 -0
  66. package/dist/dashboard/auth-middleware.js +44 -0
  67. package/dist/dashboard/auth-middleware.js.map +1 -0
  68. package/dist/dashboard/frontend/vite.config.d.ts +3 -0
  69. package/dist/dashboard/frontend/vite.config.d.ts.map +1 -0
  70. package/dist/dashboard/frontend/vite.config.js +11 -0
  71. package/dist/dashboard/frontend/vite.config.js.map +1 -0
  72. package/dist/dashboard/server.d.ts +55 -0
  73. package/dist/dashboard/server.d.ts.map +1 -0
  74. package/dist/dashboard/server.js +254 -0
  75. package/dist/dashboard/server.js.map +1 -0
  76. package/dist/index.d.ts +20 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +19 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/memory/category-organizer.d.ts +33 -0
  81. package/dist/memory/category-organizer.d.ts.map +1 -0
  82. package/dist/memory/category-organizer.js +137 -0
  83. package/dist/memory/category-organizer.js.map +1 -0
  84. package/dist/memory/extraction-pipeline.d.ts +22 -0
  85. package/dist/memory/extraction-pipeline.d.ts.map +1 -0
  86. package/dist/memory/extraction-pipeline.js +156 -0
  87. package/dist/memory/extraction-pipeline.js.map +1 -0
  88. package/dist/memory/index.d.ts +7 -0
  89. package/dist/memory/index.d.ts.map +1 -0
  90. package/dist/memory/index.js +7 -0
  91. package/dist/memory/index.js.map +1 -0
  92. package/dist/memory/memory-manager.d.ts +56 -0
  93. package/dist/memory/memory-manager.d.ts.map +1 -0
  94. package/dist/memory/memory-manager.js +198 -0
  95. package/dist/memory/memory-manager.js.map +1 -0
  96. package/dist/memory/memory-types.d.ts +44 -0
  97. package/dist/memory/memory-types.d.ts.map +1 -0
  98. package/dist/memory/memory-types.js +8 -0
  99. package/dist/memory/memory-types.js.map +1 -0
  100. package/dist/memory/salience-scorer.d.ts +19 -0
  101. package/dist/memory/salience-scorer.d.ts.map +1 -0
  102. package/dist/memory/salience-scorer.js +72 -0
  103. package/dist/memory/salience-scorer.js.map +1 -0
  104. package/dist/memory/structured-memory.d.ts +28 -0
  105. package/dist/memory/structured-memory.d.ts.map +1 -0
  106. package/dist/memory/structured-memory.js +140 -0
  107. package/dist/memory/structured-memory.js.map +1 -0
  108. package/dist/orchestrator/auth-monitor.d.ts +28 -0
  109. package/dist/orchestrator/auth-monitor.d.ts.map +1 -0
  110. package/dist/orchestrator/auth-monitor.js +49 -0
  111. package/dist/orchestrator/auth-monitor.js.map +1 -0
  112. package/dist/orchestrator/execution-loop.d.ts +59 -0
  113. package/dist/orchestrator/execution-loop.d.ts.map +1 -0
  114. package/dist/orchestrator/execution-loop.js +94 -0
  115. package/dist/orchestrator/execution-loop.js.map +1 -0
  116. package/dist/orchestrator/failover-controller.d.ts +32 -0
  117. package/dist/orchestrator/failover-controller.d.ts.map +1 -0
  118. package/dist/orchestrator/failover-controller.js +111 -0
  119. package/dist/orchestrator/failover-controller.js.map +1 -0
  120. package/dist/orchestrator/index.d.ts +11 -0
  121. package/dist/orchestrator/index.d.ts.map +1 -0
  122. package/dist/orchestrator/index.js +11 -0
  123. package/dist/orchestrator/index.js.map +1 -0
  124. package/dist/orchestrator/orchestrator.d.ts +99 -0
  125. package/dist/orchestrator/orchestrator.d.ts.map +1 -0
  126. package/dist/orchestrator/orchestrator.js +456 -0
  127. package/dist/orchestrator/orchestrator.js.map +1 -0
  128. package/dist/orchestrator/retry-queue.d.ts +39 -0
  129. package/dist/orchestrator/retry-queue.d.ts.map +1 -0
  130. package/dist/orchestrator/retry-queue.js +99 -0
  131. package/dist/orchestrator/retry-queue.js.map +1 -0
  132. package/dist/orchestrator/router.d.ts +49 -0
  133. package/dist/orchestrator/router.d.ts.map +1 -0
  134. package/dist/orchestrator/router.js +167 -0
  135. package/dist/orchestrator/router.js.map +1 -0
  136. package/dist/orchestrator/session-manager.d.ts +39 -0
  137. package/dist/orchestrator/session-manager.d.ts.map +1 -0
  138. package/dist/orchestrator/session-manager.js +117 -0
  139. package/dist/orchestrator/session-manager.js.map +1 -0
  140. package/dist/providers/claude-provider.d.ts +182 -0
  141. package/dist/providers/claude-provider.d.ts.map +1 -0
  142. package/dist/providers/claude-provider.js +443 -0
  143. package/dist/providers/claude-provider.js.map +1 -0
  144. package/dist/providers/gemini-provider.d.ts +46 -0
  145. package/dist/providers/gemini-provider.d.ts.map +1 -0
  146. package/dist/providers/gemini-provider.js +336 -0
  147. package/dist/providers/gemini-provider.js.map +1 -0
  148. package/dist/providers/index.d.ts +10 -0
  149. package/dist/providers/index.d.ts.map +1 -0
  150. package/dist/providers/index.js +10 -0
  151. package/dist/providers/index.js.map +1 -0
  152. package/dist/providers/ollama-provider.d.ts +61 -0
  153. package/dist/providers/ollama-provider.d.ts.map +1 -0
  154. package/dist/providers/ollama-provider.js +319 -0
  155. package/dist/providers/ollama-provider.js.map +1 -0
  156. package/dist/routines/event-triggers.d.ts +34 -0
  157. package/dist/routines/event-triggers.d.ts.map +1 -0
  158. package/dist/routines/event-triggers.js +104 -0
  159. package/dist/routines/event-triggers.js.map +1 -0
  160. package/dist/routines/heartbeat.d.ts +35 -0
  161. package/dist/routines/heartbeat.d.ts.map +1 -0
  162. package/dist/routines/heartbeat.js +93 -0
  163. package/dist/routines/heartbeat.js.map +1 -0
  164. package/dist/routines/index.d.ts +7 -0
  165. package/dist/routines/index.d.ts.map +1 -0
  166. package/dist/routines/index.js +7 -0
  167. package/dist/routines/index.js.map +1 -0
  168. package/dist/routines/routine-manager.d.ts +62 -0
  169. package/dist/routines/routine-manager.d.ts.map +1 -0
  170. package/dist/routines/routine-manager.js +148 -0
  171. package/dist/routines/routine-manager.js.map +1 -0
  172. package/dist/security/audit-logger.d.ts +55 -0
  173. package/dist/security/audit-logger.d.ts.map +1 -0
  174. package/dist/security/audit-logger.js +252 -0
  175. package/dist/security/audit-logger.js.map +1 -0
  176. package/dist/security/capability-tokens.d.ts +30 -0
  177. package/dist/security/capability-tokens.d.ts.map +1 -0
  178. package/dist/security/capability-tokens.js +110 -0
  179. package/dist/security/capability-tokens.js.map +1 -0
  180. package/dist/security/index.d.ts +18 -0
  181. package/dist/security/index.d.ts.map +1 -0
  182. package/dist/security/index.js +12 -0
  183. package/dist/security/index.js.map +1 -0
  184. package/dist/security/integrity-guardian.d.ts +43 -0
  185. package/dist/security/integrity-guardian.d.ts.map +1 -0
  186. package/dist/security/integrity-guardian.js +103 -0
  187. package/dist/security/integrity-guardian.js.map +1 -0
  188. package/dist/security/intent-capsule.d.ts +52 -0
  189. package/dist/security/intent-capsule.d.ts.map +1 -0
  190. package/dist/security/intent-capsule.js +157 -0
  191. package/dist/security/intent-capsule.js.map +1 -0
  192. package/dist/security/leak-detector.d.ts +26 -0
  193. package/dist/security/leak-detector.d.ts.map +1 -0
  194. package/dist/security/leak-detector.js +75 -0
  195. package/dist/security/leak-detector.js.map +1 -0
  196. package/dist/security/policy-engine.d.ts +188 -0
  197. package/dist/security/policy-engine.d.ts.map +1 -0
  198. package/dist/security/policy-engine.js +799 -0
  199. package/dist/security/policy-engine.js.map +1 -0
  200. package/dist/security/prompt-defense.d.ts +30 -0
  201. package/dist/security/prompt-defense.d.ts.map +1 -0
  202. package/dist/security/prompt-defense.js +164 -0
  203. package/dist/security/prompt-defense.js.map +1 -0
  204. package/dist/security/secrets-manager.d.ts +47 -0
  205. package/dist/security/secrets-manager.d.ts.map +1 -0
  206. package/dist/security/secrets-manager.js +132 -0
  207. package/dist/security/secrets-manager.js.map +1 -0
  208. package/dist/security/security-types.d.ts +84 -0
  209. package/dist/security/security-types.d.ts.map +1 -0
  210. package/dist/security/security-types.js +8 -0
  211. package/dist/security/security-types.js.map +1 -0
  212. package/dist/skills/index.d.ts +5 -0
  213. package/dist/skills/index.d.ts.map +1 -0
  214. package/dist/skills/index.js +5 -0
  215. package/dist/skills/index.js.map +1 -0
  216. package/dist/skills/skill-loader.d.ts +25 -0
  217. package/dist/skills/skill-loader.d.ts.map +1 -0
  218. package/dist/skills/skill-loader.js +64 -0
  219. package/dist/skills/skill-loader.js.map +1 -0
  220. package/dist/steering/flag-manager.d.ts +52 -0
  221. package/dist/steering/flag-manager.d.ts.map +1 -0
  222. package/dist/steering/flag-manager.js +160 -0
  223. package/dist/steering/flag-manager.js.map +1 -0
  224. package/dist/steering/index.d.ts +8 -0
  225. package/dist/steering/index.d.ts.map +1 -0
  226. package/dist/steering/index.js +8 -0
  227. package/dist/steering/index.js.map +1 -0
  228. package/dist/steering/steer-injector.d.ts +15 -0
  229. package/dist/steering/steer-injector.d.ts.map +1 -0
  230. package/dist/steering/steer-injector.js +41 -0
  231. package/dist/steering/steer-injector.js.map +1 -0
  232. package/dist/steering/steering-manager.d.ts +33 -0
  233. package/dist/steering/steering-manager.d.ts.map +1 -0
  234. package/dist/steering/steering-manager.js +79 -0
  235. package/dist/steering/steering-manager.js.map +1 -0
  236. package/dist/steering/telegram-gateway.d.ts +27 -0
  237. package/dist/steering/telegram-gateway.d.ts.map +1 -0
  238. package/dist/steering/telegram-gateway.js +89 -0
  239. package/dist/steering/telegram-gateway.js.map +1 -0
  240. package/dist/steering/types.d.ts +54 -0
  241. package/dist/steering/types.d.ts.map +1 -0
  242. package/dist/steering/types.js +11 -0
  243. package/dist/steering/types.js.map +1 -0
  244. package/dist/teams/agent-loader.d.ts +38 -0
  245. package/dist/teams/agent-loader.d.ts.map +1 -0
  246. package/dist/teams/agent-loader.js +85 -0
  247. package/dist/teams/agent-loader.js.map +1 -0
  248. package/dist/teams/bridge-watchdog.d.ts +44 -0
  249. package/dist/teams/bridge-watchdog.d.ts.map +1 -0
  250. package/dist/teams/bridge-watchdog.js +118 -0
  251. package/dist/teams/bridge-watchdog.js.map +1 -0
  252. package/dist/teams/gemini-bridge.d.ts +43 -0
  253. package/dist/teams/gemini-bridge.d.ts.map +1 -0
  254. package/dist/teams/gemini-bridge.js +132 -0
  255. package/dist/teams/gemini-bridge.js.map +1 -0
  256. package/dist/teams/index.d.ts +11 -0
  257. package/dist/teams/index.d.ts.map +1 -0
  258. package/dist/teams/index.js +11 -0
  259. package/dist/teams/index.js.map +1 -0
  260. package/dist/teams/mailbox.d.ts +33 -0
  261. package/dist/teams/mailbox.d.ts.map +1 -0
  262. package/dist/teams/mailbox.js +97 -0
  263. package/dist/teams/mailbox.js.map +1 -0
  264. package/dist/teams/pr-lifecycle.d.ts +47 -0
  265. package/dist/teams/pr-lifecycle.d.ts.map +1 -0
  266. package/dist/teams/pr-lifecycle.js +83 -0
  267. package/dist/teams/pr-lifecycle.js.map +1 -0
  268. package/dist/teams/team-manager.d.ts +57 -0
  269. package/dist/teams/team-manager.d.ts.map +1 -0
  270. package/dist/teams/team-manager.js +170 -0
  271. package/dist/teams/team-manager.js.map +1 -0
  272. package/dist/teams/team-types.d.ts +35 -0
  273. package/dist/teams/team-types.d.ts.map +1 -0
  274. package/dist/teams/team-types.js +9 -0
  275. package/dist/teams/team-types.js.map +1 -0
  276. package/dist/tools/index.d.ts +8 -0
  277. package/dist/tools/index.d.ts.map +1 -0
  278. package/dist/tools/index.js +8 -0
  279. package/dist/tools/index.js.map +1 -0
  280. package/dist/tools/notifications.d.ts +13 -0
  281. package/dist/tools/notifications.d.ts.map +1 -0
  282. package/dist/tools/notifications.js +30 -0
  283. package/dist/tools/notifications.js.map +1 -0
  284. package/dist/types.d.ts +311 -0
  285. package/dist/types.d.ts.map +1 -0
  286. package/dist/types.js +8 -0
  287. package/dist/types.js.map +1 -0
  288. package/dist/utils/fs.d.ts +9 -0
  289. package/dist/utils/fs.d.ts.map +1 -0
  290. package/dist/utils/fs.js +31 -0
  291. package/dist/utils/fs.js.map +1 -0
  292. package/dist/utils/logger.d.ts +43 -0
  293. package/dist/utils/logger.d.ts.map +1 -0
  294. package/dist/utils/logger.js +139 -0
  295. package/dist/utils/logger.js.map +1 -0
  296. package/dist/wasm/wasmtime-spike.d.ts +19 -0
  297. package/dist/wasm/wasmtime-spike.d.ts.map +1 -0
  298. package/dist/wasm/wasmtime-spike.js +39 -0
  299. package/dist/wasm/wasmtime-spike.js.map +1 -0
  300. package/examples/routines/content-pipeline.toml +20 -0
  301. package/examples/routines/job-search.toml +19 -0
  302. package/examples/routines/repo-cleanup.toml +14 -0
  303. package/package.json +66 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,145 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [0.9.0] — 2026-02-14
6
+
7
+ First release candidate. All 12 release gate criteria verified against source code. Zora boots, runs tasks, fails over between providers, persists sessions, and shuts down cleanly.
8
+
9
+ ### Orchestration (all release-gate gaps closed)
10
+ - Central `Orchestrator.boot()` initializes all subsystems in dependency order
11
+ - `submitTask()` flows through: classify, route, execute, persist events, inject memory, handle failover
12
+ - Automatic provider failover with depth-limited recursion (max 3 levels)
13
+ - Persistent retry queue polled every 30s with configurable backoff
14
+ - AuthMonitor scheduled checks every 5 minutes with pre-expiry warnings
15
+ - HeartbeatSystem and RoutineManager started at boot
16
+ - SteeringManager polled during execution for mid-task course corrections
17
+ - SessionManager persists all events to JSONL per job
18
+
19
+ ### Error Handling (release-gate hardening)
20
+ - AuditLogger propagates write failures instead of silently swallowing
21
+ - GeminiProvider logs JSON parse failures with full context (first 200 chars + stack)
22
+ - ExecutionLoop stream timeout protection (30-minute default, configurable)
23
+
24
+ ### CLI (fully functional daemon lifecycle)
25
+ - `zora-agent start` — Spawns daemon via fork(), writes pidfile (mode 0600), auto-opens dashboard
26
+ - `zora-agent stop` — SIGTERM with 5s grace period, SIGKILL fallback, pidfile cleanup
27
+ - `zora-agent status` — Pidfile + kill(pid, 0) liveness check, stale pidfile detection
28
+ - `zora-agent doctor` — Detects Node.js version, Claude CLI, Gemini CLI
29
+
30
+ ### Added
31
+ - Granular model selection per provider type (claude-opus, claude-sonnet, claude-haiku)
32
+ - `--max-cost-tier` CLI flag and routine config for cost-aware routing
33
+ - Ollama provider for local models (Llama, Mistral) at zero cost
34
+ - `RoutineManager.runRoutine()` for manual/test-triggered routines
35
+ - Provider quota/usage tracking in dashboard
36
+ - Docker multi-stage build with health checks
37
+ - Dashboard SSE live feed, task submission, onboarding screen
38
+ - 552 tests passing (49 unit, 3 integration, 1 benchmark), 0 type errors
39
+
40
+ ### Changed
41
+ - RoutineManager routes through `Orchestrator.submitTask()` (gets routing, failover, memory, persistence)
42
+ - Router cost filtering uses shared `COST_ORDER` constant
43
+
44
+ ### Fixed
45
+ - OllamaProvider now implements `getUsage()` (was missing from LLMProvider interface)
46
+ - Test expectations aligned to actual config default (`zora-agent` not `zora`)
47
+ - Routine TOML validation fixed for `[task]` section parsing
48
+
49
+ ## [0.6.0] — 2026-02-13
50
+
51
+ ### Security Hardening (OWASP LLM Top 10 / Agentic Top 10)
52
+
53
+ This release addresses critical security gaps identified in a comprehensive audit against OWASP LLM Top 10 (2025) and OWASP Agentic Top 10 (ASI-2026).
54
+
55
+ **Action Budgets (LLM06/LLM10 — Excessive Agency / Unbounded Consumption)**
56
+ - Per-session action limits (`max_actions_per_session`) prevent unbounded autonomous loops
57
+ - Per-type limits (`max_actions_per_type`) cap shell commands, file writes, and destructive operations independently
58
+ - Token budget enforcement caps total LLM token consumption per session
59
+ - Configurable `on_exceed` behavior: `"block"` (hard stop) or `"flag"` (prompt for approval)
60
+ - Budget tracking integrated into PolicyEngine with `recordAction()` and `recordTokenUsage()`
61
+ - All four presets (locked/safe/balanced/power) include budget defaults
62
+
63
+ **Dry-Run Preview Mode (ASI-02 — Tool Misuse)**
64
+ - `[dry_run]` policy section enables preview-without-execute for write operations
65
+ - Write tools (Write, Edit, destructive Bash) intercepted; read-only tools pass through
66
+ - Smart command classification: `ls`, `cat`, `git status`, `git diff`, `pwd`, `echo` recognized as read-only
67
+ - Dry-run interceptions logged to audit trail when `audit_dry_runs = true`
68
+ - Configurable per-tool targeting via `tools` array (empty = all write tools)
69
+
70
+ **Intent Capsules / Mandate Signing (ASI-01 — Agent Goal Hijack)**
71
+ - New `IntentCapsuleManager` creates HMAC-SHA256 signed mandate bundles per task
72
+ - SHA-256 mandate hashing with keyword extraction and category tagging
73
+ - Per-action drift detection: category match, keyword overlap (>10% threshold), capsule expiry
74
+ - Goal drift flagged for human review (not blocked outright to avoid false positives)
75
+ - Per-session signing keys via `crypto.randomBytes(32)`
76
+ - Timing-safe signature verification via `crypto.timingSafeEqual`
77
+
78
+ **RAG/Tool-Output Injection Defense (LLM01 — Prompt Injection)**
79
+ - 10 new RAG-specific injection patterns added to PromptDefense
80
+ - Detects: `[IMPORTANT INSTRUCTION]`, `NOTE TO AI`, `HIDDEN INSTRUCTION`, embedded `<system>`/`<instruction>`/`<override>`/`<admin>` tags, delimiter attacks, role impersonation
81
+ - New `sanitizeToolOutput()` function wraps suspicious tool outputs in `<untrusted_tool_output>` tags
82
+ - Existing `sanitizeInput()` updated to include RAG patterns in scan
83
+
84
+ **Infrastructure: Centralized Policy Loader**
85
+ - Extracted duplicated TOML→ZoraPolicy parsing from `cli/index.ts` and `cli/daemon.ts` into `src/config/policy-loader.ts`
86
+ - Single source of truth for all policy field defaults and backward compatibility
87
+ - New optional `[budget]` and `[dry_run]` sections with safe defaults for missing fields
88
+
89
+ ### Added
90
+ - Claude Agent SDK integration — ExecutionLoop wraps SDK `query()` with full message streaming
91
+ - Claude provider with lazy SDK import, dependency injection, abort support, and cost tracking
92
+ - Gemini CLI provider with subprocess management and stdout streaming
93
+ - N-provider router with capability matching, cost-tier awareness, and ranking modes
94
+ - Failover controller with HandoffBundle creation for mid-task provider transitions
95
+ - Retry queue with quadratic backoff and disk persistence
96
+ - Auth health monitor for provider credential tracking
97
+ - Session manager with JSONL persistence and corruption tolerance
98
+ - Policy engine with symlink detection, path canonicalization, and SDK tool interception
99
+ - Audit logger with SHA-256 hash-chained append-only JSONL and chain verification
100
+ - Secrets manager with AES-256-GCM encryption, PBKDF2 key derivation, and atomic writes
101
+ - Integrity guardian with SHA-256 baselines and file quarantine
102
+ - Leak detector with 9 pattern categories (API keys, JWTs, private keys, AWS credentials)
103
+ - Prompt defense with 20+ injection patterns (direct + RAG) and tool output sanitization
104
+ - Capability tokens with expiration enforcement and path/command validation
105
+ - 3-tier hierarchical memory system (MEMORY.md, daily notes, structured items)
106
+ - Salience scorer with exponential decay and Jaccard similarity
107
+ - Structured memory with CRUD operations and atomic writes
108
+ - Extraction pipeline with schema validation, retry logic, and deduplication
109
+ - Category organizer with auto-categorization and relevance scoring
110
+ - Team manager with filesystem-based coordination and config persistence
111
+ - Mailbox with atomic write-then-rename message queue
112
+ - Gemini bridge with subprocess orchestration and inbox polling
113
+ - Bridge watchdog with heartbeat monitoring and exponential backoff restart
114
+ - Agent loader with YAML frontmatter parsing for SDK agent definitions
115
+ - Steering manager with job-specific message persistence and archiving
116
+ - Flag manager with timeout auto-resolve and state transitions
117
+ - Telegram gateway with long polling, user allowlist, and steering commands
118
+ - Routine manager with TOML-defined tasks and node-cron scheduling
119
+ - Heartbeat system with markdown task parsing and completion marking
120
+ - Event trigger manager with fs.stat polling and glob pattern matching
121
+ - Dashboard server on localhost:7070 with Express, steering API, and health endpoint
122
+ - Auth middleware with timing-safe Bearer token comparison
123
+ - Skill loader for dynamic ~/.claude/skills/ discovery
124
+ - CLI with `ask`, `status`, `start`, `stop` commands plus memory, audit, edit, team, steer, and skill subcommands
125
+ - MCP server configuration support in config loader
126
+ - Comprehensive test suite (48 files, 500+ passing tests via Vitest + Playwright)
127
+ - CI/CD with Claude Code review workflow
128
+
129
+ ### Known Limitations (0.6.0, resolved in 0.9.0)
130
+ - ~~No main orchestrator wiring~~ — **Fixed in 0.9.0**: Orchestrator.boot() wires all components
131
+ - ~~CLI start/stop are placeholder~~ — **Fixed in 0.9.0**: Full daemon lifecycle with pidfile management
132
+ - ~~Dashboard /api/jobs returns empty~~ — **Fixed in 0.9.0**: Returns real session data
133
+ - ~~Router/FailoverController/RetryQueue/AuthMonitor never invoked~~ — **Fixed in 0.9.0**: All invoked via Orchestrator
134
+ - GeminiProvider tool parsing uses regex (still true, works but not formally verified)
135
+ - ~~ExecutionLoop does not poll SteeringManager~~ — **Fixed in 0.9.0**: Polled during execution
136
+
137
+ ## [0.5.0] — 2026-02-10
138
+
139
+ ### Added
140
+ - Initial project scaffolding with spec-first architecture
141
+ - Tier 1 (Foundation) implementation complete
142
+ - Tier 2 (Intelligence) implementation substantially complete
143
+ - v0.5 specifications and onboarding documentation
144
+ - TOML-based configuration system with deep merge and validation
145
+ - TypeScript strict mode with comprehensive type definitions
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rich Yaker
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.
package/README.md ADDED
@@ -0,0 +1,159 @@
1
+ ![Zora Header](specs/v5/assets/zora_lcars_header.png)
2
+
3
+ # Zora
4
+
5
+ **An autonomous AI agent that runs on your computer and gets work done.** Give it a task in plain English, and it uses Claude and Gemini to execute multi-step workflows while you focus on other things.
6
+
7
+ ---
8
+
9
+ ![Divider](specs/v5/assets/lcars_divider.svg)
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm i -g zora-agent
15
+ zora-agent init
16
+ zora-agent ask "summarize files in ~/Projects"
17
+ ```
18
+
19
+ That's it. Three commands from zero to productive.
20
+
21
+ ---
22
+
23
+ ![Divider](specs/v5/assets/lcars_divider.svg)
24
+
25
+ ## What It Can Do
26
+
27
+ 🚀 **Multi-Model with Automatic Failover** — Claude (Opus/Sonnet/Haiku), Gemini, and Ollama (local models). Pick the right model per task — Opus for hard problems, Haiku for cheap content, Ollama for zero-cost local work. Use `--max-cost-tier` to cap routing by cost budget. Failover is automatic.
28
+
29
+ 🛡️ **Policy-Enforced Autonomy** — Work freely within boundaries you define. The security engine enforces strict allow/deny rules for filesystem, shell, and network with action budgets, dry-run preview mode, and intent verification. [OWASP LLM Top 10 and Agentic Top 10 hardened](SECURITY.md).
30
+
31
+ 🧠 **Hierarchical Memory** — Zora remembers your preferences, past work, and project context across sessions. Long-term memory + daily rolling notes.
32
+
33
+ 🕹️ **Web Dashboard** — A local web interface for monitoring tasks, viewing provider status and quota usage, and injecting course-corrections into running workflows. Live metrics via SSE, auto-opens on `zora-agent start`.
34
+
35
+ ⏰ **Scheduled Routines** — Define recurring tasks in TOML that run automatically — daily reports, weekly cleanups, nightly code reviews. Supports `model_preference` and `max_cost_tier` per routine. Trigger manually with `RoutineManager.runRoutine()`.
36
+
37
+ 🔄 **Persistent Retry Queue** — Failed tasks are persisted to disk and retried with intelligent backoff. Resilient to transient errors.
38
+
39
+ ### Real Examples
40
+
41
+ - **File organization** — `zora-agent ask "Sort ~/Downloads by project and archive older than 30 days"`
42
+ - **Code review** — `zora-agent ask "Check all PRs in my repos and comment on style issues"`
43
+ - **Email drafting** — `zora-agent ask "Draft replies to unread emails about the product launch"`
44
+ - **Git management** — `zora-agent ask "Create feature branches from all open issues labeled 'sprint-12'"`
45
+ - **Web research** — `zora-agent ask "Find and summarize the latest React 19 migration guides"`
46
+ - **Multi-step workflows** — `zora-agent ask "Find all TODOs in my project, create a summary, and open a GitHub issue with it."`
47
+
48
+ ---
49
+
50
+ ![Divider](specs/v5/assets/lcars_divider.svg)
51
+
52
+ ## How Security Works
53
+
54
+ Zora operates within strict boundaries you define. A policy file (`~/.zora/policy.toml`) specifies allowed filesystem paths, shell commands, and network access. The agent self-corrects when it hits policy limits — no data leaves your machine except API calls to Claude/Gemini. Every action is logged to a tamper-proof audit trail.
55
+
56
+ **Security Hardening** — Audited against OWASP LLM Top 10 (2025) and OWASP Agentic Top 10 (ASI-2026):
57
+
58
+ | Defense | What It Does |
59
+ |---------|-------------|
60
+ | **Action Budgets** | Per-session limits on tool invocations and token spend prevent unbounded loops |
61
+ | **Dry-Run Mode** | Preview write operations without executing — test policies safely |
62
+ | **Intent Capsules** | HMAC-SHA256 signed mandates detect goal hijacking from injected instructions |
63
+ | **RAG Injection Defense** | 20+ patterns detect prompt injection in tool outputs and RAG documents |
64
+ | **Hash-Chain Audit** | SHA-256 chained append-only log with tamper detection |
65
+ | **AES-256-GCM Secrets** | Encrypted credential storage with PBKDF2 key derivation |
66
+
67
+ See **[SECURITY.md](SECURITY.md)** for the full security guide and OWASP compliance matrix.
68
+
69
+ ---
70
+
71
+ ![Divider](specs/v5/assets/lcars_divider.svg)
72
+
73
+ ## Architecture
74
+
75
+ ```
76
+ ┌─────────────────────────────────────────────────┐
77
+ │ ORCHESTRATOR CORE │
78
+ │ Router → Execution Loop → Failover Controller │
79
+ │ Retry Queue │ Session Manager │
80
+ ├─────────────────────────────────────────────────┤
81
+ │ LLM PROVIDER REGISTRY │
82
+ │ Claude Opus/Sonnet/Haiku │ Gemini │ Ollama │
83
+ │ Agent SDK (Native) CLI (Sub) REST (Local) │
84
+ ├─────────────────────────────────────────────────┤
85
+ │ Tools │ Memory │ Security │
86
+ │ Shell │ MEMORY.md │ Policy Engine │
87
+ │ Filesystem │ Daily Notes │ Audit Log │
88
+ │ Web │ Context Loader │ Restrictive FS │
89
+ └─────────────────────────────────────────────────┘
90
+ ```
91
+
92
+ ---
93
+
94
+ ![Divider](specs/v5/assets/lcars_divider.svg)
95
+
96
+ ## Project Status
97
+
98
+ Zora is in active development (v0.9.0). This table reflects what actually works today.
99
+
100
+ | Component | Status |
101
+ |-----------|--------|
102
+ | Multi-model orchestration (Claude Opus/Sonnet/Haiku + Gemini + Ollama) | ✅ Working |
103
+ | Automatic failover on quota/auth errors | ✅ Working |
104
+ | Policy-based security engine (path + command enforcement) | ✅ Working |
105
+ | Action budgets (per-session + per-type limits) | ✅ Working |
106
+ | Dry-run preview mode (test without executing) | ✅ Working |
107
+ | Intent capsules (HMAC-SHA256 goal drift detection) | ✅ Working |
108
+ | RAG/tool-output injection defense (20+ patterns) | ✅ Working |
109
+ | Policy-aware agent (checks permissions before acting) | ✅ Working |
110
+ | SOUL.md personality loading | ✅ Working |
111
+ | Hierarchical memory (long-term + daily notes) | ✅ Working |
112
+ | Scheduled routines via cron | ✅ Working |
113
+ | Web dashboard with live SSE feed, task submission, and onboarding | ✅ Working |
114
+ | Provider quota/usage tracking in dashboard | ✅ Working |
115
+ | Cost-aware routing via `--max-cost-tier` | ✅ Working |
116
+ | Manual routine execution (`runRoutine()`) | ✅ Working |
117
+ | Persistent retry queue with backoff | ✅ Working |
118
+ | Docker containerization for integration testing | ✅ Working |
119
+ | Interactive approval for flagged actions (`always_flag`) | 🚧 Config parsed, enforcement in progress |
120
+ | Runtime permission expansion (grant access mid-task) | 🚧 Planned |
121
+ | Cross-platform support (macOS, Linux, Windows) | 🚧 macOS tested, others in progress |
122
+
123
+ ---
124
+
125
+ ![Divider](specs/v5/assets/lcars_divider.svg)
126
+
127
+ ## Dashboard
128
+
129
+ After starting the agent, the dashboard auto-opens at `http://localhost:7070`. Submit tasks, monitor live progress via SSE, view provider quota/usage, and send course-corrections to running jobs. First-time users see a guided onboarding screen with quick-start examples.
130
+
131
+ New to Zora? Use our **[AI Setup Assistant](docs/AI_SETUP_ASSISTANT.md)** — paste the prompt into any AI chatbot (ChatGPT, Claude, Gemini) for a guided walkthrough of installation and configuration.
132
+
133
+ ---
134
+
135
+ ![Divider](specs/v5/assets/lcars_divider.svg)
136
+
137
+ ## Documentation
138
+
139
+ | Document | Description |
140
+ |----------|-------------|
141
+ | **[QUICKSTART.md](QUICKSTART.md)** | Get up and running in 5 minutes |
142
+ | **[USE_CASES.md](USE_CASES.md)** | Real-world examples and workflow patterns |
143
+ | **[SECURITY.md](SECURITY.md)** | Policy configuration and audit logging |
144
+ | **[ROUTINES_COOKBOOK.md](ROUTINES_COOKBOOK.md)** | Recipes for scheduled tasks |
145
+ | **[SETUP_GUIDE.md](SETUP_GUIDE.md)** | Detailed installation and configuration |
146
+ | **[docs/BEGINNERS_GUIDE.md](docs/BEGINNERS_GUIDE.md)** | In-depth usage guide |
147
+ | **[docs/AI_SETUP_ASSISTANT.md](docs/AI_SETUP_ASSISTANT.md)** | Interactive AI-guided setup |
148
+
149
+ ## Contributing
150
+
151
+ Contributions are welcome. Open an issue to discuss features or bugs before submitting a PR.
152
+
153
+ ## License
154
+
155
+ MIT License - see [LICENSE](LICENSE) for details.
156
+
157
+ ---
158
+
159
+ *Local first. Works for you.*
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Audit CLI Commands — view and verify the audit log.
3
+ *
4
+ * Spec §5.9 "CLI Interface" — audit subcommand.
5
+ */
6
+ import type { Command } from 'commander';
7
+ export declare function registerAuditCommands(program: Command, getAuditLogPath: () => string): void;
8
+ //# sourceMappingURL=audit-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-commands.d.ts","sourceRoot":"","sources":["../../src/cli/audit-commands.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBzC,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,MAAM,MAAM,GAC5B,IAAI,CA6CN"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Audit CLI Commands — view and verify the audit log.
3
+ *
4
+ * Spec §5.9 "CLI Interface" — audit subcommand.
5
+ */
6
+ import { AuditLogger } from '../security/audit-logger.js';
7
+ function parseDuration(duration) {
8
+ const match = /^(\d+)(h|d|m)$/.exec(duration);
9
+ if (!match)
10
+ return 24 * 60 * 60 * 1000; // default 24h
11
+ const value = parseInt(match[1], 10);
12
+ const unit = match[2];
13
+ switch (unit) {
14
+ case 'm':
15
+ return value * 60 * 1000;
16
+ case 'h':
17
+ return value * 60 * 60 * 1000;
18
+ case 'd':
19
+ return value * 24 * 60 * 60 * 1000;
20
+ default:
21
+ return 24 * 60 * 60 * 1000;
22
+ }
23
+ }
24
+ export function registerAuditCommands(program, getAuditLogPath) {
25
+ program
26
+ .command('audit')
27
+ .description('View the audit log')
28
+ .option('--last <duration>', 'Time window (e.g., 24h, 7d)', '24h')
29
+ .option('--job <jobId>', 'Filter by job ID')
30
+ .option('--type <eventType>', 'Filter by event type')
31
+ .option('--verify', 'Verify hash chain integrity')
32
+ .action(async (opts) => {
33
+ const logger = new AuditLogger(getAuditLogPath());
34
+ if (opts.verify) {
35
+ const result = await logger.verifyChain();
36
+ if (result.valid) {
37
+ console.log(`Audit chain verified: ${result.entries} entries, all valid.`);
38
+ }
39
+ else {
40
+ console.error(`Audit chain BROKEN at entry ${result.brokenAt}: ${result.reason}`);
41
+ process.exitCode = 1;
42
+ }
43
+ return;
44
+ }
45
+ const durationMs = parseDuration(opts.last);
46
+ const startTime = new Date(Date.now() - durationMs).toISOString();
47
+ const filter = { startTime };
48
+ if (opts.job)
49
+ filter.jobId = opts.job;
50
+ if (opts.type)
51
+ filter.eventType = opts.type;
52
+ const entries = await logger.readEntries(filter);
53
+ if (entries.length === 0) {
54
+ console.log('No audit entries found for the given filters.');
55
+ return;
56
+ }
57
+ console.log(`${entries.length} audit entries:\n`);
58
+ for (const entry of entries) {
59
+ console.log(` [${entry.entryId}] ${entry.eventType} — job=${entry.jobId} at ${entry.timestamp}`);
60
+ if (entry.toolName) {
61
+ console.log(` tool: ${entry.toolName}`);
62
+ }
63
+ console.log();
64
+ }
65
+ });
66
+ }
67
+ //# sourceMappingURL=audit-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-commands.js","sourceRoot":"","sources":["../../src/cli/audit-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Zora Daemon — Background process that runs the Orchestrator and Dashboard.
4
+ *
5
+ * Launched by `zora-agent start` via child_process.fork().
6
+ * Handles SIGTERM/SIGINT for graceful shutdown.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Zora Daemon — Background process that runs the Orchestrator and Dashboard.
4
+ *
5
+ * Launched by `zora-agent start` via child_process.fork().
6
+ * Handles SIGTERM/SIGINT for graceful shutdown.
7
+ */
8
+ import path from 'node:path';
9
+ import os from 'node:os';
10
+ import fs from 'node:fs';
11
+ import { loadConfig } from '../config/loader.js';
12
+ import { Orchestrator } from '../orchestrator/orchestrator.js';
13
+ import { DashboardServer } from '../dashboard/server.js';
14
+ import { ClaudeProvider } from '../providers/claude-provider.js';
15
+ import { GeminiProvider } from '../providers/gemini-provider.js';
16
+ import { OllamaProvider } from '../providers/ollama-provider.js';
17
+ function createProviders(config) {
18
+ const providers = [];
19
+ for (const pConfig of config.providers) {
20
+ if (!pConfig.enabled)
21
+ continue;
22
+ switch (pConfig.type) {
23
+ case 'claude-sdk':
24
+ providers.push(new ClaudeProvider({ config: pConfig }));
25
+ break;
26
+ case 'gemini-cli':
27
+ providers.push(new GeminiProvider({ config: pConfig }));
28
+ break;
29
+ case 'ollama':
30
+ providers.push(new OllamaProvider({ config: pConfig }));
31
+ break;
32
+ }
33
+ }
34
+ return providers;
35
+ }
36
+ async function main() {
37
+ const configDir = path.join(os.homedir(), '.zora');
38
+ const configPath = path.join(configDir, 'config.toml');
39
+ const policyPath = path.join(configDir, 'policy.toml');
40
+ if (!fs.existsSync(configPath)) {
41
+ console.error('Config not found. Run `zora-agent init` first.');
42
+ process.exit(1);
43
+ }
44
+ const config = await loadConfig(configPath);
45
+ // Load policy from TOML using centralized loader
46
+ const { loadPolicy } = await import('../config/policy-loader.js');
47
+ let policy;
48
+ try {
49
+ policy = await loadPolicy(policyPath);
50
+ }
51
+ catch {
52
+ console.error('Policy not found at ~/.zora/policy.toml. Run `zora-agent init` first.');
53
+ process.exit(1);
54
+ }
55
+ const providers = createProviders(config);
56
+ const orchestrator = new Orchestrator({ config, policy, providers });
57
+ await orchestrator.boot();
58
+ // Start dashboard server
59
+ const dashboard = new DashboardServer({
60
+ providers,
61
+ sessionManager: orchestrator.sessionManager,
62
+ steeringManager: orchestrator.steeringManager,
63
+ authMonitor: orchestrator.authMonitor,
64
+ submitTask: async (prompt) => {
65
+ // Generate jobId immediately and kick off task in background (don't await)
66
+ const jobId = `job_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
67
+ orchestrator.submitTask({ prompt, jobId, onEvent: (event) => {
68
+ dashboard.broadcastEvent({ type: event.type, data: event.content });
69
+ } }).catch(err => {
70
+ console.error(`[Daemon] Task ${jobId} failed:`, err);
71
+ dashboard.broadcastEvent({ type: 'job_failed', data: { jobId, error: err instanceof Error ? err.message : String(err) } });
72
+ });
73
+ return jobId;
74
+ },
75
+ port: config.steering.dashboard_port ?? 7070,
76
+ host: process.env.ZORA_BIND_HOST,
77
+ });
78
+ await dashboard.start();
79
+ console.log('[Daemon] Zora daemon is running.');
80
+ // Graceful shutdown handler
81
+ const shutdown = async (signal) => {
82
+ console.log(`[Daemon] Received ${signal}, shutting down...`);
83
+ try {
84
+ await dashboard.stop();
85
+ await orchestrator.shutdown();
86
+ }
87
+ catch (err) {
88
+ console.error(`[Daemon] Error during shutdown:`, err instanceof Error ? err.message : String(err));
89
+ }
90
+ // Remove pidfile
91
+ const pidFile = path.join(configDir, 'state', 'daemon.pid');
92
+ try {
93
+ fs.unlinkSync(pidFile);
94
+ }
95
+ catch {
96
+ // Already removed
97
+ }
98
+ process.exit(0);
99
+ };
100
+ process.on('SIGTERM', () => { shutdown('SIGTERM').catch(err => { console.error('[Daemon] Shutdown error:', err); process.exit(1); }); });
101
+ process.on('SIGINT', () => { shutdown('SIGINT').catch(err => { console.error('[Daemon] Shutdown error:', err); process.exit(1); }); });
102
+ }
103
+ main().catch((err) => {
104
+ console.error('[Daemon] Fatal error:', err);
105
+ process.exit(1);
106
+ });
107
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Doctor Checks — detect available providers and tools.
3
+ *
4
+ * Reusable by `zora-agent init` and a future `zora-agent doctor` command.
5
+ */
6
+ export interface DoctorResult {
7
+ node: {
8
+ found: boolean;
9
+ version: string;
10
+ };
11
+ claude: {
12
+ found: boolean;
13
+ path: string | null;
14
+ };
15
+ gemini: {
16
+ found: boolean;
17
+ path: string | null;
18
+ };
19
+ }
20
+ export declare function runDoctorChecks(): Promise<DoctorResult>;
21
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,MAAM,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChD,MAAM,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CACjD;AAWD,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAc7D"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Doctor Checks — detect available providers and tools.
3
+ *
4
+ * Reusable by `zora-agent init` and a future `zora-agent doctor` command.
5
+ */
6
+ import { execFile } from 'node:child_process';
7
+ import { promisify } from 'node:util';
8
+ const execFileAsync = promisify(execFile);
9
+ async function whichCommand(cmd) {
10
+ try {
11
+ const { stdout } = await execFileAsync('which', [cmd]);
12
+ return stdout.trim() || null;
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ export async function runDoctorChecks() {
19
+ const [claudePath, geminiPath] = await Promise.all([
20
+ whichCommand('claude'),
21
+ whichCommand('gemini'),
22
+ ]);
23
+ const nodeVersion = process.version; // e.g. "v20.11.0"
24
+ const nodeMajor = parseInt(nodeVersion.slice(1), 10);
25
+ return {
26
+ node: { found: nodeMajor >= 20, version: nodeVersion },
27
+ claude: { found: claudePath !== null, path: claudePath },
28
+ gemini: { found: geminiPath !== null, path: geminiPath },
29
+ };
30
+ }
31
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAQ1C,KAAK,UAAU,YAAY,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvD,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACjD,YAAY,CAAC,QAAQ,CAAC;QACtB,YAAY,CAAC,QAAQ,CAAC;KACvB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,kBAAkB;IACvD,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAErD,OAAO;QACL,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE;QACtD,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE;QACxD,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE;KACzD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Edit CLI Commands — open human-protected config files in $EDITOR.
3
+ *
4
+ * Spec §5.9 "CLI Interface" — config/policy/soul/memory edit subcommands.
5
+ */
6
+ import type { Command } from 'commander';
7
+ export declare function registerEditCommands(program: Command, configDir: string): void;
8
+ //# sourceMappingURL=edit-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-commands.d.ts","sourceRoot":"","sources":["../../src/cli/edit-commands.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWzC,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB,IAAI,CAmCN"}