@oratis/lisa 0.8.0 → 0.11.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 (320) hide show
  1. package/README.md +123 -16
  2. package/README.zh-CN.md +101 -15
  3. package/completions/_lisa +56 -0
  4. package/completions/lisa.bash +35 -1
  5. package/completions/lisa.fish +18 -1
  6. package/dist/advisor/engine.d.ts +7 -0
  7. package/dist/advisor/engine.d.ts.map +1 -1
  8. package/dist/advisor/engine.js +12 -0
  9. package/dist/advisor/engine.js.map +1 -1
  10. package/dist/agent.d.ts +14 -0
  11. package/dist/agent.d.ts.map +1 -1
  12. package/dist/agent.js +58 -7
  13. package/dist/agent.js.map +1 -1
  14. package/dist/agents/managed.d.ts +108 -0
  15. package/dist/agents/managed.d.ts.map +1 -0
  16. package/dist/agents/managed.js +241 -0
  17. package/dist/agents/managed.js.map +1 -0
  18. package/dist/agents/pty.d.ts +155 -0
  19. package/dist/agents/pty.d.ts.map +1 -0
  20. package/dist/agents/pty.js +299 -0
  21. package/dist/agents/pty.js.map +1 -0
  22. package/dist/approval.d.ts +13 -0
  23. package/dist/approval.d.ts.map +1 -1
  24. package/dist/approval.js +25 -2
  25. package/dist/approval.js.map +1 -1
  26. package/dist/autonomy/runs.d.ts +33 -0
  27. package/dist/autonomy/runs.d.ts.map +1 -0
  28. package/dist/autonomy/runs.js +106 -0
  29. package/dist/autonomy/runs.js.map +1 -0
  30. package/dist/channels/feishu.d.ts.map +1 -1
  31. package/dist/channels/feishu.js +65 -0
  32. package/dist/channels/feishu.js.map +1 -1
  33. package/dist/channels/router.d.ts +7 -0
  34. package/dist/channels/router.d.ts.map +1 -1
  35. package/dist/channels/router.js +1 -1
  36. package/dist/channels/router.js.map +1 -1
  37. package/dist/cli/agents-pty.d.ts +18 -0
  38. package/dist/cli/agents-pty.d.ts.map +1 -0
  39. package/dist/cli/agents-pty.js +182 -0
  40. package/dist/cli/agents-pty.js.map +1 -0
  41. package/dist/cli/agents.d.ts +2 -0
  42. package/dist/cli/agents.d.ts.map +1 -0
  43. package/dist/cli/agents.js +65 -0
  44. package/dist/cli/agents.js.map +1 -0
  45. package/dist/cli/consent.d.ts +2 -0
  46. package/dist/cli/consent.d.ts.map +1 -0
  47. package/dist/cli/consent.js +57 -0
  48. package/dist/cli/consent.js.map +1 -0
  49. package/dist/cli/model.d.ts +2 -0
  50. package/dist/cli/model.d.ts.map +1 -0
  51. package/dist/cli/model.js +121 -0
  52. package/dist/cli/model.js.map +1 -0
  53. package/dist/cli/sense.d.ts +2 -0
  54. package/dist/cli/sense.d.ts.map +1 -0
  55. package/dist/cli/sense.js +36 -0
  56. package/dist/cli/sense.js.map +1 -0
  57. package/dist/cli.js +117 -12
  58. package/dist/cli.js.map +1 -1
  59. package/dist/consent/blacklist.d.ts +28 -0
  60. package/dist/consent/blacklist.d.ts.map +1 -0
  61. package/dist/consent/blacklist.js +78 -0
  62. package/dist/consent/blacklist.js.map +1 -0
  63. package/dist/consent/store.d.ts +45 -0
  64. package/dist/consent/store.d.ts.map +1 -0
  65. package/dist/consent/store.js +126 -0
  66. package/dist/consent/store.js.map +1 -0
  67. package/dist/control/policy.d.ts +13 -0
  68. package/dist/control/policy.d.ts.map +1 -0
  69. package/dist/control/policy.js +57 -0
  70. package/dist/control/policy.js.map +1 -0
  71. package/dist/heartbeat/runner.d.ts.map +1 -1
  72. package/dist/heartbeat/runner.js +70 -14
  73. package/dist/heartbeat/runner.js.map +1 -1
  74. package/dist/idle/runner.d.ts.map +1 -1
  75. package/dist/idle/runner.js +87 -17
  76. package/dist/idle/runner.js.map +1 -1
  77. package/dist/integrations/aider/observer.d.ts +21 -1
  78. package/dist/integrations/aider/observer.d.ts.map +1 -1
  79. package/dist/integrations/aider/observer.js +110 -1
  80. package/dist/integrations/aider/observer.js.map +1 -1
  81. package/dist/integrations/claude-code/liveness.d.ts +10 -0
  82. package/dist/integrations/claude-code/liveness.d.ts.map +1 -0
  83. package/dist/integrations/claude-code/liveness.js +62 -0
  84. package/dist/integrations/claude-code/liveness.js.map +1 -0
  85. package/dist/integrations/claude-code/watcher.d.ts +39 -4
  86. package/dist/integrations/claude-code/watcher.d.ts.map +1 -1
  87. package/dist/integrations/claude-code/watcher.js +94 -57
  88. package/dist/integrations/claude-code/watcher.js.map +1 -1
  89. package/dist/integrations/codex/observer.d.ts +19 -6
  90. package/dist/integrations/codex/observer.d.ts.map +1 -1
  91. package/dist/integrations/codex/observer.js +228 -4
  92. package/dist/integrations/codex/observer.js.map +1 -1
  93. package/dist/integrations/dispatch-ledger.d.ts +30 -1
  94. package/dist/integrations/dispatch-ledger.d.ts.map +1 -1
  95. package/dist/integrations/dispatch-ledger.js +75 -9
  96. package/dist/integrations/dispatch-ledger.js.map +1 -1
  97. package/dist/integrations/git/branch.d.ts +11 -0
  98. package/dist/integrations/git/branch.d.ts.map +1 -0
  99. package/dist/integrations/git/branch.js +49 -0
  100. package/dist/integrations/git/branch.js.map +1 -0
  101. package/dist/integrations/git/observer.d.ts +39 -0
  102. package/dist/integrations/git/observer.d.ts.map +1 -0
  103. package/dist/integrations/git/observer.js +252 -0
  104. package/dist/integrations/git/observer.js.map +1 -0
  105. package/dist/integrations/github-pr/observer.d.ts.map +1 -1
  106. package/dist/integrations/github-pr/observer.js +7 -2
  107. package/dist/integrations/github-pr/observer.js.map +1 -1
  108. package/dist/integrations/hub.d.ts +8 -0
  109. package/dist/integrations/hub.d.ts.map +1 -1
  110. package/dist/integrations/hub.js +39 -1
  111. package/dist/integrations/hub.js.map +1 -1
  112. package/dist/integrations/managed/observer.d.ts +17 -0
  113. package/dist/integrations/managed/observer.d.ts.map +1 -0
  114. package/dist/integrations/managed/observer.js +46 -0
  115. package/dist/integrations/managed/observer.js.map +1 -0
  116. package/dist/integrations/opencode/observer.d.ts +53 -5
  117. package/dist/integrations/opencode/observer.d.ts.map +1 -1
  118. package/dist/integrations/opencode/observer.js +242 -20
  119. package/dist/integrations/opencode/observer.js.map +1 -1
  120. package/dist/integrations/pty/observer.d.ts +25 -0
  121. package/dist/integrations/pty/observer.d.ts.map +1 -0
  122. package/dist/integrations/pty/observer.js +48 -0
  123. package/dist/integrations/pty/observer.js.map +1 -0
  124. package/dist/integrations/registry.d.ts.map +1 -1
  125. package/dist/integrations/registry.js +5 -0
  126. package/dist/integrations/registry.js.map +1 -1
  127. package/dist/integrations/shell/observer.d.ts +33 -0
  128. package/dist/integrations/shell/observer.d.ts.map +1 -0
  129. package/dist/integrations/shell/observer.js +223 -0
  130. package/dist/integrations/shell/observer.js.map +1 -0
  131. package/dist/integrations/takoapi/a2a.d.ts +38 -0
  132. package/dist/integrations/takoapi/a2a.d.ts.map +1 -0
  133. package/dist/integrations/takoapi/a2a.js +70 -0
  134. package/dist/integrations/takoapi/a2a.js.map +1 -0
  135. package/dist/integrations/takoapi/ledger.d.ts +32 -0
  136. package/dist/integrations/takoapi/ledger.d.ts.map +1 -0
  137. package/dist/integrations/takoapi/ledger.js +96 -0
  138. package/dist/integrations/takoapi/ledger.js.map +1 -0
  139. package/dist/integrations/takoapi/observer.d.ts +39 -0
  140. package/dist/integrations/takoapi/observer.d.ts.map +1 -0
  141. package/dist/integrations/takoapi/observer.js +102 -0
  142. package/dist/integrations/takoapi/observer.js.map +1 -0
  143. package/dist/integrations/types.d.ts +17 -0
  144. package/dist/integrations/types.d.ts.map +1 -1
  145. package/dist/mcp/client.d.ts +5 -0
  146. package/dist/mcp/client.d.ts.map +1 -1
  147. package/dist/mcp/client.js +1 -1
  148. package/dist/mcp/client.js.map +1 -1
  149. package/dist/mcp/config.d.ts +4 -0
  150. package/dist/mcp/config.d.ts.map +1 -1
  151. package/dist/mcp/config.js +34 -0
  152. package/dist/mcp/config.js.map +1 -1
  153. package/dist/memory/embedding.d.ts +45 -0
  154. package/dist/memory/embedding.d.ts.map +1 -0
  155. package/dist/memory/embedding.js +139 -0
  156. package/dist/memory/embedding.js.map +1 -0
  157. package/dist/memory/search_tool.d.ts.map +1 -1
  158. package/dist/memory/search_tool.js +6 -2
  159. package/dist/memory/search_tool.js.map +1 -1
  160. package/dist/memory/vector.d.ts +14 -3
  161. package/dist/memory/vector.d.ts.map +1 -1
  162. package/dist/memory/vector.js +50 -0
  163. package/dist/memory/vector.js.map +1 -1
  164. package/dist/model/local.d.ts +43 -0
  165. package/dist/model/local.d.ts.map +1 -0
  166. package/dist/model/local.js +118 -0
  167. package/dist/model/local.js.map +1 -0
  168. package/dist/model/plan-usage.d.ts +41 -0
  169. package/dist/model/plan-usage.d.ts.map +1 -0
  170. package/dist/model/plan-usage.js +168 -0
  171. package/dist/model/plan-usage.js.map +1 -0
  172. package/dist/model/plans.d.ts +73 -0
  173. package/dist/model/plans.d.ts.map +1 -0
  174. package/dist/model/plans.js +246 -0
  175. package/dist/model/plans.js.map +1 -0
  176. package/dist/orchestrator/recent-recap.d.ts +2 -0
  177. package/dist/orchestrator/recent-recap.d.ts.map +1 -0
  178. package/dist/orchestrator/recent-recap.js +20 -0
  179. package/dist/orchestrator/recent-recap.js.map +1 -0
  180. package/dist/providers/anthropic.d.ts +1 -0
  181. package/dist/providers/anthropic.d.ts.map +1 -1
  182. package/dist/providers/anthropic.js +10 -2
  183. package/dist/providers/anthropic.js.map +1 -1
  184. package/dist/providers/fallback.d.ts +23 -0
  185. package/dist/providers/fallback.d.ts.map +1 -0
  186. package/dist/providers/fallback.js +29 -0
  187. package/dist/providers/fallback.js.map +1 -0
  188. package/dist/providers/gemini.d.ts +2 -0
  189. package/dist/providers/gemini.d.ts.map +1 -1
  190. package/dist/providers/gemini.js +24 -10
  191. package/dist/providers/gemini.js.map +1 -1
  192. package/dist/providers/openai.d.ts.map +1 -1
  193. package/dist/providers/openai.js +4 -1
  194. package/dist/providers/openai.js.map +1 -1
  195. package/dist/providers/registry.d.ts +18 -2
  196. package/dist/providers/registry.d.ts.map +1 -1
  197. package/dist/providers/registry.js +56 -9
  198. package/dist/providers/registry.js.map +1 -1
  199. package/dist/reflect.d.ts +55 -0
  200. package/dist/reflect.d.ts.map +1 -1
  201. package/dist/reflect.js +148 -54
  202. package/dist/reflect.js.map +1 -1
  203. package/dist/sense/log.d.ts +9 -0
  204. package/dist/sense/log.d.ts.map +1 -0
  205. package/dist/sense/log.js +63 -0
  206. package/dist/sense/log.js.map +1 -0
  207. package/dist/sense/screen.d.ts +43 -0
  208. package/dist/sense/screen.d.ts.map +1 -0
  209. package/dist/sense/screen.js +107 -0
  210. package/dist/sense/screen.js.map +1 -0
  211. package/dist/sense/service.d.ts +16 -0
  212. package/dist/sense/service.d.ts.map +1 -0
  213. package/dist/sense/service.js +33 -0
  214. package/dist/sense/service.js.map +1 -0
  215. package/dist/sense/types.d.ts +35 -0
  216. package/dist/sense/types.d.ts.map +1 -0
  217. package/dist/sense/types.js +11 -0
  218. package/dist/sense/types.js.map +1 -0
  219. package/dist/sense/voice.d.ts +28 -0
  220. package/dist/sense/voice.d.ts.map +1 -0
  221. package/dist/sense/voice.js +64 -0
  222. package/dist/sense/voice.js.map +1 -0
  223. package/dist/soul/git.d.ts.map +1 -1
  224. package/dist/soul/git.js +35 -16
  225. package/dist/soul/git.js.map +1 -1
  226. package/dist/soul/store.d.ts +22 -0
  227. package/dist/soul/store.d.ts.map +1 -1
  228. package/dist/soul/store.js +69 -14
  229. package/dist/soul/store.js.map +1 -1
  230. package/dist/soul/summary.d.ts +10 -0
  231. package/dist/soul/summary.d.ts.map +1 -0
  232. package/dist/soul/summary.js +57 -0
  233. package/dist/soul/summary.js.map +1 -0
  234. package/dist/soul/tools.d.ts.map +1 -1
  235. package/dist/soul/tools.js +13 -24
  236. package/dist/soul/tools.js.map +1 -1
  237. package/dist/soul/types.d.ts +9 -0
  238. package/dist/soul/types.d.ts.map +1 -1
  239. package/dist/soul/types.js.map +1 -1
  240. package/dist/subagent.d.ts +7 -0
  241. package/dist/subagent.d.ts.map +1 -1
  242. package/dist/subagent.js +3 -1
  243. package/dist/subagent.js.map +1 -1
  244. package/dist/tools/dispatch_agent.d.ts +13 -1
  245. package/dist/tools/dispatch_agent.d.ts.map +1 -1
  246. package/dist/tools/dispatch_agent.js +56 -12
  247. package/dist/tools/dispatch_agent.js.map +1 -1
  248. package/dist/tools/dispatch_status.d.ts +22 -0
  249. package/dist/tools/dispatch_status.d.ts.map +1 -0
  250. package/dist/tools/dispatch_status.js +57 -0
  251. package/dist/tools/dispatch_status.js.map +1 -0
  252. package/dist/tools/github.d.ts +34 -0
  253. package/dist/tools/github.d.ts.map +1 -0
  254. package/dist/tools/github.js +140 -0
  255. package/dist/tools/github.js.map +1 -0
  256. package/dist/tools/github_link.d.ts +36 -0
  257. package/dist/tools/github_link.d.ts.map +1 -0
  258. package/dist/tools/github_link.js +127 -0
  259. package/dist/tools/github_link.js.map +1 -0
  260. package/dist/tools/mcp.d.ts +28 -0
  261. package/dist/tools/mcp.d.ts.map +1 -0
  262. package/dist/tools/mcp.js +55 -0
  263. package/dist/tools/mcp.js.map +1 -0
  264. package/dist/tools/npm_info.d.ts +21 -0
  265. package/dist/tools/npm_info.d.ts.map +1 -0
  266. package/dist/tools/npm_info.js +102 -0
  267. package/dist/tools/npm_info.js.map +1 -0
  268. package/dist/tools/registry.d.ts +29 -0
  269. package/dist/tools/registry.d.ts.map +1 -1
  270. package/dist/tools/registry.js +75 -0
  271. package/dist/tools/registry.js.map +1 -1
  272. package/dist/tools/run_on_plan.d.ts +46 -0
  273. package/dist/tools/run_on_plan.d.ts.map +1 -0
  274. package/dist/tools/run_on_plan.js +89 -0
  275. package/dist/tools/run_on_plan.js.map +1 -0
  276. package/dist/tools/takoapi.d.ts +60 -0
  277. package/dist/tools/takoapi.d.ts.map +1 -0
  278. package/dist/tools/takoapi.js +181 -0
  279. package/dist/tools/takoapi.js.map +1 -0
  280. package/dist/tools/validate.d.ts +22 -0
  281. package/dist/tools/validate.d.ts.map +1 -0
  282. package/dist/tools/validate.js +50 -0
  283. package/dist/tools/validate.js.map +1 -0
  284. package/dist/voice/dictation.d.ts +51 -0
  285. package/dist/voice/dictation.d.ts.map +1 -0
  286. package/dist/voice/dictation.js +70 -0
  287. package/dist/voice/dictation.js.map +1 -0
  288. package/dist/web/agent-roster.d.ts +56 -0
  289. package/dist/web/agent-roster.d.ts.map +1 -0
  290. package/dist/web/agent-roster.js +109 -0
  291. package/dist/web/agent-roster.js.map +1 -0
  292. package/dist/web/devices.d.ts +27 -0
  293. package/dist/web/devices.d.ts.map +1 -0
  294. package/dist/web/devices.js +113 -0
  295. package/dist/web/devices.js.map +1 -0
  296. package/dist/web/island.d.ts +5 -1
  297. package/dist/web/island.d.ts.map +1 -1
  298. package/dist/web/island.js +427 -67
  299. package/dist/web/island.js.map +1 -1
  300. package/dist/web/lisa-client.d.ts +20 -0
  301. package/dist/web/lisa-client.d.ts.map +1 -0
  302. package/dist/web/lisa-client.js +1323 -0
  303. package/dist/web/lisa-client.js.map +1 -0
  304. package/dist/web/lisa-css.d.ts +13 -0
  305. package/dist/web/lisa-css.d.ts.map +1 -0
  306. package/dist/web/lisa-css.js +1163 -0
  307. package/dist/web/lisa-css.js.map +1 -0
  308. package/dist/web/lisa-html.d.ts +1 -1
  309. package/dist/web/lisa-html.d.ts.map +1 -1
  310. package/dist/web/lisa-html.js +16 -2091
  311. package/dist/web/lisa-html.js.map +1 -1
  312. package/dist/web/push.d.ts +76 -0
  313. package/dist/web/push.d.ts.map +1 -0
  314. package/dist/web/push.js +163 -0
  315. package/dist/web/push.js.map +1 -0
  316. package/dist/web/server.d.ts +19 -0
  317. package/dist/web/server.d.ts.map +1 -1
  318. package/dist/web/server.js +898 -65
  319. package/dist/web/server.js.map +1 -1
  320. package/package.json +5 -2
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Local-model lifecycle (PLAN_MODEL_v1.0 M1).
3
+ *
4
+ * Before this, "local models" meant: the user installs Ollama themselves, runs
5
+ * `ollama serve`, and hand-edits LISA_BASE_URL in config.env. This module makes
6
+ * it a first-class option — install / list / health / switch — while still
7
+ * routing through the existing OpenAI-compatible provider (Ollama et al. speak
8
+ * the OpenAI API), so no provider code changes.
9
+ *
10
+ * The runtime (process exec + HTTP) is injectable so the logic is unit-testable
11
+ * without a real Ollama install.
12
+ */
13
+ import { spawn } from "node:child_process";
14
+ export const defaultRuntime = {
15
+ exec(cmd, args, onLine) {
16
+ return new Promise((resolve) => {
17
+ let stdout = "";
18
+ let stderr = "";
19
+ let child;
20
+ try {
21
+ child = spawn(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
22
+ }
23
+ catch (err) {
24
+ resolve({ code: 127, stdout: "", stderr: err.message });
25
+ return;
26
+ }
27
+ const pump = (chunk, sink) => {
28
+ const s = chunk.toString();
29
+ if (sink === "out")
30
+ stdout += s;
31
+ else
32
+ stderr += s;
33
+ if (onLine)
34
+ for (const line of s.split("\n"))
35
+ if (line.trim())
36
+ onLine(line.trim());
37
+ };
38
+ child.stdout?.on("data", (c) => pump(c, "out"));
39
+ child.stderr?.on("data", (c) => pump(c, "err")); // ollama writes pull progress to stderr
40
+ child.on("error", (err) => resolve({ code: 127, stdout, stderr: stderr + err.message }));
41
+ child.on("close", (code) => resolve({ code: code ?? 0, stdout, stderr }));
42
+ });
43
+ },
44
+ async httpGet(url) {
45
+ try {
46
+ const res = await fetch(url);
47
+ return { ok: res.ok, status: res.status, body: await res.text() };
48
+ }
49
+ catch {
50
+ return { ok: false, status: 0, body: "" };
51
+ }
52
+ },
53
+ };
54
+ /** Default OpenAI-compatible endpoints per local backend. Pure. */
55
+ export function localEndpoint(backend) {
56
+ const hosts = {
57
+ ollama: "http://localhost:11434",
58
+ lmstudio: "http://localhost:1234",
59
+ llamacpp: "http://localhost:8080",
60
+ };
61
+ const envHost = backend === "ollama" ? process.env.OLLAMA_HOST : undefined;
62
+ const host = (envHost || hosts[backend] || hosts.ollama).replace(/\/$/, "");
63
+ return { host, baseURL: `${host}/v1`, apiKey: backend };
64
+ }
65
+ /** Parse a `local://[backend/]model` reference. Pure. */
66
+ export function parseLocalRef(ref) {
67
+ const m = ref.match(/^local:\/\/(.+)$/);
68
+ if (!m)
69
+ return null;
70
+ const rest = m[1].trim();
71
+ if (!rest)
72
+ return null;
73
+ const known = new Set(["ollama", "lmstudio", "llamacpp"]);
74
+ const slash = rest.indexOf("/");
75
+ if (slash > 0 && known.has(rest.slice(0, slash))) {
76
+ return { backend: rest.slice(0, slash), model: rest.slice(slash + 1) };
77
+ }
78
+ return { backend: "ollama", model: rest };
79
+ }
80
+ /** Parse Ollama's /api/tags JSON into model infos. Pure. */
81
+ export function parseOllamaTags(body) {
82
+ try {
83
+ const json = JSON.parse(body);
84
+ return (json.models ?? [])
85
+ .filter((m) => typeof m.name === "string")
86
+ .map((m) => ({ name: m.name, sizeBytes: typeof m.size === "number" ? m.size : undefined }));
87
+ }
88
+ catch {
89
+ return [];
90
+ }
91
+ }
92
+ /** The Ollama backend: install / list / health via its CLI + HTTP API. */
93
+ export class OllamaBackend {
94
+ runtime;
95
+ name = "ollama";
96
+ host;
97
+ constructor(runtime = defaultRuntime, host = localEndpoint("ollama").host) {
98
+ this.runtime = runtime;
99
+ this.host = host.replace(/\/$/, "");
100
+ }
101
+ async health() {
102
+ const res = await this.runtime.httpGet(`${this.host}/api/tags`);
103
+ return res.ok ? "up" : "down";
104
+ }
105
+ async listInstalled() {
106
+ const res = await this.runtime.httpGet(`${this.host}/api/tags`);
107
+ return res.ok ? parseOllamaTags(res.body) : [];
108
+ }
109
+ async install(model, onLine) {
110
+ const { code, stderr } = await this.runtime.exec("ollama", ["pull", model], onLine);
111
+ if (code === 0)
112
+ return;
113
+ throw new Error(code === 127
114
+ ? "ollama CLI not found — install it from https://ollama.com, then retry"
115
+ : `\`ollama pull ${model}\` failed: ${stderr.trim().slice(-200) || `exit ${code}`}`);
116
+ }
117
+ }
118
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/model/local.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { PlanId } from "./plans.js";
2
+ /** Claude subscription limits reset on a rolling ~5h basis. */
3
+ export declare const WINDOW_HOURS = 5;
4
+ export interface PlanUsage {
5
+ /** Gross tokens (input + output + cache create + cache read) in the rolling window. */
6
+ windowTokens: number;
7
+ windowHours: number;
8
+ /** Gross tokens since local midnight. */
9
+ todayTokens: number;
10
+ /** Transcript files that contributed to the window/today. */
11
+ sessions: number;
12
+ }
13
+ interface UsageEntry {
14
+ atMs: number;
15
+ tokens: number;
16
+ }
17
+ /** Sum the billable token fields from a Claude `usage` object. Pure. */
18
+ export declare function usageTokens(u: Record<string, unknown>): number;
19
+ /** Local midnight (ms) for the day containing nowMs. Pure-ish (no Date.now). */
20
+ export declare function startOfLocalDay(nowMs: number): number;
21
+ /** Bucket timestamped token entries into rolling-window + today sums. Pure. */
22
+ export declare function aggregateUsage(entries: UsageEntry[], nowMs: number, windowMs: number, dayStartMs: number): {
23
+ windowTokens: number;
24
+ todayTokens: number;
25
+ };
26
+ /**
27
+ * Read Claude Code's local transcripts and sum token usage over the rolling
28
+ * window + today. Returns null if the projects dir is absent/unreadable.
29
+ */
30
+ export declare function readClaudeUsage(opts: {
31
+ home?: string;
32
+ nowMs: number;
33
+ }): PlanUsage | null;
34
+ /** Usage for a plan, or null if it has no readable local token log. */
35
+ export declare function planUsage(id: PlanId, nowMs: number): PlanUsage | null;
36
+ /** Compact token count, e.g. 1234567 → "1.2M". Pure. */
37
+ export declare function formatTokens(n: number): string;
38
+ /** One-line usage summary, e.g. "1.2M tok in 5h · 4.8M today". Pure. */
39
+ export declare function formatUsage(u: PlanUsage): string;
40
+ export {};
41
+ //# sourceMappingURL=plan-usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-usage.d.ts","sourceRoot":"","sources":["../../src/model/plan-usage.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,+DAA+D;AAC/D,eAAO,MAAM,YAAY,IAAI,CAAC;AAI9B,MAAM,WAAW,SAAS;IACxB,uFAAuF;IACvF,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAO9D;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIrD;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,OAAO,EAAE,UAAU,EAAE,EACrB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAS/C;AA6BD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAAG,IAAI,CAwDxF;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAGrE;AAED,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAEhD"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Real coding-plan usage (CODING_PLANS Phase 5a) — honest, local, no faked %.
3
+ *
4
+ * Subscription plans are rate-limited, not metered, and the per-window limit
5
+ * isn't published in token terms — so we do NOT invent a "headroom %". What we
6
+ * CAN show truthfully is *consumption*: Claude Code records per-turn token usage
7
+ * in its local transcripts (`~/.claude/projects/**​/*.jsonl`), each line stamped
8
+ * with a `timestamp` and a `message.usage` object. Summing those over Claude's
9
+ * rolling ~5-hour limit window (and since local midnight) is real usage from
10
+ * local data — the same `usage` field the claude-code observer already reads, so
11
+ * the metadata-not-payload privacy posture holds (we read token COUNTS and
12
+ * timestamps only, never message content).
13
+ *
14
+ * Codex / Copilot have no comparable standard local token log, so usage is null
15
+ * for them rather than guessed.
16
+ */
17
+ import { readdirSync, statSync, readFileSync } from "node:fs";
18
+ import { homedir } from "node:os";
19
+ import { join } from "node:path";
20
+ /** Claude subscription limits reset on a rolling ~5h basis. */
21
+ export const WINDOW_HOURS = 5;
22
+ /** Safety cap on transcript files scanned per call (newest first). */
23
+ const MAX_FILES = 80;
24
+ function num(v) {
25
+ return typeof v === "number" && Number.isFinite(v) ? v : 0;
26
+ }
27
+ /** Sum the billable token fields from a Claude `usage` object. Pure. */
28
+ export function usageTokens(u) {
29
+ return (num(u.input_tokens) +
30
+ num(u.output_tokens) +
31
+ num(u.cache_creation_input_tokens) +
32
+ num(u.cache_read_input_tokens));
33
+ }
34
+ /** Local midnight (ms) for the day containing nowMs. Pure-ish (no Date.now). */
35
+ export function startOfLocalDay(nowMs) {
36
+ const d = new Date(nowMs);
37
+ d.setHours(0, 0, 0, 0);
38
+ return d.getTime();
39
+ }
40
+ /** Bucket timestamped token entries into rolling-window + today sums. Pure. */
41
+ export function aggregateUsage(entries, nowMs, windowMs, dayStartMs) {
42
+ const windowStart = nowMs - windowMs;
43
+ let windowTokens = 0;
44
+ let todayTokens = 0;
45
+ for (const e of entries) {
46
+ if (e.atMs >= windowStart)
47
+ windowTokens += e.tokens;
48
+ if (e.atMs >= dayStartMs)
49
+ todayTokens += e.tokens;
50
+ }
51
+ return { windowTokens, todayTokens };
52
+ }
53
+ /** Recursively collect `*.jsonl` paths under dir (Claude nests one level). */
54
+ function listTranscripts(dir) {
55
+ const out = [];
56
+ const walk = (d, depth) => {
57
+ let ents;
58
+ try {
59
+ ents = readdirSync(d, { withFileTypes: true });
60
+ }
61
+ catch {
62
+ return;
63
+ }
64
+ for (const ent of ents) {
65
+ const p = join(d, ent.name);
66
+ if (ent.isDirectory()) {
67
+ if (depth < 3)
68
+ walk(p, depth + 1);
69
+ }
70
+ else if (ent.isFile() && ent.name.endsWith(".jsonl")) {
71
+ try {
72
+ out.push({ path: p, mtimeMs: statSync(p).mtimeMs });
73
+ }
74
+ catch {
75
+ /* unreadable → skip */
76
+ }
77
+ }
78
+ }
79
+ };
80
+ walk(dir, 0);
81
+ return out;
82
+ }
83
+ /**
84
+ * Read Claude Code's local transcripts and sum token usage over the rolling
85
+ * window + today. Returns null if the projects dir is absent/unreadable.
86
+ */
87
+ export function readClaudeUsage(opts) {
88
+ const home = opts.home ?? process.env.CLAUDE_HOME ?? join(homedir(), ".claude");
89
+ const projects = join(home, "projects");
90
+ const nowMs = opts.nowMs;
91
+ const windowMs = WINDOW_HOURS * 3_600_000;
92
+ const dayStart = startOfLocalDay(nowMs);
93
+ const scanFrom = Math.min(nowMs - windowMs, dayStart);
94
+ let files;
95
+ try {
96
+ files = listTranscripts(projects);
97
+ }
98
+ catch {
99
+ return null;
100
+ }
101
+ if (files.length === 0)
102
+ return null;
103
+ // Only files touched within the scan window can hold in-window entries.
104
+ // Newest first, capped, so a heavy history can't make this unbounded.
105
+ const recent = files
106
+ .filter((f) => f.mtimeMs >= scanFrom)
107
+ .sort((a, b) => b.mtimeMs - a.mtimeMs)
108
+ .slice(0, MAX_FILES);
109
+ const entries = [];
110
+ let sessions = 0;
111
+ for (const f of recent) {
112
+ let raw;
113
+ try {
114
+ raw = readFileSync(f.path, "utf8");
115
+ }
116
+ catch {
117
+ continue;
118
+ }
119
+ let contributed = false;
120
+ for (const line of raw.split("\n")) {
121
+ if (!line)
122
+ continue;
123
+ let e;
124
+ try {
125
+ e = JSON.parse(line);
126
+ }
127
+ catch {
128
+ continue;
129
+ }
130
+ const atMs = Date.parse(typeof e.timestamp === "string" ? e.timestamp : "");
131
+ if (!Number.isFinite(atMs) || atMs < scanFrom)
132
+ continue;
133
+ const u = e.message?.usage;
134
+ if (!u || typeof u !== "object")
135
+ continue;
136
+ const tokens = usageTokens(u);
137
+ if (tokens > 0) {
138
+ entries.push({ atMs, tokens });
139
+ contributed = true;
140
+ }
141
+ }
142
+ if (contributed)
143
+ sessions++;
144
+ }
145
+ const { windowTokens, todayTokens } = aggregateUsage(entries, nowMs, windowMs, dayStart);
146
+ return { windowTokens, windowHours: WINDOW_HOURS, todayTokens, sessions };
147
+ }
148
+ /** Usage for a plan, or null if it has no readable local token log. */
149
+ export function planUsage(id, nowMs) {
150
+ if (id === "claude")
151
+ return readClaudeUsage({ nowMs });
152
+ return null; // codex / copilot: no standard local token log
153
+ }
154
+ /** Compact token count, e.g. 1234567 → "1.2M". Pure. */
155
+ export function formatTokens(n) {
156
+ if (n >= 1e9)
157
+ return (n / 1e9).toFixed(1) + "B";
158
+ if (n >= 1e6)
159
+ return (n / 1e6).toFixed(1) + "M";
160
+ if (n >= 1e3)
161
+ return Math.round(n / 1e3) + "K";
162
+ return String(n);
163
+ }
164
+ /** One-line usage summary, e.g. "1.2M tok in 5h · 4.8M today". Pure. */
165
+ export function formatUsage(u) {
166
+ return `${formatTokens(u.windowTokens)} tok in ${u.windowHours}h · ${formatTokens(u.todayTokens)} today`;
167
+ }
168
+ //# sourceMappingURL=plan-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-usage.js","sourceRoot":"","sources":["../../src/model/plan-usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ export type PlanId = "claude" | "codex" | "copilot";
2
+ export declare const PLAN_IDS: readonly PlanId[];
3
+ export interface PlanStatus {
4
+ id: PlanId;
5
+ /** Human label, e.g. "Claude Pro/Max". */
6
+ label: string;
7
+ /** The vendor CLI that owns this plan's auth. */
8
+ cli: string;
9
+ /** Resolved binary path/name, or null if not found. */
10
+ binary: string | null;
11
+ /** Is the CLI installed (binary present)? */
12
+ available: boolean;
13
+ /**
14
+ * Best-effort login signal from credential *presence* (never contents):
15
+ * true = a credential file / token env was found, false = looked and found
16
+ * none, null = can't tell (e.g. macOS Keychain — opaque without reading it).
17
+ */
18
+ loggedIn: boolean | null;
19
+ /** Short human hint about state / how to enable. */
20
+ detail: string;
21
+ }
22
+ /** Injectable view of the host used for presence-only detection. Pure inputs. */
23
+ export interface PlanProbe {
24
+ home: string;
25
+ platform: NodeJS.Platform;
26
+ env: Record<string, string | undefined>;
27
+ /** Does a file/dir exist at this absolute path? */
28
+ exists(p: string): boolean;
29
+ /** Directory entries, or [] on any error. */
30
+ readdir(p: string): string[];
31
+ /** Is `cmd` an executable on PATH (or an existing absolute path)? */
32
+ onPath(cmd: string): boolean;
33
+ }
34
+ /** The real host probe (filesystem + PATH + env). */
35
+ export declare function defaultPlanProbe(): PlanProbe;
36
+ /** Is `cmd` resolvable on PATH? Absolute/relative paths are checked directly. Pure-ish. */
37
+ export declare function onPath(cmd: string, env: Record<string, string | undefined>): boolean;
38
+ /** Parse a `plan://<id>` reference into a known PlanId, else null. Pure. */
39
+ export declare function parsePlanRef(ref: string): PlanId | null;
40
+ /** Currently selected coding-plan delegation target, if any (LISA_CODING_PLAN). */
41
+ export declare function selectedPlan(env?: Record<string, string | undefined>): PlanId | null;
42
+ /** Detect one plan's status. */
43
+ export declare function detectPlan(id: PlanId, probe?: PlanProbe): PlanStatus;
44
+ /** Detect every known plan. */
45
+ export declare function detectPlans(probe?: PlanProbe): PlanStatus[];
46
+ /**
47
+ * The headless dispatch CLI kind a plan delegates through. Each plan id is also
48
+ * its CLI kind in launchAgent: claude → `claude -p`, codex → `codex exec`,
49
+ * copilot → `copilot -p`.
50
+ */
51
+ export declare function planDispatchKind(id: PlanId): "claude" | "codex" | "copilot";
52
+ export interface PlanPreflight {
53
+ ok: boolean;
54
+ /** Why delegation can't proceed (only when ok=false). */
55
+ reason?: string;
56
+ }
57
+ /**
58
+ * Can we delegate coding work to this detected plan right now? Pure. A null
59
+ * (unknown) login passes — on macOS the credential lives in the Keychain and
60
+ * "installed but login unverifiable" should not block; the CLI itself will
61
+ * prompt if truly logged out.
62
+ */
63
+ export declare function planPreflight(status: PlanStatus): PlanPreflight;
64
+ /** Status glyph: ✓ logged in · ✗ unavailable/logged-out · ? installed, login unknown. Pure. */
65
+ export declare function planMark(s: PlanStatus): "✓" | "✗" | "?";
66
+ /**
67
+ * One-line coding-plan summary for surfaces like `lisa agents`. Pure. Shows the
68
+ * selected delegation target (★) and each plan's glyph. Headroom/rate-limit
69
+ * numbers are intentionally omitted — they'd need version-fragile parsing of the
70
+ * vendor CLI's output, and a wrong number is worse than none.
71
+ */
72
+ export declare function planSummaryLine(statuses: PlanStatus[], selected: PlanId | null): string;
73
+ //# sourceMappingURL=plans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../../src/model/plans.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAEpD,eAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,EAAmC,CAAC;AAE1E,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACxC,mDAAmD;IACnD,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,6CAA6C;IAC7C,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,qEAAqE;IACrE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9B;AAED,qDAAqD;AACrD,wBAAgB,gBAAgB,IAAI,SAAS,CAsB5C;AAED,2FAA2F;AAC3F,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAsBpF;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKvD;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,GAAG,IAAI,CAGjG;AAkGD,gCAAgC;AAChC,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,GAAE,SAA8B,GAAG,UAAU,CASxF;AAED,+BAA+B;AAC/B,wBAAgB,WAAW,CAAC,KAAK,GAAE,SAA8B,GAAG,UAAU,EAAE,CAE/E;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAE3E;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAK/D;AAID,+FAA+F;AAC/F,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAIvD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAIvF"}