@tonycasey/lisa 2.2.0 → 2.5.5

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 (262) hide show
  1. package/dist/lib/application/handlers/PromptSubmitHandler.d.ts +22 -12
  2. package/dist/lib/application/handlers/PromptSubmitHandler.d.ts.map +1 -1
  3. package/dist/lib/application/handlers/PromptSubmitHandler.js +36 -13
  4. package/dist/lib/application/handlers/PromptSubmitHandler.js.map +1 -1
  5. package/dist/lib/application/handlers/SessionStartHandler.d.ts +47 -5
  6. package/dist/lib/application/handlers/SessionStartHandler.d.ts.map +1 -1
  7. package/dist/lib/application/handlers/SessionStartHandler.js +164 -37
  8. package/dist/lib/application/handlers/SessionStartHandler.js.map +1 -1
  9. package/dist/lib/application/handlers/SessionStopHandler.d.ts +29 -5
  10. package/dist/lib/application/handlers/SessionStopHandler.d.ts.map +1 -1
  11. package/dist/lib/application/handlers/SessionStopHandler.js +83 -11
  12. package/dist/lib/application/handlers/SessionStopHandler.js.map +1 -1
  13. package/dist/lib/application/interfaces/index.d.ts +1 -0
  14. package/dist/lib/application/interfaces/index.d.ts.map +1 -1
  15. package/dist/lib/application/mediator/IMediator.d.ts +73 -0
  16. package/dist/lib/application/mediator/IMediator.d.ts.map +1 -0
  17. package/dist/lib/application/mediator/IMediator.js +12 -0
  18. package/dist/lib/application/mediator/IMediator.js.map +1 -0
  19. package/dist/lib/application/mediator/Mediator.d.ts +29 -0
  20. package/dist/lib/application/mediator/Mediator.d.ts.map +1 -0
  21. package/dist/lib/application/mediator/Mediator.js +53 -0
  22. package/dist/lib/application/mediator/Mediator.js.map +1 -0
  23. package/dist/lib/application/mediator/index.d.ts +10 -0
  24. package/dist/lib/application/mediator/index.d.ts.map +1 -0
  25. package/dist/lib/application/mediator/index.js +18 -0
  26. package/dist/lib/application/mediator/index.js.map +1 -0
  27. package/dist/lib/application/mediator/requests/PromptSubmitRequest.d.ts +60 -0
  28. package/dist/lib/application/mediator/requests/PromptSubmitRequest.d.ts.map +1 -0
  29. package/dist/lib/application/mediator/requests/PromptSubmitRequest.js +35 -0
  30. package/dist/lib/application/mediator/requests/PromptSubmitRequest.js.map +1 -0
  31. package/dist/lib/application/mediator/requests/SessionStartRequest.d.ts +36 -0
  32. package/dist/lib/application/mediator/requests/SessionStartRequest.d.ts.map +1 -0
  33. package/dist/lib/application/mediator/requests/SessionStartRequest.js +32 -0
  34. package/dist/lib/application/mediator/requests/SessionStartRequest.js.map +1 -0
  35. package/dist/lib/application/mediator/requests/SessionStopRequest.d.ts +67 -0
  36. package/dist/lib/application/mediator/requests/SessionStopRequest.d.ts.map +1 -0
  37. package/dist/lib/application/mediator/requests/SessionStopRequest.js +35 -0
  38. package/dist/lib/application/mediator/requests/SessionStopRequest.js.map +1 -0
  39. package/dist/lib/application/mediator/requests/index.d.ts +9 -0
  40. package/dist/lib/application/mediator/requests/index.d.ts.map +1 -0
  41. package/dist/lib/application/mediator/requests/index.js +13 -0
  42. package/dist/lib/application/mediator/requests/index.js.map +1 -0
  43. package/dist/lib/cli.d.ts +2 -44
  44. package/dist/lib/cli.d.ts.map +1 -1
  45. package/dist/lib/cli.js +351 -606
  46. package/dist/lib/cli.js.map +1 -1
  47. package/dist/lib/commands/docker.d.ts +20 -0
  48. package/dist/lib/commands/docker.d.ts.map +1 -0
  49. package/dist/lib/commands/docker.js +27 -0
  50. package/dist/lib/commands/docker.js.map +1 -0
  51. package/dist/lib/commands/doctor.d.ts +94 -0
  52. package/dist/lib/commands/doctor.d.ts.map +1 -0
  53. package/dist/lib/commands/doctor.js +716 -0
  54. package/dist/lib/commands/doctor.js.map +1 -0
  55. package/dist/lib/commands/index.d.ts +10 -0
  56. package/dist/lib/commands/index.d.ts.map +1 -0
  57. package/dist/lib/commands/index.js +31 -0
  58. package/dist/lib/commands/index.js.map +1 -0
  59. package/dist/lib/commands/init.d.ts +31 -0
  60. package/dist/lib/commands/init.d.ts.map +1 -0
  61. package/dist/lib/commands/init.js +497 -0
  62. package/dist/lib/commands/init.js.map +1 -0
  63. package/dist/lib/commands/shared/constants.d.ts +27 -0
  64. package/dist/lib/commands/shared/constants.d.ts.map +1 -0
  65. package/dist/lib/commands/shared/constants.js +46 -0
  66. package/dist/lib/commands/shared/constants.js.map +1 -0
  67. package/dist/lib/commands/shared/index.d.ts +5 -0
  68. package/dist/lib/commands/shared/index.d.ts.map +1 -0
  69. package/dist/lib/commands/shared/index.js +15 -0
  70. package/dist/lib/commands/shared/index.js.map +1 -0
  71. package/dist/lib/domain/index.d.ts +4 -2
  72. package/dist/lib/domain/index.d.ts.map +1 -1
  73. package/dist/lib/domain/index.js +5 -2
  74. package/dist/lib/domain/index.js.map +1 -1
  75. package/dist/lib/domain/interfaces/ILabelInference.d.ts +62 -0
  76. package/dist/lib/domain/interfaces/ILabelInference.d.ts.map +1 -0
  77. package/dist/lib/domain/interfaces/ILabelInference.js +11 -0
  78. package/dist/lib/domain/interfaces/ILabelInference.js.map +1 -0
  79. package/dist/lib/domain/interfaces/ILisaServices.d.ts +6 -0
  80. package/dist/lib/domain/interfaces/ILisaServices.d.ts.map +1 -1
  81. package/dist/lib/domain/interfaces/IMcpClient.d.ts +15 -2
  82. package/dist/lib/domain/interfaces/IMcpClient.d.ts.map +1 -1
  83. package/dist/lib/domain/interfaces/ISessionCaptureService.d.ts +2 -1
  84. package/dist/lib/domain/interfaces/ISessionCaptureService.d.ts.map +1 -1
  85. package/dist/lib/domain/interfaces/IStructuredLog.d.ts +162 -0
  86. package/dist/lib/domain/interfaces/IStructuredLog.d.ts.map +1 -0
  87. package/dist/lib/domain/interfaces/IStructuredLog.js +85 -0
  88. package/dist/lib/domain/interfaces/IStructuredLog.js.map +1 -0
  89. package/dist/lib/domain/interfaces/index.d.ts +2 -0
  90. package/dist/lib/domain/interfaces/index.d.ts.map +1 -1
  91. package/dist/lib/domain/interfaces/index.js +6 -0
  92. package/dist/lib/domain/interfaces/index.js.map +1 -1
  93. package/dist/lib/domain/interfaces/types/ITask.d.ts +16 -0
  94. package/dist/lib/domain/interfaces/types/ITask.d.ts.map +1 -1
  95. package/dist/lib/domain/interfaces/types/ITask.js.map +1 -1
  96. package/dist/lib/domain/utils/cancellation.d.ts +111 -0
  97. package/dist/lib/domain/utils/cancellation.d.ts.map +1 -0
  98. package/dist/lib/domain/utils/cancellation.js +168 -0
  99. package/dist/lib/domain/utils/cancellation.js.map +1 -0
  100. package/dist/lib/domain/utils/index.d.ts +8 -0
  101. package/dist/lib/domain/utils/index.d.ts.map +1 -0
  102. package/dist/lib/domain/utils/index.js +16 -0
  103. package/dist/lib/domain/utils/index.js.map +1 -0
  104. package/dist/lib/infrastructure/adapters/claude/session-start.d.ts +1 -1
  105. package/dist/lib/infrastructure/adapters/claude/session-start.js +9 -11
  106. package/dist/lib/infrastructure/adapters/claude/session-start.js.map +1 -1
  107. package/dist/lib/infrastructure/adapters/claude/session-stop.d.ts +1 -5
  108. package/dist/lib/infrastructure/adapters/claude/session-stop.d.ts.map +1 -1
  109. package/dist/lib/infrastructure/adapters/claude/session-stop.js +12 -15
  110. package/dist/lib/infrastructure/adapters/claude/session-stop.js.map +1 -1
  111. package/dist/lib/infrastructure/adapters/claude/user-prompt-submit.d.ts +1 -1
  112. package/dist/lib/infrastructure/adapters/claude/user-prompt-submit.js +9 -11
  113. package/dist/lib/infrastructure/adapters/claude/user-prompt-submit.js.map +1 -1
  114. package/dist/lib/infrastructure/adapters/opencode/plugin.d.ts +2 -2
  115. package/dist/lib/infrastructure/adapters/opencode/plugin.d.ts.map +1 -1
  116. package/dist/lib/infrastructure/adapters/opencode/plugin.js +16 -21
  117. package/dist/lib/infrastructure/adapters/opencode/plugin.js.map +1 -1
  118. package/dist/lib/infrastructure/cli/index.d.ts +8 -0
  119. package/dist/lib/infrastructure/cli/index.d.ts.map +1 -0
  120. package/dist/lib/infrastructure/cli/index.js +15 -0
  121. package/dist/lib/infrastructure/cli/index.js.map +1 -0
  122. package/dist/lib/infrastructure/cli/io.d.ts +91 -0
  123. package/dist/lib/infrastructure/cli/io.d.ts.map +1 -0
  124. package/dist/lib/infrastructure/cli/io.js +128 -0
  125. package/dist/lib/infrastructure/cli/io.js.map +1 -0
  126. package/dist/lib/infrastructure/dal/connections/McpConnectionManager.js +1 -1
  127. package/dist/lib/infrastructure/dal/connections/McpConnectionManager.js.map +1 -1
  128. package/dist/lib/infrastructure/dal/repositories/mcp/McpTaskRepository.d.ts.map +1 -1
  129. package/dist/lib/infrastructure/dal/repositories/mcp/McpTaskRepository.js +6 -2
  130. package/dist/lib/infrastructure/dal/repositories/mcp/McpTaskRepository.js.map +1 -1
  131. package/dist/lib/infrastructure/dal/repositories/neo4j/Neo4jTaskRepository.d.ts +5 -2
  132. package/dist/lib/infrastructure/dal/repositories/neo4j/Neo4jTaskRepository.d.ts.map +1 -1
  133. package/dist/lib/infrastructure/dal/repositories/neo4j/Neo4jTaskRepository.js +78 -45
  134. package/dist/lib/infrastructure/dal/repositories/neo4j/Neo4jTaskRepository.js.map +1 -1
  135. package/dist/lib/infrastructure/dal/repositories/zep/ZepTaskRepository.d.ts.map +1 -1
  136. package/dist/lib/infrastructure/dal/repositories/zep/ZepTaskRepository.js +6 -2
  137. package/dist/lib/infrastructure/dal/repositories/zep/ZepTaskRepository.js.map +1 -1
  138. package/dist/lib/infrastructure/di/Container.d.ts +72 -0
  139. package/dist/lib/infrastructure/di/Container.d.ts.map +1 -0
  140. package/dist/lib/infrastructure/di/Container.js +182 -0
  141. package/dist/lib/infrastructure/di/Container.js.map +1 -0
  142. package/dist/lib/infrastructure/di/IContainer.d.ts +87 -0
  143. package/dist/lib/infrastructure/di/IContainer.d.ts.map +1 -0
  144. package/dist/lib/infrastructure/di/IContainer.js +11 -0
  145. package/dist/lib/infrastructure/di/IContainer.js.map +1 -0
  146. package/dist/lib/infrastructure/di/ServiceFactory.d.ts +6 -0
  147. package/dist/lib/infrastructure/di/ServiceFactory.d.ts.map +1 -1
  148. package/dist/lib/infrastructure/di/ServiceFactory.js +66 -0
  149. package/dist/lib/infrastructure/di/ServiceFactory.js.map +1 -1
  150. package/dist/lib/infrastructure/di/bootstrap.d.ts +43 -0
  151. package/dist/lib/infrastructure/di/bootstrap.d.ts.map +1 -0
  152. package/dist/lib/infrastructure/di/bootstrap.js +272 -0
  153. package/dist/lib/infrastructure/di/bootstrap.js.map +1 -0
  154. package/dist/lib/infrastructure/di/index.d.ts +6 -0
  155. package/dist/lib/infrastructure/di/index.d.ts.map +1 -1
  156. package/dist/lib/infrastructure/di/index.js +15 -1
  157. package/dist/lib/infrastructure/di/index.js.map +1 -1
  158. package/dist/lib/infrastructure/di/tokens.d.ts +70 -0
  159. package/dist/lib/infrastructure/di/tokens.d.ts.map +1 -0
  160. package/dist/lib/infrastructure/di/tokens.js +58 -0
  161. package/dist/lib/infrastructure/di/tokens.js.map +1 -0
  162. package/dist/lib/infrastructure/index.d.ts +1 -0
  163. package/dist/lib/infrastructure/index.d.ts.map +1 -1
  164. package/dist/lib/infrastructure/index.js +2 -0
  165. package/dist/lib/infrastructure/index.js.map +1 -1
  166. package/dist/lib/infrastructure/logging/Logger.d.ts +51 -4
  167. package/dist/lib/infrastructure/logging/Logger.d.ts.map +1 -1
  168. package/dist/lib/infrastructure/logging/Logger.js +127 -2
  169. package/dist/lib/infrastructure/logging/Logger.js.map +1 -1
  170. package/dist/lib/infrastructure/mcp/McpClient.d.ts +36 -1
  171. package/dist/lib/infrastructure/mcp/McpClient.d.ts.map +1 -1
  172. package/dist/lib/infrastructure/mcp/McpClient.js +68 -2
  173. package/dist/lib/infrastructure/mcp/McpClient.js.map +1 -1
  174. package/dist/lib/infrastructure/services/LabelInferenceService.d.ts +33 -0
  175. package/dist/lib/infrastructure/services/LabelInferenceService.d.ts.map +1 -0
  176. package/dist/lib/infrastructure/services/LabelInferenceService.js +225 -0
  177. package/dist/lib/infrastructure/services/LabelInferenceService.js.map +1 -0
  178. package/dist/lib/infrastructure/services/MemoryService.d.ts +18 -1
  179. package/dist/lib/infrastructure/services/MemoryService.d.ts.map +1 -1
  180. package/dist/lib/infrastructure/services/MemoryService.js +117 -52
  181. package/dist/lib/infrastructure/services/MemoryService.js.map +1 -1
  182. package/dist/lib/infrastructure/services/SessionCaptureService.d.ts +74 -20
  183. package/dist/lib/infrastructure/services/SessionCaptureService.d.ts.map +1 -1
  184. package/dist/lib/infrastructure/services/SessionCaptureService.js +331 -22
  185. package/dist/lib/infrastructure/services/SessionCaptureService.js.map +1 -1
  186. package/dist/lib/infrastructure/services/index.d.ts +1 -0
  187. package/dist/lib/infrastructure/services/index.d.ts.map +1 -1
  188. package/dist/lib/infrastructure/services/index.js +4 -1
  189. package/dist/lib/infrastructure/services/index.js.map +1 -1
  190. package/dist/lib/infrastructure/utils/index.d.ts +10 -0
  191. package/dist/lib/infrastructure/utils/index.d.ts.map +1 -0
  192. package/dist/lib/infrastructure/utils/index.js +26 -0
  193. package/dist/lib/infrastructure/utils/index.js.map +1 -0
  194. package/dist/lib/skills/github/github.d.ts +27 -0
  195. package/dist/lib/skills/github/github.d.ts.map +1 -0
  196. package/dist/lib/skills/github/github.js +408 -0
  197. package/dist/lib/skills/github/github.js.map +1 -0
  198. package/dist/lib/skills/shared/clients/GhCliClient.d.ts +17 -0
  199. package/dist/lib/skills/shared/clients/GhCliClient.d.ts.map +1 -0
  200. package/dist/lib/skills/shared/clients/GhCliClient.js +244 -0
  201. package/dist/lib/skills/shared/clients/GhCliClient.js.map +1 -0
  202. package/dist/lib/skills/shared/clients/McpClient.d.ts +12 -0
  203. package/dist/lib/skills/shared/clients/McpClient.d.ts.map +1 -1
  204. package/dist/lib/skills/shared/clients/McpClient.js +121 -76
  205. package/dist/lib/skills/shared/clients/McpClient.js.map +1 -1
  206. package/dist/lib/skills/shared/clients/index.d.ts +1 -0
  207. package/dist/lib/skills/shared/clients/index.d.ts.map +1 -1
  208. package/dist/lib/skills/shared/clients/index.js +4 -1
  209. package/dist/lib/skills/shared/clients/index.js.map +1 -1
  210. package/dist/lib/skills/shared/clients/interfaces/IGhCliClient.d.ts +56 -0
  211. package/dist/lib/skills/shared/clients/interfaces/IGhCliClient.d.ts.map +1 -0
  212. package/dist/lib/skills/shared/clients/interfaces/IGhCliClient.js +7 -0
  213. package/dist/lib/skills/shared/clients/interfaces/IGhCliClient.js.map +1 -0
  214. package/dist/lib/skills/shared/clients/interfaces/IZepClient.d.ts +7 -1
  215. package/dist/lib/skills/shared/clients/interfaces/IZepClient.d.ts.map +1 -1
  216. package/dist/lib/skills/shared/clients/interfaces/index.d.ts +1 -0
  217. package/dist/lib/skills/shared/clients/interfaces/index.d.ts.map +1 -1
  218. package/dist/lib/skills/shared/clients/interfaces/index.js +1 -0
  219. package/dist/lib/skills/shared/clients/interfaces/index.js.map +1 -1
  220. package/dist/lib/skills/shared/services/GitHubService.d.ts +169 -0
  221. package/dist/lib/skills/shared/services/GitHubService.d.ts.map +1 -0
  222. package/dist/lib/skills/shared/services/GitHubService.js +493 -0
  223. package/dist/lib/skills/shared/services/GitHubService.js.map +1 -0
  224. package/dist/lib/skills/shared/services/GitHubSyncService.d.ts +124 -0
  225. package/dist/lib/skills/shared/services/GitHubSyncService.d.ts.map +1 -0
  226. package/dist/lib/skills/shared/services/GitHubSyncService.js +412 -0
  227. package/dist/lib/skills/shared/services/GitHubSyncService.js.map +1 -0
  228. package/dist/lib/skills/shared/services/TaskCliService.d.ts +4 -2
  229. package/dist/lib/skills/shared/services/TaskCliService.d.ts.map +1 -1
  230. package/dist/lib/skills/shared/services/TaskCliService.js +90 -6
  231. package/dist/lib/skills/shared/services/TaskCliService.js.map +1 -1
  232. package/dist/lib/skills/shared/services/TaskService.d.ts.map +1 -1
  233. package/dist/lib/skills/shared/services/TaskService.js +199 -21
  234. package/dist/lib/skills/shared/services/TaskService.js.map +1 -1
  235. package/dist/lib/skills/shared/services/index.d.ts +2 -0
  236. package/dist/lib/skills/shared/services/index.d.ts.map +1 -1
  237. package/dist/lib/skills/shared/services/index.js +7 -1
  238. package/dist/lib/skills/shared/services/index.js.map +1 -1
  239. package/dist/lib/skills/shared/services/interfaces/ITaskService.d.ts +56 -1
  240. package/dist/lib/skills/shared/services/interfaces/ITaskService.d.ts.map +1 -1
  241. package/dist/lib/skills/shared/utils/index.d.ts +1 -0
  242. package/dist/lib/skills/shared/utils/index.d.ts.map +1 -1
  243. package/dist/lib/skills/shared/utils/index.js +9 -1
  244. package/dist/lib/skills/shared/utils/index.js.map +1 -1
  245. package/dist/lib/skills/shared/utils/issue-refs.d.ts +127 -0
  246. package/dist/lib/skills/shared/utils/issue-refs.d.ts.map +1 -0
  247. package/dist/lib/skills/shared/utils/issue-refs.js +179 -0
  248. package/dist/lib/skills/shared/utils/issue-refs.js.map +1 -0
  249. package/dist/lib/skills/tasks/tasks.d.ts +5 -2
  250. package/dist/lib/skills/tasks/tasks.d.ts.map +1 -1
  251. package/dist/lib/skills/tasks/tasks.js +8 -3
  252. package/dist/lib/skills/tasks/tasks.js.map +1 -1
  253. package/dist/opencode/lisa.js +5886 -1310
  254. package/dist/package.json +1 -1
  255. package/dist/project/.lisa/skills/github/SKILL.md +415 -0
  256. package/dist/project/.lisa/skills/lisa/SKILL.md +22 -0
  257. package/dist/project/.lisa/skills/memory/SKILL.md +3 -2
  258. package/package.json +6 -5
  259. package/dist/hooks/session-start.js +0 -5763
  260. package/dist/hooks/session-stop.js +0 -5348
  261. package/dist/hooks/user-prompt-submit.js +0 -5406
  262. package/dist/project/.claude/config.js +0 -40
package/dist/lib/cli.js CHANGED
@@ -1,623 +1,81 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
3
36
  var __importDefault = (this && this.__importDefault) || function (mod) {
4
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
38
  };
6
39
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.runScan = exports.TEMPLATE_ROOT = exports.DEFAULT_GROUP = exports.DEFAULT_ENDPOINT = exports.createDefaultServices = void 0;
8
- exports.initCommand = initCommand;
9
- exports.doctorCommand = doctorCommand;
10
- exports.upCommand = upCommand;
11
- exports.downCommand = downCommand;
12
- exports.cleanupPreviousInstall = cleanupPreviousInstall;
40
+ exports.runScan = exports.TEMPLATE_ROOT = exports.DEFAULT_GROUP = exports.DEFAULT_ENDPOINT = exports.cleanupPreviousInstall = exports.createDefaultServices = exports.downCommand = exports.upCommand = exports.doctorCommand = exports.initCommand = void 0;
13
41
  const commander_1 = require("commander");
14
42
  const child_process_1 = require("child_process");
15
43
  const fs_extra_1 = __importDefault(require("fs-extra"));
16
44
  const path_1 = __importDefault(require("path"));
17
45
  const chalk_1 = __importDefault(require("chalk"));
18
- const prompts_1 = require("@inquirer/prompts");
19
46
  const services_1 = require("./services");
20
47
  Object.defineProperty(exports, "createDefaultServices", { enumerable: true, get: function () { return services_1.createDefaultServices; } });
21
48
  const scanner_1 = require("./scanner");
22
49
  Object.defineProperty(exports, "runScan", { enumerable: true, get: function () { return scanner_1.runScan; } });
23
50
  const infrastructure_1 = require("./infrastructure");
24
- // Templates are copied into dist/project by postbuild; resolve relative to compiled file.
25
- const TEMPLATE_ROOT = path_1.default.join(__dirname, '..', 'project');
26
- exports.TEMPLATE_ROOT = TEMPLATE_ROOT;
27
- // Bundled hooks and plugins are in dist/hooks and dist/opencode
28
- const BUNDLED_HOOKS_ROOT = path_1.default.join(__dirname, '..', 'hooks');
29
- const BUNDLED_OPENCODE_ROOT = path_1.default.join(__dirname, '..', 'opencode');
30
- // Read version from package.json (works in both dev and dist)
31
- const PACKAGE_JSON_PATH = path_1.default.join(__dirname, '..', '..', 'package.json');
32
- const VERSION = fs_extra_1.default.existsSync(PACKAGE_JSON_PATH)
33
- ? fs_extra_1.default.readJsonSync(PACKAGE_JSON_PATH).version
34
- : '0.0.0';
35
- const DEFAULT_ENDPOINT = 'http://localhost:8010/mcp/';
36
- exports.DEFAULT_ENDPOINT = DEFAULT_ENDPOINT;
37
- const ZEP_CLOUD_ENDPOINT = 'https://api.getzep.com/mcp/';
38
- /**
39
- * Get project name from package.json or directory name.
40
- * Used as the default group ID for memory storage.
41
- */
42
- function getProjectName() {
43
- try {
44
- const pkgPath = path_1.default.join(process.cwd(), 'package.json');
45
- if (fs_extra_1.default.existsSync(pkgPath)) {
46
- const pkg = fs_extra_1.default.readJsonSync(pkgPath);
47
- if (pkg.name) {
48
- // Remove scope prefix if present (e.g., @tonycasey/lisa -> lisa)
49
- return pkg.name.replace(/^@[^/]+\//, '');
50
- }
51
- }
52
- }
53
- catch {
54
- // Ignore errors reading package.json
55
- }
56
- // Fall back to directory name
57
- return path_1.default.basename(process.cwd());
58
- }
59
- const DEFAULT_GROUP = getProjectName();
60
- exports.DEFAULT_GROUP = DEFAULT_GROUP;
51
+ const di_1 = require("./infrastructure/di");
52
+ const requests_1 = require("./application/mediator/requests");
53
+ const cli_1 = require("./infrastructure/cli");
54
+ const domain_1 = require("./domain");
55
+ const services_2 = require("./infrastructure/services");
56
+ const commands_1 = require("./commands");
57
+ Object.defineProperty(exports, "doctorCommand", { enumerable: true, get: function () { return commands_1.doctorCommand; } });
58
+ Object.defineProperty(exports, "initCommand", { enumerable: true, get: function () { return commands_1.initCommand; } });
59
+ Object.defineProperty(exports, "cleanupPreviousInstall", { enumerable: true, get: function () { return commands_1.cleanupPreviousInstall; } });
60
+ Object.defineProperty(exports, "upCommand", { enumerable: true, get: function () { return commands_1.upCommand; } });
61
+ Object.defineProperty(exports, "downCommand", { enumerable: true, get: function () { return commands_1.downCommand; } });
62
+ Object.defineProperty(exports, "TEMPLATE_ROOT", { enumerable: true, get: function () { return commands_1.TEMPLATE_ROOT; } });
63
+ Object.defineProperty(exports, "DEFAULT_ENDPOINT", { enumerable: true, get: function () { return commands_1.DEFAULT_ENDPOINT; } });
64
+ Object.defineProperty(exports, "DEFAULT_GROUP", { enumerable: true, get: function () { return commands_1.DEFAULT_GROUP; } });
61
65
  // Create CLI logger (console disabled by default to avoid interfering with CLI output)
62
66
  const cliLogger = (0, infrastructure_1.createLogger)({
63
67
  enableConsole: process.env.LOG_CONSOLE === 'true',
64
68
  enableFile: process.env.LOG_FILE !== 'false',
65
69
  });
66
- /**
67
- * Create a symlink with Windows fallback.
68
- * On Windows, tries junction first, then falls back to directory copy.
69
- * Records copy fallbacks for later sync.
70
- */
71
- async function createSymlink(target, link, cwd) {
72
- const isWindows = process.platform === 'win32';
73
- const projectRoot = cwd || process.cwd();
74
- // Skip if link already exists (use lstat to detect symlinks even if target doesn't exist)
75
- try {
76
- await fs_extra_1.default.lstat(link);
77
- return; // Link exists (symlink, junction, or regular file/dir)
78
- }
79
- catch {
80
- // Link doesn't exist, proceed with creation
81
- }
82
- // Calculate relative path from link to target (for Unix symlinks)
83
- const linkDir = path_1.default.dirname(link);
84
- const relativeTarget = path_1.default.relative(linkDir, target);
85
- try {
86
- if (isWindows) {
87
- // Windows junctions require absolute paths
88
- const absoluteTarget = path_1.default.resolve(target);
89
- // Try junction first (doesn't require admin rights)
90
- await fs_extra_1.default.symlink(absoluteTarget, link, 'junction');
91
- }
92
- else {
93
- // Unix: standard symlink with relative path
94
- await fs_extra_1.default.symlink(relativeTarget, link, 'dir');
95
- }
96
- }
97
- catch (err) {
98
- const error = err;
99
- if (isWindows && (error.code === 'EPERM' || error.code === 'ENOENT' || error.code === 'EINVAL')) {
100
- // Junction failed, fall back to copy
101
- console.warn(chalk_1.default.yellow(` Symlink failed, copying directory instead: ${path_1.default.basename(link)}`));
102
- await fs_extra_1.default.copy(target, link);
103
- // Record that we used copy (for future sync)
104
- await recordCopyFallback(projectRoot, link, target);
105
- }
106
- else {
107
- throw err;
108
- }
109
- }
110
- }
111
- /**
112
- * Track directories that were copied instead of linked.
113
- * Used by `lisa sync` to keep copies up to date.
114
- */
115
- async function recordCopyFallback(projectRoot, link, target) {
116
- const fallbackFile = path_1.default.join(projectRoot, '.lisa', '.copy-fallbacks.json');
117
- let existing = { copies: [] };
118
- try {
119
- existing = await fs_extra_1.default.readJson(fallbackFile);
120
- }
121
- catch {
122
- // File doesn't exist yet, use default
123
- }
124
- // Store relative paths
125
- const relLink = path_1.default.relative(projectRoot, link);
126
- const relTarget = path_1.default.relative(projectRoot, target);
127
- // Check if already recorded
128
- if (!existing.copies.some(c => c.link === relLink)) {
129
- existing.copies.push({ link: relLink, target: relTarget, createdAt: new Date().toISOString() });
130
- await fs_extra_1.default.ensureDir(path_1.default.dirname(fallbackFile));
131
- await fs_extra_1.default.writeJson(fallbackFile, existing, { spaces: 2 });
132
- }
133
- }
134
- /**
135
- * Clean up previous Lisa installation before upgrade.
136
- * - Removes scripts/** JS files from skill directories (old format)
137
- * - Backs up existing SKILL.md files to SKILL.md.backup
138
- * - Removes common/ and shared/ directories (now bundled)
139
- *
140
- * @param skillsDir - Path to skills directory
141
- * @param verbose - If true, logs detailed information about each operation
142
- */
143
- async function cleanupPreviousInstall(skillsDir, verbose = false) {
144
- const backedUp = [];
145
- const removed = [];
146
- if (!await fs_extra_1.default.pathExists(skillsDir)) {
147
- if (verbose) {
148
- console.log(chalk_1.default.gray(` [cleanup] Skills directory does not exist: ${skillsDir}`));
149
- }
150
- return { backedUp, removed };
151
- }
152
- if (verbose) {
153
- console.log(chalk_1.default.cyan(` [cleanup] Scanning skills directory: ${skillsDir}`));
154
- }
155
- const skillDirs = await fs_extra_1.default.readdir(skillsDir);
156
- for (const skillName of skillDirs) {
157
- const skillPath = path_1.default.join(skillsDir, skillName);
158
- const stat = await fs_extra_1.default.stat(skillPath);
159
- if (!stat.isDirectory())
160
- continue;
161
- // Remove common/ and shared/ directories (now bundled into CLI)
162
- if (skillName === 'common' || skillName === 'shared') {
163
- if (verbose) {
164
- console.log(chalk_1.default.yellow(` [cleanup] Removing bundled directory: ${skillName}/`));
165
- }
166
- await fs_extra_1.default.remove(skillPath);
167
- removed.push(skillPath);
168
- continue;
169
- }
170
- // Backup existing SKILL.md files
171
- const skillMdPath = path_1.default.join(skillPath, 'SKILL.md');
172
- if (await fs_extra_1.default.pathExists(skillMdPath)) {
173
- const backupPath = path_1.default.join(skillPath, 'SKILL.md.backup');
174
- if (verbose) {
175
- console.log(chalk_1.default.gray(` [cleanup] Backing up: ${skillName}/SKILL.md -> SKILL.md.backup`));
176
- }
177
- await fs_extra_1.default.copy(skillMdPath, backupPath, { overwrite: true });
178
- backedUp.push(skillMdPath);
179
- }
180
- // Remove scripts/ directory with all JS files
181
- const scriptsDir = path_1.default.join(skillPath, 'scripts');
182
- if (await fs_extra_1.default.pathExists(scriptsDir)) {
183
- // Find and remove all .js files in scripts/
184
- const scriptFiles = await fs_extra_1.default.readdir(scriptsDir);
185
- for (const file of scriptFiles) {
186
- if (file.endsWith('.js')) {
187
- const filePath = path_1.default.join(scriptsDir, file);
188
- if (verbose) {
189
- console.log(chalk_1.default.yellow(` [cleanup] Removing old script: ${skillName}/scripts/${file}`));
190
- }
191
- await fs_extra_1.default.remove(filePath);
192
- removed.push(filePath);
193
- }
194
- }
195
- // Remove scripts/ directory if empty
196
- const remainingFiles = await fs_extra_1.default.readdir(scriptsDir);
197
- if (remainingFiles.length === 0) {
198
- if (verbose) {
199
- console.log(chalk_1.default.gray(` [cleanup] Removing empty directory: ${skillName}/scripts/`));
200
- }
201
- await fs_extra_1.default.remove(scriptsDir);
202
- removed.push(scriptsDir);
203
- }
204
- else if (verbose) {
205
- console.log(chalk_1.default.gray(` [cleanup] Keeping ${skillName}/scripts/ (contains ${remainingFiles.length} non-JS files)`));
206
- }
207
- }
208
- }
209
- return { backedUp, removed };
210
- }
211
- // Interactive prompt functions
212
- async function promptDeploymentMode() {
213
- return await (0, prompts_1.select)({
214
- message: 'How would you like to configure storage?',
215
- choices: [
216
- {
217
- name: 'Set up later (scaffold project, configure storage later)',
218
- value: 'skip',
219
- },
220
- {
221
- name: 'Local Docker (runs Neo4j + MCP server locally)',
222
- value: 'local',
223
- },
224
- {
225
- name: 'Zep Cloud (managed storage service)',
226
- value: 'zep-cloud',
227
- },
228
- ],
229
- });
230
- }
231
- async function promptZepCloudConfig() {
232
- const zepApiKey = await (0, prompts_1.password)({
233
- message: 'Zep API Key:',
234
- validate: (val) => val.length > 0 || 'API key is required',
235
- });
236
- const zepProjectId = await (0, prompts_1.input)({
237
- message: 'Zep Project ID:',
238
- validate: (val) => val.length > 0 || 'Project ID is required',
239
- });
240
- return {
241
- zepApiKey,
242
- zepProjectId,
243
- endpoint: ZEP_CLOUD_ENDPOINT,
244
- };
245
- }
246
- async function promptGroupId() {
247
- const projectName = path_1.default.basename(process.cwd());
248
- return await (0, prompts_1.input)({
249
- message: 'Group ID:',
250
- default: projectName,
251
- });
252
- }
253
- async function promptCliSupport() {
254
- const choices = await (0, prompts_1.checkbox)({
255
- message: 'Which CLI tools do you want to support?',
256
- choices: [
257
- {
258
- name: 'Claude Code (Anthropic)',
259
- value: 'claude-code',
260
- checked: true,
261
- },
262
- {
263
- name: 'OpenCode (open source)',
264
- value: 'opencode',
265
- checked: true,
266
- },
267
- ],
268
- });
269
- // Default to both if none selected
270
- if (choices.length === 0) {
271
- return ['claude-code', 'opencode'];
272
- }
273
- return choices;
274
- }
275
- async function initCommand(opts, services) {
276
- const force = Boolean(opts.force);
277
- const verbose = opts.verbose !== false; // Default to true
278
- const cwd = opts.cwd;
279
- let config;
280
- let cliSupport;
281
- // Determine if we need interactive prompts
282
- const hasExplicitMode = opts.mode !== undefined;
283
- const skipPrompts = opts.yes || hasExplicitMode;
284
- if (skipPrompts) {
285
- // Non-interactive mode - use provided options or defaults
286
- const mode = opts.mode || 'local';
287
- config = {
288
- mode,
289
- endpoint: opts.endpoint || (mode === 'zep-cloud' ? ZEP_CLOUD_ENDPOINT : DEFAULT_ENDPOINT),
290
- groupId: opts.group || process.env.GRAPHITI_GROUP_ID || DEFAULT_GROUP,
291
- zepApiKey: opts.zepApiKey,
292
- zepProjectId: opts.zepProjectId,
293
- };
294
- // Default to both CLIs if not specified
295
- cliSupport = opts.cliSupport || ['claude-code', 'opencode'];
296
- }
297
- else {
298
- // Interactive mode - prompt user
299
- const mode = await promptDeploymentMode();
300
- let modeConfig;
301
- if (mode === 'zep-cloud') {
302
- modeConfig = await promptZepCloudConfig();
303
- }
304
- else {
305
- modeConfig = { endpoint: DEFAULT_ENDPOINT };
306
- }
307
- const groupId = await promptGroupId();
308
- // Prompt for CLI support
309
- cliSupport = await promptCliSupport();
310
- config = {
311
- mode,
312
- endpoint: modeConfig.endpoint || DEFAULT_ENDPOINT,
313
- groupId,
314
- ...modeConfig,
315
- };
316
- }
317
- const includeDocker = opts.includeDocker !== false && config.mode !== 'zep-cloud' && config.mode !== 'skip';
318
- const supportClaudeCode = cliSupport.includes('claude-code');
319
- const supportOpenCode = cliSupport.includes('opencode');
320
- const replacements = {
321
- GRAPHITI_ENDPOINT: config.endpoint,
322
- GRAPHITI_GROUP: config.groupId,
323
- GRAPHITI_GROUP_ID: config.groupId,
324
- PROJECT_NAME: config.groupId,
325
- };
326
- const lisaDir = path_1.default.join(cwd, '.lisa');
327
- const skillsDir = path_1.default.join(lisaDir, 'skills');
328
- const rulesDir = path_1.default.join(lisaDir, 'rules');
329
- const claudeDir = path_1.default.join(cwd, '.claude');
330
- const composeDest = path_1.default.join(cwd, 'docker-compose.graphiti.yml');
331
- const copies = [];
332
- // Create .env from template on first install only (preserve user customizations)
333
- const envDest = path_1.default.join(lisaDir, '.env');
334
- if (!await fs_extra_1.default.pathExists(envDest)) {
335
- await fs_extra_1.default.ensureDir(lisaDir);
336
- copies.push(services.templateCopier.copy('.lisa/.env.template', envDest, replacements, false // Never force overwrite - preserves user customizations
337
- ));
338
- }
339
- // Clean up previous installation if upgrading
340
- // This removes old scripts/** JS files and backs up existing SKILL.md files
341
- if (await fs_extra_1.default.pathExists(skillsDir)) {
342
- if (verbose) {
343
- console.log(chalk_1.default.cyan('\nUpgrade cleanup:'));
344
- }
345
- const cleanup = await cleanupPreviousInstall(skillsDir, verbose);
346
- if (cleanup.backedUp.length > 0) {
347
- console.log(chalk_1.default.cyan(` Backed up ${cleanup.backedUp.length} existing SKILL.md file(s)`));
348
- }
349
- if (cleanup.removed.length > 0) {
350
- console.log(chalk_1.default.cyan(` Removed ${cleanup.removed.length} old script file(s)/director(ies)`));
351
- }
352
- if (verbose && cleanup.backedUp.length === 0 && cleanup.removed.length === 0) {
353
- console.log(chalk_1.default.gray(' No cleanup needed (fresh install or already upgraded)'));
354
- }
355
- }
356
- // Skill scaffolding (model-neutral) - copy only SKILL.md files and cache dirs
357
- // Scripts are accessed via subcommands (lisa memory, lisa tasks, etc.)
358
- // SKILL.md files are always overwritten (we back them up above), other files respect force flag
359
- const skillsSrc = path_1.default.join(TEMPLATE_ROOT, '.lisa', 'skills');
360
- await fs_extra_1.default.ensureDir(skillsDir);
361
- copies.push(fs_extra_1.default.copy(skillsSrc, skillsDir, {
362
- overwrite: true, // Always overwrite SKILL.md files (they're backed up above)
363
- filter: (src) => {
364
- const basename = path_1.default.basename(src);
365
- const relativePath = path_1.default.relative(skillsSrc, src);
366
- // Always include the root skills directory
367
- if (relativePath === '')
368
- return true;
369
- // Include skill directories (memory, tasks, jira, git, lisa, prompt, init-review)
370
- // but exclude shared/, common/, scripts/
371
- if (relativePath.includes('shared') || relativePath.includes('common'))
372
- return false;
373
- if (relativePath.includes('scripts'))
374
- return false;
375
- // Include SKILL.md files and cache directories
376
- if (basename === 'SKILL.md' || basename === 'SKILL.local.md')
377
- return true;
378
- if (basename === 'cache' || basename === '.gitkeep')
379
- return true;
380
- // Include directories that might contain the above
381
- return fs_extra_1.default.statSync(src).isDirectory();
382
- }
383
- }));
384
- // Rules scaffolding (shared)
385
- copies.push(services.templateCopier.copy('.lisa/rules/shared/clean-architecture.md', path_1.default.join(rulesDir, 'shared', 'clean-architecture.md'), replacements, force));
386
- copies.push(services.templateCopier.copy('.lisa/rules/shared/code-quality-rules.md', path_1.default.join(rulesDir, 'shared', 'code-quality-rules.md'), replacements, force));
387
- copies.push(services.templateCopier.copy('.lisa/rules/shared/testing-principles.md', path_1.default.join(rulesDir, 'shared', 'testing-principles.md'), replacements, force));
388
- // Rules scaffolding (typescript)
389
- copies.push(services.templateCopier.copy('.lisa/rules/typescript/coding-standards.md', path_1.default.join(rulesDir, 'typescript', 'coding-standards.md'), replacements, force));
390
- copies.push(services.templateCopier.copy('.lisa/rules/typescript/testing.md', path_1.default.join(rulesDir, 'typescript', 'testing.md'), replacements, force));
391
- copies.push(services.templateCopier.copy('.lisa/rules/typescript/typescript-config-guide.md', path_1.default.join(rulesDir, 'typescript', 'typescript-config-guide.md'), replacements, force));
392
- // Claude Code scaffolding (hooks and settings) - only if Claude Code is selected
393
- if (supportClaudeCode) {
394
- copies.push(services.templateCopier.copy('.claude/config.js', path_1.default.join(claudeDir, 'config.js'), replacements, force));
395
- // Copy bundled hooks (these are pre-bundled with all dependencies)
396
- const hooksDir = path_1.default.join(claudeDir, 'hooks');
397
- await fs_extra_1.default.ensureDir(hooksDir);
398
- const bundledHooks = ['session-start.js', 'session-stop.js', 'user-prompt-submit.js'];
399
- for (const hook of bundledHooks) {
400
- const src = path_1.default.join(BUNDLED_HOOKS_ROOT, hook);
401
- const dest = path_1.default.join(hooksDir, hook);
402
- if (await fs_extra_1.default.pathExists(src)) {
403
- copies.push(fs_extra_1.default.copy(src, dest, { overwrite: force }));
404
- }
405
- }
406
- // Create symlinks for .claude/skills and .claude/rules
407
- // If these are real directories (not symlinks), clean them up first
408
- const claudeSkillsLink = path_1.default.join(claudeDir, 'skills');
409
- const claudeRulesLink = path_1.default.join(claudeDir, 'rules');
410
- // Check if .claude/skills exists as a real directory (not symlink)
411
- try {
412
- const skillsStat = await fs_extra_1.default.lstat(claudeSkillsLink);
413
- if (skillsStat.isDirectory() && !skillsStat.isSymbolicLink()) {
414
- // Clean up old scripts in .claude/skills before removing
415
- if (verbose) {
416
- console.log(chalk_1.default.cyan('\nConverting .claude/skills from directory to symlink:'));
417
- }
418
- await cleanupPreviousInstall(claudeSkillsLink, verbose);
419
- await fs_extra_1.default.remove(claudeSkillsLink);
420
- console.log(chalk_1.default.cyan(' Converted .claude/skills to symlink -> .lisa/skills'));
421
- }
422
- }
423
- catch {
424
- // Doesn't exist, will be created as symlink
425
- }
426
- try {
427
- const rulesStat = await fs_extra_1.default.lstat(claudeRulesLink);
428
- if (rulesStat.isDirectory() && !rulesStat.isSymbolicLink()) {
429
- await fs_extra_1.default.remove(claudeRulesLink);
430
- console.log(chalk_1.default.cyan(' Converted .claude/rules to symlink -> .lisa/rules'));
431
- }
432
- }
433
- catch {
434
- // Doesn't exist, will be created as symlink
435
- }
436
- await createSymlink(skillsDir, claudeSkillsLink, cwd);
437
- await createSymlink(rulesDir, claudeRulesLink, cwd);
438
- }
439
- // OpenCode scaffolding - only if OpenCode is selected
440
- if (supportOpenCode) {
441
- const opencodeDir = path_1.default.join(cwd, '.opencode');
442
- const pluginDir = path_1.default.join(opencodeDir, 'plugin');
443
- await fs_extra_1.default.ensureDir(pluginDir);
444
- // Copy bundled OpenCode plugin
445
- const pluginSrc = path_1.default.join(BUNDLED_OPENCODE_ROOT, 'lisa.js');
446
- const pluginDest = path_1.default.join(pluginDir, 'lisa.js');
447
- if (await fs_extra_1.default.pathExists(pluginSrc)) {
448
- copies.push(fs_extra_1.default.copy(pluginSrc, pluginDest, { overwrite: force }));
449
- }
450
- // Create symlink for .opencode/skills
451
- await createSymlink(skillsDir, path_1.default.join(opencodeDir, 'skills'), cwd);
452
- }
453
- if (includeDocker) {
454
- // Choose compose file based on mode
455
- const composeTemplate = '.lisa/docker/docker-compose.graphiti.yml';
456
- copies.push(services.templateCopier.copy(composeTemplate, composeDest, replacements, force));
457
- }
458
- await Promise.all(copies);
459
- // Build scaffolded directories list
460
- const scaffoldedDirs = ['.lisa'];
461
- if (supportClaudeCode)
462
- scaffoldedDirs.push('.claude');
463
- if (supportOpenCode)
464
- scaffoldedDirs.push('.opencode');
465
- if (includeDocker)
466
- scaffoldedDirs.push('Docker assets');
467
- console.log(chalk_1.default.green(`Scaffolded ${scaffoldedDirs.join(', ')} into ${cwd}`));
468
- console.log(`Mode: ${config.mode}`);
469
- console.log(`Endpoint: ${config.endpoint}`);
470
- console.log(`Group ID: ${config.groupId}`);
471
- console.log(`CLI Support: ${cliSupport.join(', ')}`);
472
- // Show skip mode instructions
473
- if (config.mode === 'skip') {
474
- console.log('');
475
- console.log(chalk_1.default.cyan('To configure storage later:'));
476
- console.log(chalk_1.default.cyan(' 1. Read .lisa/docs/STORAGE_SETUP.md'));
477
- console.log(chalk_1.default.cyan(' 2. Edit .lisa/.env with your configuration'));
478
- console.log(chalk_1.default.cyan(' 3. Start a new terminal session'));
479
- console.log(chalk_1.default.cyan(' 4. Run `lisa doctor` to verify connection'));
480
- }
481
- // Isolated mode: create .claude/lib structure for non-npm projects
482
- if (opts.isolated) {
483
- const libDir = path_1.default.join(claudeDir, 'lib');
484
- await fs_extra_1.default.ensureDir(libDir);
485
- // Create minimal package.json in .claude/lib
486
- const libPackageJson = {
487
- name: 'claude-lib',
488
- version: '1.0.0',
489
- private: true,
490
- description: 'Lisa support files for Claude Code',
491
- };
492
- const libPackagePath = path_1.default.join(libDir, 'package.json');
493
- if (!await fs_extra_1.default.pathExists(libPackagePath) || force) {
494
- await fs_extra_1.default.writeJson(libPackagePath, libPackageJson, { spaces: 2 });
495
- console.log(chalk_1.default.green('Created .claude/lib/package.json'));
496
- }
497
- // Add .claude/lib to .gitignore if not already there
498
- const gitignorePath = path_1.default.join(cwd, '.gitignore');
499
- if (await fs_extra_1.default.pathExists(gitignorePath)) {
500
- let gitignore = await fs_extra_1.default.readFile(gitignorePath, 'utf8');
501
- if (!gitignore.includes('.claude/lib/node_modules')) {
502
- gitignore += '\n# Lisa support files\n.claude/lib/node_modules/\n';
503
- await fs_extra_1.default.writeFile(gitignorePath, gitignore);
504
- console.log(chalk_1.default.green('Added .claude/lib/node_modules to .gitignore'));
505
- }
506
- }
507
- console.log('');
508
- console.log(chalk_1.default.cyan('Isolated mode: Lisa installed to .claude/lib/'));
509
- console.log(chalk_1.default.cyan('Your project root stays clean (no package.json or node_modules).'));
510
- }
511
- }
512
- async function loadConfig(cwd) {
513
- // Read from .env file (legacy/runtime config)
514
- const lisaEnv = path_1.default.join(cwd, '.lisa', '.env');
515
- const map = {};
516
- if (await fs_extra_1.default.pathExists(lisaEnv)) {
517
- const raw = await fs_extra_1.default.readFile(lisaEnv, 'utf8');
518
- raw.split(/\r?\n/).forEach((line) => {
519
- if (!line || line.startsWith('#'))
520
- return;
521
- const idx = line.indexOf('=');
522
- if (idx === -1)
523
- return;
524
- const key = line.slice(0, idx).trim();
525
- map[key] = line.slice(idx + 1).trim();
526
- });
527
- }
528
- // If no .env exists, return null
529
- if (Object.keys(map).length === 0) {
530
- return null;
531
- }
532
- return {
533
- endpoint: map.GRAPHITI_ENDPOINT || DEFAULT_ENDPOINT,
534
- group: map.GRAPHITI_GROUP_ID || DEFAULT_GROUP,
535
- mode: map.STORAGE_MODE || 'local',
536
- zepApiKey: map.ZEP_API_KEY,
537
- };
538
- }
539
- async function doctorCommand(opts, services) {
540
- const cwd = opts.cwd;
541
- // Default compose file location is at project root (deployed by init command)
542
- const composeFile = opts.compose || path_1.default.join(cwd, 'docker-compose.graphiti.yml');
543
- const config = (await loadConfig(cwd)) ?? { endpoint: undefined, group: undefined, mode: 'local' };
544
- const endpoint = opts.endpoint || config.endpoint || DEFAULT_ENDPOINT;
545
- const mode = config.mode || 'local';
546
- const results = [];
547
- // Show current mode
548
- results.push(chalk_1.default.cyan(`Mode: ${mode}`));
549
- results.push(chalk_1.default.cyan(`Group: ${config.group || DEFAULT_GROUP}`));
550
- results.push('');
551
- // Mode-specific checks
552
- if (mode === 'zep-cloud') {
553
- // Zep Cloud mode - no local Docker needed
554
- results.push(chalk_1.default.yellow('Zep Cloud mode - no local Docker required'));
555
- results.push('');
556
- // Get API key from config or environment for Zep Cloud authentication
557
- const zepApiKey = config.zepApiKey || process.env.ZEP_API_KEY;
558
- if (!zepApiKey) {
559
- results.push(chalk_1.default.yellow('Warning: ZEP_API_KEY not configured (required for Zep Cloud)'));
560
- }
561
- try {
562
- await services.mcp.ping(endpoint, { apiKey: zepApiKey });
563
- results.push(chalk_1.default.green(`Zep MCP reachable at ${endpoint}`));
564
- }
565
- catch (err) {
566
- const message = err instanceof Error ? err.message : String(err);
567
- results.push(chalk_1.default.red(`Zep MCP check failed at ${endpoint}: ${message}`));
568
- }
569
- }
570
- else if (mode === 'skip') {
571
- // Skip mode - memory/tasks not configured
572
- results.push(chalk_1.default.yellow('Skip mode - memory/tasks not configured'));
573
- results.push(chalk_1.default.yellow('Run "lisa init" again to configure storage backend'));
574
- }
575
- else {
576
- // Local mode - Docker is needed
577
- try {
578
- const stdout = await services.docker.version();
579
- results.push(chalk_1.default.green(`Docker OK: ${stdout}`));
580
- }
581
- catch (err) {
582
- const message = err instanceof Error ? err.message : String(err);
583
- results.push(chalk_1.default.red(`Docker missing or not running: ${message}`));
584
- }
585
- try {
586
- const stdout = await services.docker.composeVersion();
587
- results.push(chalk_1.default.green(`Docker Compose OK: ${stdout}`));
588
- }
589
- catch (err) {
590
- const message = err instanceof Error ? err.message : String(err);
591
- results.push(chalk_1.default.red(`Docker Compose missing: ${message}`));
592
- }
593
- if (await fs_extra_1.default.pathExists(composeFile)) {
594
- results.push(chalk_1.default.green(`Compose file found: ${composeFile}`));
595
- }
596
- else {
597
- results.push(chalk_1.default.red(`Compose file not found: ${composeFile}`));
598
- }
599
- try {
600
- await services.mcp.ping(endpoint);
601
- results.push(chalk_1.default.green(`MCP reachable at ${endpoint}`));
602
- }
603
- catch (err) {
604
- const message = err instanceof Error ? err.message : String(err);
605
- results.push(chalk_1.default.red(`MCP check failed at ${endpoint}: ${message}`));
606
- }
607
- }
608
- console.log(results.join('\n'));
609
- }
610
- async function upCommand(opts, services) {
611
- await services.docker.compose(opts.composeFile, ['up', '-d']);
612
- }
613
- async function downCommand(opts, services) {
614
- await services.docker.compose(opts.composeFile, ['down']);
615
- }
70
+ // Command implementations moved to src/lib/commands/
71
+ // - initCommand, cleanupPreviousInstall -> init.ts
72
+ // - doctorCommand -> doctor.ts
73
+ // - upCommand, downCommand -> docker.ts
616
74
  const program = new commander_1.Command();
617
75
  program
618
76
  .name('lisa')
619
77
  .description('Lisa remembers everything. Memory for Claude Code and AI assistants.')
620
- .version(VERSION);
78
+ .version(commands_1.VERSION);
621
79
  program
622
80
  .command('init')
623
81
  .description('Scaffold .lisa, .claude/.opencode, and Docker assets')
@@ -643,7 +101,7 @@ program
643
101
  opencodeOnly: cmd.opencodeOnly,
644
102
  verbose,
645
103
  });
646
- const services = (0, services_1.createDefaultServices)(TEMPLATE_ROOT);
104
+ const services = (0, services_1.createDefaultServices)(commands_1.TEMPLATE_ROOT);
647
105
  // Determine CLI support from flags
648
106
  let cliSupport;
649
107
  if (cmd.claudeOnly && !cmd.opencodeOnly) {
@@ -656,7 +114,7 @@ program
656
114
  cliSupport = ['claude-code', 'opencode'];
657
115
  }
658
116
  // If neither flag is set, cliSupport remains undefined and prompts will be shown
659
- await initCommand({
117
+ await (0, commands_1.initCommand)({
660
118
  endpoint: cmd.endpoint,
661
119
  group: cmd.group,
662
120
  force: cmd.force,
@@ -689,7 +147,7 @@ program
689
147
  .option('-v, --verbose', 'Show detailed logging (default: true)', true)
690
148
  .option('-q, --quiet', 'Suppress detailed logging')
691
149
  .action(async (cmd) => {
692
- const services = (0, services_1.createDefaultServices)(TEMPLATE_ROOT);
150
+ const services = (0, services_1.createDefaultServices)(commands_1.TEMPLATE_ROOT);
693
151
  const verbose = cmd.verbose && !cmd.quiet;
694
152
  // Determine CLI support from flags
695
153
  let cliSupport;
@@ -702,7 +160,7 @@ program
702
160
  else if (cmd.claudeOnly && cmd.opencodeOnly) {
703
161
  cliSupport = ['claude-code', 'opencode'];
704
162
  }
705
- await initCommand({
163
+ await (0, commands_1.initCommand)({
706
164
  endpoint: cmd.endpoint,
707
165
  group: cmd.group,
708
166
  force: cmd.force,
@@ -723,8 +181,8 @@ program
723
181
  .option('-c, --compose <file>', 'Compose file', 'docker-compose.graphiti.yml')
724
182
  .action(async (cmd) => {
725
183
  const composeFile = path_1.default.resolve(process.cwd(), cmd.compose);
726
- const services = (0, services_1.createDefaultServices)(TEMPLATE_ROOT);
727
- await upCommand({ composeFile }, services);
184
+ const services = (0, services_1.createDefaultServices)(commands_1.TEMPLATE_ROOT);
185
+ await (0, commands_1.upCommand)({ composeFile }, services);
728
186
  });
729
187
  program
730
188
  .command('down')
@@ -732,17 +190,25 @@ program
732
190
  .option('-c, --compose <file>', 'Compose file', 'docker-compose.graphiti.yml')
733
191
  .action(async (cmd) => {
734
192
  const composeFile = path_1.default.resolve(process.cwd(), cmd.compose);
735
- const services = (0, services_1.createDefaultServices)(TEMPLATE_ROOT);
736
- await downCommand({ composeFile }, services);
193
+ const services = (0, services_1.createDefaultServices)(commands_1.TEMPLATE_ROOT);
194
+ await (0, commands_1.downCommand)({ composeFile }, services);
737
195
  });
738
196
  program
739
197
  .command('doctor')
740
- .description('Validate Docker and MCP connectivity')
198
+ .description('Validate Lisa configuration and backend connectivity')
741
199
  .option('-c, --compose <file>', 'Compose file', 'docker-compose.graphiti.yml')
742
200
  .option('-e, --endpoint <url>', 'MCP endpoint override')
201
+ .option('-v, --verbose', 'Show detailed diagnostics')
202
+ .option('--json', 'Output results as JSON')
743
203
  .action(async (cmd) => {
744
- const services = (0, services_1.createDefaultServices)(TEMPLATE_ROOT);
745
- await doctorCommand({ cwd: process.cwd(), compose: cmd.compose, endpoint: cmd.endpoint }, services);
204
+ const services = (0, services_1.createDefaultServices)(commands_1.TEMPLATE_ROOT);
205
+ await (0, commands_1.doctorCommand)({
206
+ cwd: process.cwd(),
207
+ compose: cmd.compose,
208
+ endpoint: cmd.endpoint,
209
+ verbose: cmd.verbose,
210
+ json: cmd.json,
211
+ }, services);
746
212
  });
747
213
  program
748
214
  .command('scan [path]')
@@ -993,6 +459,17 @@ program
993
459
  const scriptPath = path_1.default.join(__dirname, 'skills', 'jira', 'jira.js');
994
460
  await spawnAndWait(scriptPath, args);
995
461
  });
462
+ // Subcommand: lisa github
463
+ program
464
+ .command('github')
465
+ .description('GitHub Issues and Projects operations')
466
+ .allowUnknownOption()
467
+ .action(async (_opts, cmd) => {
468
+ // Pass all arguments after the command to the script
469
+ const args = cmd.args || [];
470
+ const scriptPath = path_1.default.join(__dirname, 'skills', 'github', 'github.js');
471
+ await spawnAndWait(scriptPath, args);
472
+ });
996
473
  // Subcommand: lisa prompt
997
474
  program
998
475
  .command('prompt')
@@ -1033,6 +510,274 @@ program
1033
510
  const scriptPath = path_1.default.join(__dirname, 'skills', 'lisa', 'compile-skills.js');
1034
511
  await spawnAndWait(scriptPath, args);
1035
512
  });
513
+ // Subcommand: lisa issue
514
+ // Wraps gh CLI with auto-labeling capabilities
515
+ const issueCmd = program
516
+ .command('issue')
517
+ .description('GitHub issue management with auto-labeling');
518
+ issueCmd
519
+ .command('create')
520
+ .description('Create a GitHub issue with automatic label inference')
521
+ .requiredOption('-t, --title <title>', 'Issue title')
522
+ .option('-b, --body <body>', 'Issue body')
523
+ .option('-l, --label <labels...>', 'Explicit labels (skips auto-labeling for type)')
524
+ .option('--no-auto-label', 'Disable automatic label inference')
525
+ .option('-y, --yes', 'Skip confirmation, apply inferred labels automatically')
526
+ .option('--dry-run', 'Show what would be created without creating')
527
+ .action(async (opts) => {
528
+ const title = opts.title;
529
+ const body = opts.body || '';
530
+ const explicitLabels = opts.label || [];
531
+ const autoLabel = opts.autoLabel !== false;
532
+ const skipConfirm = opts.yes || false;
533
+ const dryRun = opts.dryRun || false;
534
+ // Collect all labels
535
+ const allLabels = [...explicitLabels];
536
+ let inferredLabels = [];
537
+ let reasons = {};
538
+ // Auto-label if enabled and no explicit type labels provided
539
+ if (autoLabel) {
540
+ const service = (0, services_2.createLabelInferenceService)();
541
+ const result = service.inferLabels(title, body);
542
+ inferredLabels = result.labels;
543
+ reasons = result.reasons;
544
+ // Filter out labels that conflict with explicit labels
545
+ const explicitTypes = explicitLabels.filter(l => ['bug', 'enhancement', 'documentation', 'refactor', 'testing'].includes(l));
546
+ if (explicitTypes.length > 0) {
547
+ // User specified a type label, don't override it
548
+ inferredLabels = inferredLabels.filter(l => !['bug', 'enhancement', 'documentation', 'refactor', 'testing'].includes(l));
549
+ }
550
+ // Add non-duplicate inferred labels
551
+ for (const label of inferredLabels) {
552
+ if (!allLabels.includes(label)) {
553
+ allLabels.push(label);
554
+ }
555
+ }
556
+ }
557
+ // Show what will be created
558
+ console.log(chalk_1.default.bold('Issue to create:'));
559
+ console.log(` Title: ${chalk_1.default.cyan(title)}`);
560
+ if (body) {
561
+ const bodyPreview = body.length > 100 ? body.slice(0, 100) + '...' : body;
562
+ console.log(` Body: ${chalk_1.default.dim(bodyPreview)}`);
563
+ }
564
+ console.log('');
565
+ if (explicitLabels.length > 0) {
566
+ console.log(chalk_1.default.bold('Explicit labels:'));
567
+ for (const label of explicitLabels) {
568
+ console.log(` ${chalk_1.default.green('+')} ${label}`);
569
+ }
570
+ console.log('');
571
+ }
572
+ if (inferredLabels.length > 0) {
573
+ console.log(chalk_1.default.bold('Inferred labels:'));
574
+ for (const label of inferredLabels) {
575
+ const reason = reasons[label] || 'Pattern match';
576
+ console.log(` ${chalk_1.default.yellow('~')} ${label} ${chalk_1.default.dim(`(${reason})`)}`);
577
+ }
578
+ console.log('');
579
+ }
580
+ if (allLabels.length > 0) {
581
+ console.log(chalk_1.default.bold('Final labels:'));
582
+ console.log(` ${allLabels.join(', ')}`);
583
+ console.log('');
584
+ }
585
+ if (dryRun) {
586
+ console.log(chalk_1.default.yellow('Dry run - no issue created'));
587
+ return;
588
+ }
589
+ // Confirm if not skipping
590
+ if (!skipConfirm && inferredLabels.length > 0) {
591
+ const { confirm } = await Promise.resolve().then(() => __importStar(require('@inquirer/prompts')));
592
+ const confirmed = await confirm({
593
+ message: 'Create issue with these labels?',
594
+ default: true,
595
+ });
596
+ if (!confirmed) {
597
+ console.log(chalk_1.default.yellow('Cancelled'));
598
+ return;
599
+ }
600
+ }
601
+ // Build gh command
602
+ const ghArgs = ['issue', 'create', '--title', title];
603
+ if (body) {
604
+ ghArgs.push('--body', body);
605
+ }
606
+ for (const label of allLabels) {
607
+ ghArgs.push('--label', label);
608
+ }
609
+ // Execute gh command using spawnSync to avoid shell injection
610
+ try {
611
+ const { spawnSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
612
+ const result = spawnSync('gh', ghArgs, {
613
+ encoding: 'utf8',
614
+ stdio: ['inherit', 'pipe', 'inherit'],
615
+ shell: false,
616
+ });
617
+ if (result.error) {
618
+ throw result.error;
619
+ }
620
+ if (result.status !== 0) {
621
+ throw new Error(`gh exited with code ${result.status}`);
622
+ }
623
+ console.log(chalk_1.default.green('Issue created:'), (result.stdout || '').trim());
624
+ }
625
+ catch (error) {
626
+ const message = error instanceof Error ? error.message : String(error);
627
+ console.error(chalk_1.default.red('Failed to create issue:'), message);
628
+ process.exit(1);
629
+ }
630
+ });
631
+ issueCmd
632
+ .command('labels')
633
+ .description('Infer labels for content without creating an issue')
634
+ .requiredOption('-t, --title <title>', 'Issue title to analyze')
635
+ .option('-b, --body <body>', 'Issue body to analyze')
636
+ .option('--json', 'Output as JSON')
637
+ .action((opts) => {
638
+ const service = (0, services_2.createLabelInferenceService)();
639
+ const result = service.inferLabels(opts.title, opts.body || '');
640
+ if (opts.json) {
641
+ console.log(JSON.stringify(result, null, 2));
642
+ }
643
+ else {
644
+ if (result.labels.length === 0) {
645
+ console.log(chalk_1.default.yellow('No labels inferred'));
646
+ }
647
+ else {
648
+ console.log(chalk_1.default.bold('Inferred labels:'));
649
+ for (const label of result.labels) {
650
+ const reason = result.reasons[label] || 'Pattern match';
651
+ console.log(` ${chalk_1.default.green('+')} ${label}`);
652
+ console.log(` ${chalk_1.default.dim(reason)}`);
653
+ }
654
+ console.log('');
655
+ console.log(`Confidence: ${(result.confidence * 100).toFixed(0)}%`);
656
+ }
657
+ }
658
+ });
659
+ // Subcommand: lisa hook
660
+ // These commands are called by Claude Code via settings.json hooks
661
+ const hookCmd = program
662
+ .command('hook')
663
+ .description('Hook commands for Claude Code integration');
664
+ hookCmd
665
+ .command('session-start')
666
+ .description('Handle session start event (called by Claude Code)')
667
+ .action(async () => {
668
+ let dispose;
669
+ try {
670
+ // Read input from Claude Code
671
+ const input = await (0, cli_1.readJsonFromStdin)();
672
+ const trigger = (0, cli_1.parseTrigger)(input.source, input.session_type, input.trigger);
673
+ // Bootstrap container and resolve mediator
674
+ const bootstrap = await (0, di_1.bootstrapContainer)({
675
+ projectRoot: input.cwd || process.cwd(),
676
+ disableLogging: true,
677
+ });
678
+ dispose = bootstrap.dispose;
679
+ const mediator = await bootstrap.container.resolve(di_1.TOKENS.Mediator);
680
+ // Create and send request
681
+ const request = new requests_1.SessionStartRequest(trigger, (0, domain_1.toISOTimestamp)(), input.session_id);
682
+ const result = await mediator.send(request);
683
+ // Output context to stdout (goes to Claude)
684
+ const output = {
685
+ hookSpecificOutput: {
686
+ hookEventName: 'SessionStart',
687
+ additionalContext: result.contextContent,
688
+ },
689
+ };
690
+ await (0, cli_1.writeJsonToStdout)(output);
691
+ // Status message to stderr (shown to user)
692
+ await (0, cli_1.writeStatus)(result.message);
693
+ }
694
+ catch (error) {
695
+ // On error, still output something to not block session
696
+ const errorMessage = error instanceof Error ? error.message : String(error);
697
+ const output = {
698
+ hookSpecificOutput: {
699
+ hookEventName: 'SessionStart',
700
+ additionalContext: `Memory load skipped: ${errorMessage}`,
701
+ },
702
+ };
703
+ await (0, cli_1.writeJsonToStdout)(output);
704
+ await (0, cli_1.writeStatus)(`Memory load failed: ${errorMessage}`);
705
+ }
706
+ finally {
707
+ if (dispose)
708
+ await dispose();
709
+ }
710
+ });
711
+ hookCmd
712
+ .command('session-stop')
713
+ .description('Handle session stop event (called by Claude Code)')
714
+ .action(async () => {
715
+ let dispose;
716
+ try {
717
+ // Read input from Claude Code
718
+ const input = await (0, cli_1.readJsonFromStdin)();
719
+ // Bootstrap container and resolve mediator
720
+ const bootstrap = await (0, di_1.bootstrapContainer)({
721
+ projectRoot: input.cwd || process.cwd(),
722
+ disableLogging: true,
723
+ });
724
+ dispose = bootstrap.dispose;
725
+ const mediator = await bootstrap.container.resolve(di_1.TOKENS.Mediator);
726
+ // Create and send request
727
+ const request = new requests_1.SessionStopRequest('idle', (0, domain_1.toISOTimestamp)(), input.session_id, input.transcript_path);
728
+ const result = await mediator.send(request);
729
+ // Status message to stderr
730
+ await (0, cli_1.writeStatus)(result.message);
731
+ }
732
+ catch (error) {
733
+ // Silent failure - don't block user
734
+ const errorMessage = error instanceof Error ? error.message : String(error);
735
+ await (0, cli_1.writeStatus)(`Session capture failed: ${errorMessage}`);
736
+ }
737
+ finally {
738
+ if (dispose)
739
+ await dispose();
740
+ }
741
+ });
742
+ hookCmd
743
+ .command('user-prompt-submit')
744
+ .description('Handle user prompt submit event (called by Claude Code)')
745
+ .action(async () => {
746
+ let dispose;
747
+ try {
748
+ // Read input from Claude Code
749
+ const input = await (0, cli_1.readJsonFromStdin)();
750
+ const content = input.prompt || input.content || '';
751
+ const permissionMode = (input.permission_mode || input.permissionMode || 'default');
752
+ if (!content) {
753
+ // No content to process
754
+ return;
755
+ }
756
+ // Bootstrap container and resolve mediator
757
+ const bootstrap = await (0, di_1.bootstrapContainer)({
758
+ projectRoot: process.cwd(),
759
+ disableLogging: true,
760
+ });
761
+ dispose = bootstrap.dispose;
762
+ const mediator = await bootstrap.container.resolve(di_1.TOKENS.Mediator);
763
+ // Create and send request
764
+ const request = new requests_1.PromptSubmitRequest(content, (0, domain_1.toISOTimestamp)(), input.session_id, permissionMode);
765
+ const result = await mediator.send(request);
766
+ // Output recursion results if in plan mode
767
+ if (result.recursion?.hasContext) {
768
+ console.log('\nšŸ” Related Context from Memory:\n');
769
+ console.log(result.recursion.summary);
770
+ console.log('');
771
+ }
772
+ }
773
+ catch {
774
+ // Silent failure - don't block user
775
+ }
776
+ finally {
777
+ if (dispose)
778
+ await dispose();
779
+ }
780
+ });
1036
781
  if (require.main === module) {
1037
782
  program.parseAsync(process.argv).catch((err) => {
1038
783
  console.error(chalk_1.default.red(err.message));