crewx 0.8.1 → 0.8.2-rc.2

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 (125) hide show
  1. package/README.md +268 -268
  2. package/bin/cli-commands.js +34 -0
  3. package/bin/crewx-lib.js +213 -108
  4. package/bin/crewx-ui.js +83 -83
  5. package/bin/crewx.js +219 -147
  6. package/bin/launcher-flags.js +29 -0
  7. package/bin/package.json +1 -1
  8. package/dist/assets/MarketPage-DptjaFpT.js +36 -0
  9. package/dist/assets/{PromptTab-DVKc7hJY.js → PromptTab-DZha2_v1.js} +1 -1
  10. package/dist/assets/{_baseUniq-wjlVo2E6.js → _baseUniq-jd6NubI3.js} +1 -1
  11. package/dist/assets/{arc-BfPgRtzW.js → arc-C2te3-8P.js} +1 -1
  12. package/dist/assets/{architectureDiagram-Q4EWVU46-ewcueFAG.js → architectureDiagram-Q4EWVU46-CbIQua02.js} +1 -1
  13. package/dist/assets/{blockDiagram-DXYQGD6D-TxlbbvKn.js → blockDiagram-DXYQGD6D-Cg7qkpSM.js} +1 -1
  14. package/dist/assets/{c4Diagram-AHTNJAMY-C1lT_bl_.js → c4Diagram-AHTNJAMY-BkffDY1F.js} +1 -1
  15. package/dist/assets/channel-beae0DeI.js +1 -0
  16. package/dist/assets/chatgpt-logo-dark.svg +15 -15
  17. package/dist/assets/chatgpt-logo.svg +15 -15
  18. package/dist/assets/{chunk-4BX2VUAB-C41j2mCL.js → chunk-4BX2VUAB-BxHe9wPE.js} +1 -1
  19. package/dist/assets/{chunk-4TB4RGXK-HNNsUbz0.js → chunk-4TB4RGXK--f1tN90O.js} +1 -1
  20. package/dist/assets/{chunk-55IACEB6-qtCgO0r2.js → chunk-55IACEB6-B5QXfPXQ.js} +1 -1
  21. package/dist/assets/{chunk-EDXVE4YY-BSnDYtsd.js → chunk-EDXVE4YY-DqKhblOg.js} +1 -1
  22. package/dist/assets/{chunk-FMBD7UC4-DyHRLQqX.js → chunk-FMBD7UC4-DZ1w_G02.js} +1 -1
  23. package/dist/assets/{chunk-OYMX7WX6-CCjfi6WS.js → chunk-OYMX7WX6-BqAgQpv8.js} +1 -1
  24. package/dist/assets/{chunk-QZHKN3VN-COLty8kd.js → chunk-QZHKN3VN-DPqnGqVi.js} +1 -1
  25. package/dist/assets/{chunk-YZCP3GAM-CHUUnGeN.js → chunk-YZCP3GAM-x-ZYSQLd.js} +1 -1
  26. package/dist/assets/classDiagram-6PBFFD2Q-BquWrs1y.js +1 -0
  27. package/dist/assets/classDiagram-v2-HSJHXN6E-BquWrs1y.js +1 -0
  28. package/dist/assets/clone-C9wSPtDN.js +1 -0
  29. package/dist/assets/{cose-bilkent-S5V4N54A-CSip-V2g.js → cose-bilkent-S5V4N54A-4VCNRP-E.js} +1 -1
  30. package/dist/assets/{dagre-KV5264BT-DkdpnWhv.js → dagre-KV5264BT-DucVi1QS.js} +1 -1
  31. package/dist/assets/{diagram-5BDNPKRD-PH4qc6PV.js → diagram-5BDNPKRD-ChdRA8bE.js} +1 -1
  32. package/dist/assets/{diagram-G4DWMVQ6-Cg5xZcjx.js → diagram-G4DWMVQ6-B1-97yHr.js} +1 -1
  33. package/dist/assets/{diagram-MMDJMWI5-soKmeTCW.js → diagram-MMDJMWI5-CQs3cO7G.js} +1 -1
  34. package/dist/assets/{diagram-TYMM5635-Daq5Mihu.js → diagram-TYMM5635-CuNCxDfO.js} +1 -1
  35. package/dist/assets/{erDiagram-SMLLAGMA-kr2OtY0Y.js → erDiagram-SMLLAGMA-DdR8v8g-.js} +1 -1
  36. package/dist/assets/{flowDiagram-DWJPFMVM-DQZCb8gm.js → flowDiagram-DWJPFMVM-Dt02upId.js} +1 -1
  37. package/dist/assets/{ganttDiagram-T4ZO3ILL-BHkn485T.js → ganttDiagram-T4ZO3ILL-cG_k9VOa.js} +1 -1
  38. package/dist/assets/{gitGraphDiagram-UUTBAWPF-FaCyYFmC.js → gitGraphDiagram-UUTBAWPF-Dz1DjhKq.js} +1 -1
  39. package/dist/assets/{graph-BVJlrP6V.js → graph-CF2NtM33.js} +1 -1
  40. package/dist/assets/{infoDiagram-42DDH7IO-DJOWkKdM.js → infoDiagram-42DDH7IO-tQWKrYM6.js} +1 -1
  41. package/dist/assets/{ishikawaDiagram-UXIWVN3A-VfpvNaIf.js → ishikawaDiagram-UXIWVN3A-CLuUMkF0.js} +1 -1
  42. package/dist/assets/{journeyDiagram-VCZTEJTY-CPzsak-v.js → journeyDiagram-VCZTEJTY-a6JenLCk.js} +1 -1
  43. package/dist/assets/{kanban-definition-6JOO6SKY-DFqLDBU0.js → kanban-definition-6JOO6SKY-rqOxTzYb.js} +1 -1
  44. package/dist/assets/{layout-CCSbNPHm.js → layout-Dvic1Hpy.js} +1 -1
  45. package/dist/assets/{linear-C4T7PCKE.js → linear-CfMV1S6a.js} +1 -1
  46. package/dist/assets/main-05K4ggqd.css +10 -0
  47. package/dist/assets/main-CCM1gtr8.js +1165 -0
  48. package/dist/assets/{min-CGQNEYGh.js → min-GpF3DZux.js} +1 -1
  49. package/dist/assets/{mindmap-definition-QFDTVHPH-AuU1EqwS.js → mindmap-definition-QFDTVHPH-Cg80z0Jx.js} +1 -1
  50. package/dist/assets/{pieDiagram-DEJITSTG-CopkCZwp.js → pieDiagram-DEJITSTG-BrtK7lAq.js} +1 -1
  51. package/dist/assets/{quadrantDiagram-34T5L4WZ-lMKrSv_t.js → quadrantDiagram-34T5L4WZ-BL2txAAS.js} +1 -1
  52. package/dist/assets/{requirementDiagram-MS252O5E-dWUpHOFb.js → requirementDiagram-MS252O5E-Co3wpBnu.js} +1 -1
  53. package/dist/assets/{sankeyDiagram-XADWPNL6-C8UQx9Bb.js → sankeyDiagram-XADWPNL6-B4KJXdQ4.js} +1 -1
  54. package/dist/assets/{sequenceDiagram-FGHM5R23-CUVNIItJ.js → sequenceDiagram-FGHM5R23-xs5OuzvV.js} +1 -1
  55. package/dist/assets/{stateDiagram-FHFEXIEX-Ct0GamGl.js → stateDiagram-FHFEXIEX-bbEP20JD.js} +1 -1
  56. package/dist/assets/stateDiagram-v2-QKLJ7IA2-XYh9U1A7.js +1 -0
  57. package/dist/assets/{timeline-definition-GMOUNBTQ-ul8Po7f7.js → timeline-definition-GMOUNBTQ-CTc2wVwC.js} +1 -1
  58. package/dist/assets/{vennDiagram-DHZGUBPP-B4AOWQnP.js → vennDiagram-DHZGUBPP-oJpXott7.js} +1 -1
  59. package/dist/assets/{wardley-RL74JXVD-Dr7Wp3AJ.js → wardley-RL74JXVD-aTmOXkKh.js} +1 -1
  60. package/dist/assets/{wardleyDiagram-NUSXRM2D-Ck70faXX.js → wardleyDiagram-NUSXRM2D-C83SOkig.js} +1 -1
  61. package/dist/assets/{xychartDiagram-5P7HB3ND-Bsy5-cNt.js → xychartDiagram-5P7HB3ND-BScws0tF.js} +1 -1
  62. package/dist/index.html +13 -13
  63. package/dist-electron/main.js +153 -116
  64. package/dist-electron/overlay.js +102 -65
  65. package/dist-electron/package.json +1 -0
  66. package/dist-electron/preload.js +8 -8
  67. package/dist-server/bootstrap/crewx-server.js +19 -10
  68. package/dist-server/domain/agent/agent.service.js +12 -0
  69. package/dist-server/domain/agent/dto/update-agent.dto.js +20 -1
  70. package/dist-server/domain/mcp/crewx-tool.factory.js +44 -113
  71. package/dist-server/domain/mcp/mcp.module.js +2 -0
  72. package/dist-server/domain/mcp/mcp.service.js +37 -12
  73. package/dist-server/domain/message/message.service.js +21 -13
  74. package/dist-server/domain/skill/skill.service.js +63 -43
  75. package/dist-server/domain/task/task.module.js +2 -0
  76. package/dist-server/domain/task/task.service.js +17 -10
  77. package/dist-server/domain/thread/dto/update-thread.dto.js +23 -0
  78. package/dist-server/domain/thread/thread.controller.js +16 -0
  79. package/dist-server/domain/thread/thread.service.js +9 -0
  80. package/dist-server/main.js +1 -1
  81. package/dist-server/modules/crewx.module.js +16 -1
  82. package/dist-server/repository/box.repository.js +20 -20
  83. package/dist-server/repository/project.repository.js +13 -13
  84. package/dist-server/repository/request-log.repository.js +10 -10
  85. package/dist-server/repository/task.repository.js +72 -72
  86. package/dist-server/repository/thread.repository.js +78 -58
  87. package/package.json +6 -6
  88. package/packages/cli/dist/bootstrap/crewx-cli.js +12 -0
  89. package/packages/cli/dist/commands/agent.js +23 -23
  90. package/packages/cli/dist/commands/init.js +19 -19
  91. package/packages/cli/dist/commands/parse-common-flags.d.ts +19 -3
  92. package/packages/cli/dist/commands/parse-common-flags.js +46 -6
  93. package/packages/cli/dist/commands/registry.d.ts +13 -0
  94. package/packages/cli/dist/commands/registry.js +29 -0
  95. package/packages/cli/dist/commands/task-db.js +7 -7
  96. package/packages/cli/dist/examples/deny-secrets-plugin.d.ts +22 -0
  97. package/packages/cli/dist/examples/deny-secrets-plugin.js +40 -0
  98. package/packages/cli/dist/main.js +134 -68
  99. package/packages/cli/dist/plugins/examples/echo-hook.d.ts +24 -0
  100. package/packages/cli/dist/plugins/examples/echo-hook.js +60 -0
  101. package/packages/cli/dist/plugins/examples/verify-echo-hook.d.ts +8 -0
  102. package/packages/cli/dist/plugins/examples/verify-echo-hook.js +47 -0
  103. package/packages/cli/dist/plugins/sqlite-tracing.d.ts +11 -0
  104. package/packages/cli/dist/plugins/sqlite-tracing.js +19 -0
  105. package/packages/cli/dist/schema/tasks.d.ts +7 -0
  106. package/packages/cli/dist/schema/tasks.js +48 -0
  107. package/packages/cli/package.json +52 -52
  108. package/scripts/analyze-task-logs.mjs +569 -0
  109. package/scripts/build-manual.mjs +266 -266
  110. package/scripts/emit-dist-server-package-json.mjs +7 -7
  111. package/scripts/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  112. package/scripts/postinstall.mjs +44 -44
  113. package/scripts/smoke-tarball.mjs +285 -285
  114. package/scripts/snapshot-msg-list.sh +52 -52
  115. package/server.js +167 -164
  116. package/dist/assets/MarketPage-Dwsg6K-B.js +0 -31
  117. package/dist/assets/channel-BP4PNMmz.js +0 -1
  118. package/dist/assets/classDiagram-6PBFFD2Q-Upr3UAcM.js +0 -1
  119. package/dist/assets/classDiagram-v2-HSJHXN6E-Upr3UAcM.js +0 -1
  120. package/dist/assets/clone-B8BP7ReZ.js +0 -1
  121. package/dist/assets/main-CELBpK6r.js +0 -1166
  122. package/dist/assets/main-CmP-VosD.css +0 -10
  123. package/dist/assets/stateDiagram-v2-QKLJ7IA2-CFBLQDEx.js +0 -1
  124. package/dist-server/domain/task/dto/project-usage.dto.js +0 -38
  125. package/dist-server/domain/thread/dto/send-message.dto.js +0 -10
@@ -8,6 +8,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
11
14
  var TaskService_1;
12
15
  Object.defineProperty(exports, "__esModule", { value: true });
13
16
  exports.TaskService = void 0;
@@ -18,8 +21,8 @@ const fs_1 = require("fs");
18
21
  const child_process_1 = require("child_process");
19
22
  const js_yaml_1 = require("js-yaml");
20
23
  const task_constants_js_1 = require("./task.constants.js");
21
- const crewx_tool_factory_js_1 = require("../mcp/crewx-tool.factory.js");
22
24
  const sdk_1 = require("@crewx/sdk");
25
+ const sdk_2 = require("@crewx/sdk");
23
26
  const task_repository_js_1 = require("../../repository/task.repository.js");
24
27
  const workspace_context_store_js_1 = require("../../common/workspace-context.store.js");
25
28
  const MAX_LOG_ENTRY_FIELD_LEN = 128 * 1024; // 128KB worth of UTF-16 code units
@@ -28,9 +31,11 @@ const MAX_LOG_ENTRY_FIELD_LEN = 128 * 1024; // 128KB worth of UTF-16 code units
28
31
  // TSK005 uses crewx.db for execution status and logs.
29
32
  let TaskService = TaskService_1 = class TaskService {
30
33
  taskRepo;
34
+ crewx;
31
35
  logger = new common_1.Logger(TaskService_1.name);
32
- constructor(taskRepo) {
36
+ constructor(taskRepo, crewx) {
33
37
  this.taskRepo = taskRepo;
38
+ this.crewx = crewx;
34
39
  }
35
40
  // TSK.ALL: All tasks from crewx.db with filtering, search, and pagination
36
41
  getAllTasks(params, workspaceId) {
@@ -72,14 +77,14 @@ let TaskService = TaskService_1 = class TaskService {
72
77
  if (!agent || typeof agent !== 'string' || !agent.trim()) {
73
78
  throw new common_1.BadRequestException('agent is required');
74
79
  }
75
- // Fire-and-forget: start CLI execution in background so HTTP response is immediate
76
- (0, crewx_tool_factory_js_1.getCrewXTool)()
77
- .then((tool) => tool.executeAgent({
78
- agentId: agent,
79
- task: message,
80
+ // Fire-and-forget: delegate to shared Crewx singleton (ConversationPlugin
81
+ // handles threads row upsert). Never close the instance — CrewxModule owns it.
82
+ this.crewx
83
+ .execute(`@${agent}`, message, {
84
+ threadId,
80
85
  platform: 'cli',
81
86
  metadata: { thread: threadId },
82
- }))
87
+ })
83
88
  .catch((err) => {
84
89
  this.logger.error(`Background executeAgent failed [thread=${threadId}]: ${err.message}`, err.stack);
85
90
  });
@@ -391,7 +396,7 @@ let TaskService = TaskService_1 = class TaskService {
391
396
  const entries = [];
392
397
  for (const log of rawLogs) {
393
398
  if (log.level === 'stdout') {
394
- entries.push(...(0, sdk_1.parseStdoutEvent)(log.timestamp, log.message));
399
+ entries.push(...(0, sdk_2.parseStdoutEvent)(log.timestamp, log.message));
395
400
  }
396
401
  else if (log.level === 'info') {
397
402
  entries.push({
@@ -650,5 +655,7 @@ let TaskService = TaskService_1 = class TaskService {
650
655
  exports.TaskService = TaskService;
651
656
  exports.TaskService = TaskService = TaskService_1 = __decorate([
652
657
  (0, common_1.Injectable)(),
653
- __metadata("design:paramtypes", [task_repository_js_1.TaskRepository])
658
+ __param(1, (0, common_1.Inject)(sdk_1.Crewx)),
659
+ __metadata("design:paramtypes", [task_repository_js_1.TaskRepository,
660
+ sdk_1.Crewx])
654
661
  ], TaskService);
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.UpdateThreadDto = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ class UpdateThreadDto {
15
+ title;
16
+ }
17
+ exports.UpdateThreadDto = UpdateThreadDto;
18
+ __decorate([
19
+ (0, class_validator_1.IsString)(),
20
+ (0, class_validator_1.MinLength)(1),
21
+ (0, class_validator_1.MaxLength)(120),
22
+ __metadata("design:type", String)
23
+ ], UpdateThreadDto.prototype, "title", void 0);
@@ -19,6 +19,7 @@ const thread_service_js_1 = require("./thread.service.js");
19
19
  const box_service_js_1 = require("../box/box.service.js");
20
20
  const list_threads_dto_js_1 = require("./dto/list-threads.dto.js");
21
21
  const build_context_dto_js_1 = require("./dto/build-context.dto.js");
22
+ const update_thread_dto_js_1 = require("./dto/update-thread.dto.js");
22
23
  const workspace_decorator_js_1 = require("../../common/decorators/workspace.decorator.js");
23
24
  let ThreadController = class ThreadController {
24
25
  threadService;
@@ -32,6 +33,11 @@ let ThreadController = class ThreadController {
32
33
  const data = this.threadService.listThreads(query, ws.id);
33
34
  return { success: true, data };
34
35
  }
36
+ // THD.UPDATE: Update thread title
37
+ updateThread(threadId, dto, ws) {
38
+ const data = this.threadService.updateThread(threadId, ws.id, { title: dto.title });
39
+ return { success: true, data };
40
+ }
35
41
  // THD.GET: Get thread meta info (messages moved to MSG.LIST)
36
42
  getThread(threadId, ws) {
37
43
  const data = this.threadService.getThread(threadId, ws.id);
@@ -68,6 +74,16 @@ __decorate([
68
74
  __metadata("design:paramtypes", [list_threads_dto_js_1.ListThreadsDto, Object]),
69
75
  __metadata("design:returntype", void 0)
70
76
  ], ThreadController.prototype, "listThreads", null);
77
+ __decorate([
78
+ (0, swagger_1.ApiOperation)({ operationId: 'THD.UPDATE', summary: 'Update thread title' }),
79
+ (0, common_1.Patch)(':threadId'),
80
+ __param(0, (0, common_1.Param)('threadId')),
81
+ __param(1, (0, common_1.Body)()),
82
+ __param(2, (0, workspace_decorator_js_1.Workspace)()),
83
+ __metadata("design:type", Function),
84
+ __metadata("design:paramtypes", [String, update_thread_dto_js_1.UpdateThreadDto, Object]),
85
+ __metadata("design:returntype", void 0)
86
+ ], ThreadController.prototype, "updateThread", null);
71
87
  __decorate([
72
88
  (0, swagger_1.ApiOperation)({ operationId: 'THD.GET', summary: 'Get thread meta info' }),
73
89
  (0, common_1.Get)(':threadId'),
@@ -101,6 +101,15 @@ let ThreadService = class ThreadService {
101
101
  },
102
102
  };
103
103
  }
104
+ // THD.UPDATE: Update thread title (locks against auto-overwrite)
105
+ updateThread(threadId, workspaceId, patch) {
106
+ this.validateId(threadId);
107
+ const updated = this.threadRepo.updateThreadTitle(threadId, patch.title, workspaceId);
108
+ if (!updated) {
109
+ throw new common_1.NotFoundException(`Thread not found: ${threadId}`);
110
+ }
111
+ return { threadId, title: patch.title };
112
+ }
104
113
  // TSK.LIST: List tasks for a thread (polling)
105
114
  getThreadTasks(threadId, workspaceId) {
106
115
  this.validateId(threadId);
@@ -92,7 +92,7 @@ async function bootstrap() {
92
92
  // Fallback to index.html for SPA routing
93
93
  app.use((req, res, next) => {
94
94
  if (!req.path.startsWith('/api/') && !req.path.startsWith('/mcp')) {
95
- res.sendFile((0, path_1.join)(staticPath, 'index.html'));
95
+ res.sendFile('index.html', { root: staticPath });
96
96
  }
97
97
  else {
98
98
  next();
@@ -5,6 +5,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.CrewxModule = void 0;
10
13
  const common_1 = require("@nestjs/common");
@@ -16,6 +19,10 @@ const crewx_server_js_1 = require("../bootstrap/crewx-server.js");
16
19
  * CrewxModule — NestJS DI Provider for the Crewx facade.
17
20
  *
18
21
  * Loads crewx.yaml from the server workspace at boot time via async factory.
22
+ * The resulting instance is a singleton shared across web / MCP / any other
23
+ * path that needs Crewx. Do NOT call crewx.close() from call sites — the
24
+ * module owns the instance lifecycle via onApplicationShutdown.
25
+ *
19
26
  * Resolution order:
20
27
  * 1. CREWX_CONFIG env var (full file path)
21
28
  * 2. CREWX_WORKSPACE env var + crewx.yaml
@@ -23,6 +30,13 @@ const crewx_server_js_1 = require("../bootstrap/crewx-server.js");
23
30
  * 4. process.cwd() + crewx.yml
24
31
  */
25
32
  let CrewxModule = class CrewxModule {
33
+ crewx;
34
+ constructor(crewx) {
35
+ this.crewx = crewx;
36
+ }
37
+ async onApplicationShutdown() {
38
+ await this.crewx.close().catch(() => { });
39
+ }
26
40
  };
27
41
  exports.CrewxModule = CrewxModule;
28
42
  exports.CrewxModule = CrewxModule = __decorate([
@@ -46,5 +60,6 @@ exports.CrewxModule = CrewxModule = __decorate([
46
60
  },
47
61
  ],
48
62
  exports: [sdk_1.Crewx],
49
- })
63
+ }),
64
+ __metadata("design:paramtypes", [sdk_1.Crewx])
50
65
  ], CrewxModule);
@@ -20,12 +20,12 @@ let BoxRepository = class BoxRepository extends base_sqlite_repository_js_1.Base
20
20
  const db = this.openReadonly(dbPath);
21
21
  try {
22
22
  this.ensureThreadExists(db, threadId);
23
- return db.all(`
24
- SELECT id, thread_id, seq, first_task_id, mid_task_id, last_task_id,
25
- task_count, summary, source_tokens, summary_tokens, created_at
26
- FROM thread_boxes
27
- WHERE thread_id = ?
28
- ORDER BY seq ASC
23
+ return db.all(`
24
+ SELECT id, thread_id, seq, first_task_id, mid_task_id, last_task_id,
25
+ task_count, summary, source_tokens, summary_tokens, created_at
26
+ FROM thread_boxes
27
+ WHERE thread_id = ?
28
+ ORDER BY seq ASC
29
29
  `, [threadId]);
30
30
  }
31
31
  catch (error) {
@@ -48,11 +48,11 @@ let BoxRepository = class BoxRepository extends base_sqlite_repository_js_1.Base
48
48
  }
49
49
  const db = this.openReadonly(dbPath);
50
50
  try {
51
- const row = db.get(`
52
- SELECT id, thread_id, seq, first_task_id, mid_task_id, last_task_id,
53
- task_count, summary, source_tokens, summary_tokens, created_at
54
- FROM thread_boxes
55
- WHERE id = ? AND thread_id = ?
51
+ const row = db.get(`
52
+ SELECT id, thread_id, seq, first_task_id, mid_task_id, last_task_id,
53
+ task_count, summary, source_tokens, summary_tokens, created_at
54
+ FROM thread_boxes
55
+ WHERE id = ? AND thread_id = ?
56
56
  `, [boxId, threadId]);
57
57
  if (!row) {
58
58
  throw new common_1.NotFoundException(`Box not found: ${boxId} in thread: ${threadId}`);
@@ -81,11 +81,11 @@ let BoxRepository = class BoxRepository extends base_sqlite_repository_js_1.Base
81
81
  try {
82
82
  this.ensureThreadExists(db, threadId);
83
83
  try {
84
- db.run(`
85
- INSERT INTO thread_boxes
86
- (id, thread_id, seq, first_task_id, mid_task_id, last_task_id,
87
- task_count, summary, source_tokens, summary_tokens, created_at)
88
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
84
+ db.run(`
85
+ INSERT INTO thread_boxes
86
+ (id, thread_id, seq, first_task_id, mid_task_id, last_task_id,
87
+ task_count, summary, source_tokens, summary_tokens, created_at)
88
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
89
89
  `, [
90
90
  data.id,
91
91
  threadId,
@@ -106,10 +106,10 @@ let BoxRepository = class BoxRepository extends base_sqlite_repository_js_1.Base
106
106
  }
107
107
  throw error;
108
108
  }
109
- return db.get(`
110
- SELECT id, thread_id, seq, first_task_id, mid_task_id, last_task_id,
111
- task_count, summary, source_tokens, summary_tokens, created_at
112
- FROM thread_boxes WHERE id = ?
109
+ return db.get(`
110
+ SELECT id, thread_id, seq, first_task_id, mid_task_id, last_task_id,
111
+ task_count, summary, source_tokens, summary_tokens, created_at
112
+ FROM thread_boxes WHERE id = ?
113
113
  `, [data.id]);
114
114
  }
115
115
  catch (error) {
@@ -31,9 +31,9 @@ let ProjectRepository = class ProjectRepository extends base_sqlite_repository_j
31
31
  }
32
32
  // Backfill workspace_path for rows that still have it in the old repo_path column
33
33
  try {
34
- db.run(`
35
- UPDATE workspaces SET workspace_path = repo_path
36
- WHERE (workspace_path IS NULL OR workspace_path = '') AND repo_path IS NOT NULL AND repo_path != ''
34
+ db.run(`
35
+ UPDATE workspaces SET workspace_path = repo_path
36
+ WHERE (workspace_path IS NULL OR workspace_path = '') AND repo_path IS NOT NULL AND repo_path != ''
37
37
  `);
38
38
  }
39
39
  catch {
@@ -86,13 +86,13 @@ let ProjectRepository = class ProjectRepository extends base_sqlite_repository_j
86
86
  const db = this.openProjectDb();
87
87
  try {
88
88
  const countRow = db.get('SELECT COUNT(*) as count FROM threads WHERE workspace_id = ?', [id]);
89
- const rows = db.all(`
90
- SELECT t.*,
91
- (SELECT agent_id FROM tasks tk WHERE tk.thread_id = t.id AND tk.agent_id IS NOT NULL ORDER BY tk.started_at ASC LIMIT 1) AS agent_id
92
- FROM threads t
93
- WHERE t.workspace_id = ?
94
- ORDER BY t.updated_at DESC
95
- LIMIT ? OFFSET ?
89
+ const rows = db.all(`
90
+ SELECT t.*,
91
+ (SELECT agent_id FROM tasks tk WHERE tk.thread_id = t.id AND tk.agent_id IS NOT NULL ORDER BY tk.started_at ASC LIMIT 1) AS agent_id
92
+ FROM threads t
93
+ WHERE t.workspace_id = ?
94
+ ORDER BY t.updated_at DESC
95
+ LIMIT ? OFFSET ?
96
96
  `, [id, params.limit, params.offset]);
97
97
  return { rows, total: countRow.count };
98
98
  }
@@ -128,9 +128,9 @@ let ProjectRepository = class ProjectRepository extends base_sqlite_repository_j
128
128
  const db = this.openProjectDb(false);
129
129
  try {
130
130
  const now = new Date().toISOString();
131
- db.run(`
132
- INSERT INTO workspaces (id, slug, name, workspace_path, is_active, created_at, updated_at)
133
- VALUES (?, ?, ?, ?, 1, ?, ?)
131
+ db.run(`
132
+ INSERT INTO workspaces (id, slug, name, workspace_path, is_active, created_at, updated_at)
133
+ VALUES (?, ?, ?, ?, 1, ?, ?)
134
134
  `, [id, slug, name, repoPath, now, now]);
135
135
  return db.get('SELECT * FROM workspaces WHERE id = ?', [id]);
136
136
  }
@@ -15,16 +15,16 @@ const common_1 = require("@nestjs/common");
15
15
  const base_sqlite_repository_js_1 = require("./base-sqlite.repository.js");
16
16
  let RequestLogRepository = class RequestLogRepository extends base_sqlite_repository_js_1.BaseSqliteRepository {
17
17
  static { RequestLogRepository_1 = this; }
18
- static INSERT_SQL = `
19
- INSERT INTO request_logs (
20
- id, path, method, status_code, duration_ms,
21
- ip, request_headers, response_headers, request_body, response_body,
22
- query, user_id, project_id, partition_key, timestamp, metadata
23
- ) VALUES (
24
- ?, ?, ?, ?, ?,
25
- ?, ?, ?, ?, ?,
26
- ?, ?, ?, ?, ?, ?
27
- )
18
+ static INSERT_SQL = `
19
+ INSERT INTO request_logs (
20
+ id, path, method, status_code, duration_ms,
21
+ ip, request_headers, response_headers, request_body, response_body,
22
+ query, user_id, project_id, partition_key, timestamp, metadata
23
+ ) VALUES (
24
+ ?, ?, ?, ?, ?,
25
+ ?, ?, ?, ?, ?,
26
+ ?, ?, ?, ?, ?, ?
27
+ )
28
28
  `;
29
29
  logger = new common_1.Logger(RequestLogRepository_1.name);
30
30
  db = null;
@@ -23,16 +23,16 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
23
23
  const db = this.openReadonly(dbPath);
24
24
  try {
25
25
  // Primary lookup: by internal task UUID
26
- let row = db.get(`SELECT id, agent_id, status, started_at, completed_at, duration_ms,
27
- error, caller_agent_id, parent_task_id, logs,
28
- prompt, result, model, thread_id, input_tokens, output_tokens, cost_usd, metadata
26
+ let row = db.get(`SELECT id, agent_id, status, started_at, completed_at, duration_ms,
27
+ error, caller_agent_id, parent_task_id, logs,
28
+ prompt, result, model, thread_id, input_tokens, output_tokens, cost_usd, metadata
29
29
  FROM tasks WHERE id = ?${wsFilter}`, [taskId, ...wsParams]);
30
30
  // Fallback: treat taskId as thread/conversation name
31
31
  if (!row) {
32
- row = db.get(`SELECT id, agent_id, status, started_at, completed_at, duration_ms,
33
- error, caller_agent_id, parent_task_id, logs,
34
- prompt, result, model, thread_id, input_tokens, output_tokens, cost_usd, metadata
35
- FROM tasks WHERE (thread_id = ? OR (thread_id IS NULL AND command LIKE ?))${wsFilter}
32
+ row = db.get(`SELECT id, agent_id, status, started_at, completed_at, duration_ms,
33
+ error, caller_agent_id, parent_task_id, logs,
34
+ prompt, result, model, thread_id, input_tokens, output_tokens, cost_usd, metadata
35
+ FROM tasks WHERE (thread_id = ? OR (thread_id IS NULL AND command LIKE ?))${wsFilter}
36
36
  ORDER BY started_at DESC LIMIT 1`, [taskId, `%--thread=${taskId}%`, ...wsParams]);
37
37
  }
38
38
  if (row)
@@ -51,7 +51,7 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
51
51
  }
52
52
  /** Get child tasks for a parent task. */
53
53
  findChildTasks(db, parentTaskId) {
54
- return db.all(`SELECT id, agent_id, status, started_at, completed_at, duration_ms, error, logs
54
+ return db.all(`SELECT id, agent_id, status, started_at, completed_at, duration_ms, error, logs
55
55
  FROM tasks WHERE parent_task_id = ? ORDER BY started_at ASC`, [parentTaskId]);
56
56
  }
57
57
  /** Get workspace usage summary, optionally filtered by workspaceId. */
@@ -63,18 +63,18 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
63
63
  try {
64
64
  const whereClause = workspaceId ? `WHERE workspace_id = ?` : '';
65
65
  const queryParams = workspaceId ? [workspaceId] : [];
66
- return db.all(`
67
- SELECT
68
- COALESCE(workspace_id, 'unknown') AS workspace_id,
69
- COALESCE(workspace_name, 'Unknown Workspace') AS workspace_name,
70
- SUM(input_tokens) AS input_tokens,
71
- SUM(output_tokens) AS output_tokens,
72
- SUM(cost_usd) AS cost_usd,
73
- COUNT(*) AS task_count
74
- FROM tasks
75
- ${whereClause}
76
- GROUP BY workspace_id, workspace_name
77
- ORDER BY (SUM(input_tokens) + SUM(output_tokens)) DESC
66
+ return db.all(`
67
+ SELECT
68
+ COALESCE(workspace_id, 'unknown') AS workspace_id,
69
+ COALESCE(workspace_name, 'Unknown Workspace') AS workspace_name,
70
+ SUM(input_tokens) AS input_tokens,
71
+ SUM(output_tokens) AS output_tokens,
72
+ SUM(cost_usd) AS cost_usd,
73
+ COUNT(*) AS task_count
74
+ FROM tasks
75
+ ${whereClause}
76
+ GROUP BY workspace_id, workspace_name
77
+ ORDER BY (SUM(input_tokens) + SUM(output_tokens)) DESC
78
78
  `, queryParams);
79
79
  }
80
80
  catch (error) {
@@ -98,7 +98,7 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
98
98
  continue;
99
99
  const db = this.openReadonly(dbPath);
100
100
  try {
101
- const rows = db.all(`SELECT id, input_tokens, output_tokens, cost_usd
101
+ const rows = db.all(`SELECT id, input_tokens, output_tokens, cost_usd
102
102
  FROM tasks WHERE thread_id = ? OR (thread_id IS NULL AND command LIKE ?)`, [threadId, `%--thread=${threadId}%`]);
103
103
  for (const row of rows) {
104
104
  if (seenIds.has(row.id))
@@ -134,9 +134,9 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
134
134
  const baseParams = [threadId, `%--thread=${threadId}%`];
135
135
  if (workspaceId)
136
136
  baseParams.push(workspaceId);
137
- const rows = db.all(`SELECT id, agent_id, started_at, completed_at, logs
138
- FROM tasks
139
- WHERE (thread_id = ? OR (thread_id IS NULL AND command LIKE ?))${wsFilter}
137
+ const rows = db.all(`SELECT id, agent_id, started_at, completed_at, logs
138
+ FROM tasks
139
+ WHERE (thread_id = ? OR (thread_id IS NULL AND command LIKE ?))${wsFilter}
140
140
  ORDER BY started_at ASC`, baseParams);
141
141
  for (const row of rows) {
142
142
  if (!seenIds.has(row.id)) {
@@ -187,10 +187,10 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
187
187
  const countRow = db.get(`SELECT COUNT(*) AS cnt FROM tasks ${whereClause}`, queryParams);
188
188
  const total = countRow?.cnt ?? 0;
189
189
  const sortDir = params.sortDir === 'ASC' ? 'ASC' : 'DESC';
190
- const tasks = db.all(`SELECT id, agent_id, status, prompt, model, started_at, completed_at, duration_ms,
191
- input_tokens, output_tokens, cost_usd, thread_id
192
- FROM tasks ${whereClause}
193
- ORDER BY started_at ${sortDir}
190
+ const tasks = db.all(`SELECT id, agent_id, status, prompt, model, started_at, completed_at, duration_ms,
191
+ input_tokens, output_tokens, cost_usd, thread_id
192
+ FROM tasks ${whereClause}
193
+ ORDER BY started_at ${sortDir}
194
194
  LIMIT ? OFFSET ?`, [...queryParams, params.limit, params.offset]);
195
195
  return { tasks, total };
196
196
  }
@@ -215,34 +215,34 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
215
215
  ? (params.push(workspace), `AND t.workspace_name = ?`)
216
216
  : '';
217
217
  // Provider derived from coding_agent_command first word (no agents table)
218
- return db.all(`
219
- SELECT
220
- t.agent_id,
221
- t.workspace_id,
222
- t.workspace_name,
223
- COALESCE(
224
- 'cli/' || SUBSTR(t.coding_agent_command, 1,
225
- CASE WHEN INSTR(t.coding_agent_command, ' ') > 0
226
- THEN INSTR(t.coding_agent_command, ' ') - 1
227
- ELSE LENGTH(t.coding_agent_command)
228
- END
229
- ),
230
- 'unknown'
231
- ) AS provider,
232
- COALESCE(SUM(t.input_tokens), 0) AS input_tokens,
233
- COALESCE(SUM(t.output_tokens), 0) AS output_tokens,
234
- COALESCE(SUM(t.input_tokens), 0) + COALESCE(SUM(t.output_tokens), 0) AS total_tokens,
235
- COALESCE(SUM(t.cost_usd), 0) AS total_cost,
236
- COUNT(*) AS task_count,
237
- COALESCE(SUM(t.duration_ms), 0) AS active_duration_ms,
238
- MAX(t.completed_at) AS last_active_at
239
- FROM tasks t
240
- WHERE t.status IN ('completed', 'success')
241
- AND t.started_at >= ?
242
- AND t.started_at < ?
243
- ${workspaceCondition}
244
- GROUP BY t.agent_id, t.workspace_id, t.workspace_name, provider
245
- ORDER BY total_tokens DESC
218
+ return db.all(`
219
+ SELECT
220
+ t.agent_id,
221
+ t.workspace_id,
222
+ t.workspace_name,
223
+ COALESCE(
224
+ 'cli/' || SUBSTR(t.coding_agent_command, 1,
225
+ CASE WHEN INSTR(t.coding_agent_command, ' ') > 0
226
+ THEN INSTR(t.coding_agent_command, ' ') - 1
227
+ ELSE LENGTH(t.coding_agent_command)
228
+ END
229
+ ),
230
+ 'unknown'
231
+ ) AS provider,
232
+ COALESCE(SUM(t.input_tokens), 0) AS input_tokens,
233
+ COALESCE(SUM(t.output_tokens), 0) AS output_tokens,
234
+ COALESCE(SUM(t.input_tokens), 0) + COALESCE(SUM(t.output_tokens), 0) AS total_tokens,
235
+ COALESCE(SUM(t.cost_usd), 0) AS total_cost,
236
+ COUNT(*) AS task_count,
237
+ COALESCE(SUM(t.duration_ms), 0) AS active_duration_ms,
238
+ MAX(t.completed_at) AS last_active_at
239
+ FROM tasks t
240
+ WHERE t.status IN ('completed', 'success')
241
+ AND t.started_at >= ?
242
+ AND t.started_at < ?
243
+ ${workspaceCondition}
244
+ GROUP BY t.agent_id, t.workspace_id, t.workspace_name, provider
245
+ ORDER BY total_tokens DESC
246
246
  `, params);
247
247
  }
248
248
  catch (error) {
@@ -263,18 +263,18 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
263
263
  const workspaceCondition = workspace
264
264
  ? (params.push(workspace), `AND t.workspace_name = ?`)
265
265
  : '';
266
- return db.all(`
267
- SELECT
268
- t.started_at,
269
- t.agent_id,
270
- COALESCE(t.input_tokens, 0) AS input_tokens,
271
- COALESCE(t.output_tokens, 0) AS output_tokens
272
- FROM tasks t
273
- WHERE t.status IN ('completed', 'success')
274
- AND t.started_at >= ?
275
- AND t.started_at < ?
276
- ${workspaceCondition}
277
- ORDER BY t.started_at ASC
266
+ return db.all(`
267
+ SELECT
268
+ t.started_at,
269
+ t.agent_id,
270
+ COALESCE(t.input_tokens, 0) AS input_tokens,
271
+ COALESCE(t.output_tokens, 0) AS output_tokens
272
+ FROM tasks t
273
+ WHERE t.status IN ('completed', 'success')
274
+ AND t.started_at >= ?
275
+ AND t.started_at < ?
276
+ ${workspaceCondition}
277
+ ORDER BY t.started_at ASC
278
278
  `, params);
279
279
  }
280
280
  catch (error) {
@@ -315,7 +315,7 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
315
315
  const params = workspaceId
316
316
  ? [error, now, taskId, workspaceId]
317
317
  : [error, now, taskId];
318
- db.run(`UPDATE tasks SET status = 'failed', error = ?, completed_at = ?
318
+ db.run(`UPDATE tasks SET status = 'failed', error = ?, completed_at = ?
319
319
  WHERE id = ? AND status = 'running'${wsFilter}`, params);
320
320
  const changes = db.get(`SELECT changes() AS cnt`);
321
321
  return (changes?.cnt ?? 0) > 0;
@@ -336,9 +336,9 @@ let TaskRepository = class TaskRepository extends base_sqlite_repository_js_1.Ba
336
336
  try {
337
337
  const wsFilter = workspaceId ? ` AND workspace_id = ?` : '';
338
338
  const params = workspaceId ? [`%${hint}%`, workspaceId] : [`%${hint}%`];
339
- const rows = db.all(`SELECT id, agent_id, started_at, completed_at, logs
340
- FROM tasks
341
- WHERE prompt LIKE ?${wsFilter}
339
+ const rows = db.all(`SELECT id, agent_id, started_at, completed_at, logs
340
+ FROM tasks
341
+ WHERE prompt LIKE ?${wsFilter}
342
342
  ORDER BY started_at ASC`, params);
343
343
  for (const row of rows) {
344
344
  if (!seenIds.has(row.id)) {