@mcoda/core 0.1.4

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 (142) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +9 -0
  4. package/dist/api/AgentsApi.d.ts +36 -0
  5. package/dist/api/AgentsApi.d.ts.map +1 -0
  6. package/dist/api/AgentsApi.js +176 -0
  7. package/dist/api/QaTasksApi.d.ts +8 -0
  8. package/dist/api/QaTasksApi.d.ts.map +1 -0
  9. package/dist/api/QaTasksApi.js +36 -0
  10. package/dist/api/TasksApi.d.ts +7 -0
  11. package/dist/api/TasksApi.d.ts.map +1 -0
  12. package/dist/api/TasksApi.js +34 -0
  13. package/dist/config/ConfigService.d.ts +3 -0
  14. package/dist/config/ConfigService.d.ts.map +1 -0
  15. package/dist/config/ConfigService.js +2 -0
  16. package/dist/domain/dependencies/Dependency.d.ts +3 -0
  17. package/dist/domain/dependencies/Dependency.d.ts.map +1 -0
  18. package/dist/domain/dependencies/Dependency.js +2 -0
  19. package/dist/domain/epics/Epic.d.ts +3 -0
  20. package/dist/domain/epics/Epic.d.ts.map +1 -0
  21. package/dist/domain/epics/Epic.js +2 -0
  22. package/dist/domain/projects/Project.d.ts +3 -0
  23. package/dist/domain/projects/Project.d.ts.map +1 -0
  24. package/dist/domain/projects/Project.js +2 -0
  25. package/dist/domain/tasks/Task.d.ts +3 -0
  26. package/dist/domain/tasks/Task.d.ts.map +1 -0
  27. package/dist/domain/tasks/Task.js +2 -0
  28. package/dist/domain/userStories/UserStory.d.ts +3 -0
  29. package/dist/domain/userStories/UserStory.d.ts.map +1 -0
  30. package/dist/domain/userStories/UserStory.js +2 -0
  31. package/dist/index.d.ts +28 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +27 -0
  34. package/dist/prompts/PdrPrompts.d.ts +4 -0
  35. package/dist/prompts/PdrPrompts.d.ts.map +1 -0
  36. package/dist/prompts/PdrPrompts.js +21 -0
  37. package/dist/prompts/PromptLoader.d.ts +3 -0
  38. package/dist/prompts/PromptLoader.d.ts.map +1 -0
  39. package/dist/prompts/PromptLoader.js +2 -0
  40. package/dist/prompts/SdsPrompts.d.ts +5 -0
  41. package/dist/prompts/SdsPrompts.d.ts.map +1 -0
  42. package/dist/prompts/SdsPrompts.js +44 -0
  43. package/dist/services/agents/AgentManagementService.d.ts +3 -0
  44. package/dist/services/agents/AgentManagementService.d.ts.map +1 -0
  45. package/dist/services/agents/AgentManagementService.js +2 -0
  46. package/dist/services/agents/GatewayAgentService.d.ts +92 -0
  47. package/dist/services/agents/GatewayAgentService.d.ts.map +1 -0
  48. package/dist/services/agents/GatewayAgentService.js +870 -0
  49. package/dist/services/agents/RoutingApiClient.d.ts +23 -0
  50. package/dist/services/agents/RoutingApiClient.d.ts.map +1 -0
  51. package/dist/services/agents/RoutingApiClient.js +62 -0
  52. package/dist/services/agents/RoutingService.d.ts +50 -0
  53. package/dist/services/agents/RoutingService.d.ts.map +1 -0
  54. package/dist/services/agents/RoutingService.js +386 -0
  55. package/dist/services/agents/generated/RoutingApiClient.d.ts +21 -0
  56. package/dist/services/agents/generated/RoutingApiClient.d.ts.map +1 -0
  57. package/dist/services/agents/generated/RoutingApiClient.js +68 -0
  58. package/dist/services/backlog/BacklogService.d.ts +98 -0
  59. package/dist/services/backlog/BacklogService.d.ts.map +1 -0
  60. package/dist/services/backlog/BacklogService.js +453 -0
  61. package/dist/services/backlog/TaskOrderingService.d.ts +88 -0
  62. package/dist/services/backlog/TaskOrderingService.d.ts.map +1 -0
  63. package/dist/services/backlog/TaskOrderingService.js +675 -0
  64. package/dist/services/docs/DocsService.d.ts +82 -0
  65. package/dist/services/docs/DocsService.d.ts.map +1 -0
  66. package/dist/services/docs/DocsService.js +1631 -0
  67. package/dist/services/estimate/EstimateService.d.ts +12 -0
  68. package/dist/services/estimate/EstimateService.d.ts.map +1 -0
  69. package/dist/services/estimate/EstimateService.js +103 -0
  70. package/dist/services/estimate/VelocityService.d.ts +19 -0
  71. package/dist/services/estimate/VelocityService.d.ts.map +1 -0
  72. package/dist/services/estimate/VelocityService.js +237 -0
  73. package/dist/services/estimate/types.d.ts +30 -0
  74. package/dist/services/estimate/types.d.ts.map +1 -0
  75. package/dist/services/estimate/types.js +1 -0
  76. package/dist/services/execution/ExecutionService.d.ts +3 -0
  77. package/dist/services/execution/ExecutionService.d.ts.map +1 -0
  78. package/dist/services/execution/ExecutionService.js +2 -0
  79. package/dist/services/execution/QaFollowupService.d.ts +38 -0
  80. package/dist/services/execution/QaFollowupService.d.ts.map +1 -0
  81. package/dist/services/execution/QaFollowupService.js +236 -0
  82. package/dist/services/execution/QaProfileService.d.ts +22 -0
  83. package/dist/services/execution/QaProfileService.d.ts.map +1 -0
  84. package/dist/services/execution/QaProfileService.js +142 -0
  85. package/dist/services/execution/QaTasksService.d.ts +101 -0
  86. package/dist/services/execution/QaTasksService.d.ts.map +1 -0
  87. package/dist/services/execution/QaTasksService.js +1117 -0
  88. package/dist/services/execution/TaskSelectionService.d.ts +50 -0
  89. package/dist/services/execution/TaskSelectionService.d.ts.map +1 -0
  90. package/dist/services/execution/TaskSelectionService.js +281 -0
  91. package/dist/services/execution/TaskStateService.d.ts +19 -0
  92. package/dist/services/execution/TaskStateService.d.ts.map +1 -0
  93. package/dist/services/execution/TaskStateService.js +59 -0
  94. package/dist/services/execution/WorkOnTasksService.d.ts +80 -0
  95. package/dist/services/execution/WorkOnTasksService.d.ts.map +1 -0
  96. package/dist/services/execution/WorkOnTasksService.js +1833 -0
  97. package/dist/services/jobs/JobInsightsService.d.ts +97 -0
  98. package/dist/services/jobs/JobInsightsService.d.ts.map +1 -0
  99. package/dist/services/jobs/JobInsightsService.js +263 -0
  100. package/dist/services/jobs/JobResumeService.d.ts +16 -0
  101. package/dist/services/jobs/JobResumeService.d.ts.map +1 -0
  102. package/dist/services/jobs/JobResumeService.js +113 -0
  103. package/dist/services/jobs/JobService.d.ts +149 -0
  104. package/dist/services/jobs/JobService.d.ts.map +1 -0
  105. package/dist/services/jobs/JobService.js +490 -0
  106. package/dist/services/jobs/JobsApiClient.d.ts +73 -0
  107. package/dist/services/jobs/JobsApiClient.d.ts.map +1 -0
  108. package/dist/services/jobs/JobsApiClient.js +67 -0
  109. package/dist/services/openapi/OpenApiService.d.ts +54 -0
  110. package/dist/services/openapi/OpenApiService.d.ts.map +1 -0
  111. package/dist/services/openapi/OpenApiService.js +503 -0
  112. package/dist/services/planning/CreateTasksService.d.ts +68 -0
  113. package/dist/services/planning/CreateTasksService.d.ts.map +1 -0
  114. package/dist/services/planning/CreateTasksService.js +989 -0
  115. package/dist/services/planning/KeyHelpers.d.ts +5 -0
  116. package/dist/services/planning/KeyHelpers.d.ts.map +1 -0
  117. package/dist/services/planning/KeyHelpers.js +62 -0
  118. package/dist/services/planning/PlanningService.d.ts +3 -0
  119. package/dist/services/planning/PlanningService.d.ts.map +1 -0
  120. package/dist/services/planning/PlanningService.js +2 -0
  121. package/dist/services/planning/RefineTasksService.d.ts +56 -0
  122. package/dist/services/planning/RefineTasksService.d.ts.map +1 -0
  123. package/dist/services/planning/RefineTasksService.js +1328 -0
  124. package/dist/services/review/CodeReviewService.d.ts +103 -0
  125. package/dist/services/review/CodeReviewService.d.ts.map +1 -0
  126. package/dist/services/review/CodeReviewService.js +1187 -0
  127. package/dist/services/system/SystemUpdateService.d.ts +55 -0
  128. package/dist/services/system/SystemUpdateService.d.ts.map +1 -0
  129. package/dist/services/system/SystemUpdateService.js +136 -0
  130. package/dist/services/tasks/TaskApiResolver.d.ts +7 -0
  131. package/dist/services/tasks/TaskApiResolver.d.ts.map +1 -0
  132. package/dist/services/tasks/TaskApiResolver.js +41 -0
  133. package/dist/services/tasks/TaskDetailService.d.ts +106 -0
  134. package/dist/services/tasks/TaskDetailService.d.ts.map +1 -0
  135. package/dist/services/tasks/TaskDetailService.js +332 -0
  136. package/dist/services/telemetry/TelemetryService.d.ts +53 -0
  137. package/dist/services/telemetry/TelemetryService.d.ts.map +1 -0
  138. package/dist/services/telemetry/TelemetryService.js +434 -0
  139. package/dist/workspace/WorkspaceManager.d.ts +35 -0
  140. package/dist/workspace/WorkspaceManager.d.ts.map +1 -0
  141. package/dist/workspace/WorkspaceManager.js +201 -0
  142. package/package.json +45 -0
@@ -0,0 +1,97 @@
1
+ import { WorkspaceResolution } from "../../workspace/WorkspaceManager.js";
2
+ import { JobRecord, JobService, JobState } from "./JobService.js";
3
+ export interface JobListFilters {
4
+ status?: string;
5
+ type?: string;
6
+ projectKey?: string;
7
+ since?: string;
8
+ limit?: number;
9
+ }
10
+ export interface JobSummary extends JobRecord {
11
+ progressPct?: number | null;
12
+ lastCheckpointStage?: string;
13
+ lastCheckpointAt?: string;
14
+ stateDetail?: string;
15
+ jobState?: JobState;
16
+ jobStateDetail?: string;
17
+ totalUnits?: number;
18
+ completedUnits?: number;
19
+ }
20
+ export interface CheckpointSummary {
21
+ stage?: string;
22
+ timestamp?: string;
23
+ details?: Record<string, unknown>;
24
+ path?: string;
25
+ }
26
+ export interface JobLogEntry {
27
+ timestamp: string;
28
+ sequence?: number | null;
29
+ level?: string | null;
30
+ source?: string | null;
31
+ message?: string | null;
32
+ taskId?: string | null;
33
+ taskKey?: string | null;
34
+ phase?: string | null;
35
+ details?: Record<string, unknown> | null;
36
+ }
37
+ export interface JobLogsResult {
38
+ entries: JobLogEntry[];
39
+ cursor?: {
40
+ timestamp: string;
41
+ sequence?: number | null;
42
+ };
43
+ }
44
+ export interface TaskRunSnapshot {
45
+ taskId?: string | null;
46
+ taskKey?: string | null;
47
+ status?: string | null;
48
+ startedAt?: string | null;
49
+ finishedAt?: string | null;
50
+ command?: string | null;
51
+ }
52
+ export interface TaskRunSummary {
53
+ totals: Record<string, number>;
54
+ tasks: TaskRunSnapshot[];
55
+ }
56
+ export interface TokenUsageSummary {
57
+ agentId?: string | null;
58
+ modelName?: string | null;
59
+ commandName?: string | null;
60
+ commandRunId?: string | null;
61
+ taskId?: string | null;
62
+ tokensPrompt?: number | null;
63
+ tokensCompletion?: number | null;
64
+ tokensTotal?: number | null;
65
+ cost?: number | null;
66
+ }
67
+ export declare class JobInsightsService {
68
+ private workspace;
69
+ private jobService;
70
+ private apiClient?;
71
+ constructor(workspace: WorkspaceResolution, jobService: JobService, apiBaseUrl?: string);
72
+ static create(workspace: WorkspaceResolution): Promise<JobInsightsService>;
73
+ close(): Promise<void>;
74
+ listJobs(filters?: JobListFilters): Promise<JobSummary[]>;
75
+ getJob(jobId: string): Promise<JobSummary | undefined>;
76
+ latestCheckpoint(jobId: string): Promise<CheckpointSummary | undefined>;
77
+ getJobLogs(jobId: string, options?: {
78
+ since?: string;
79
+ after?: {
80
+ timestamp: string;
81
+ sequence?: number | null;
82
+ };
83
+ }): Promise<JobLogsResult>;
84
+ summarizeTasks(jobId: string): Promise<TaskRunSummary>;
85
+ summarizeTokenUsage(jobId: string): Promise<TokenUsageSummary[]>;
86
+ readJobLog(jobId: string): Promise<string>;
87
+ readJobLogTail(jobId: string, offset: number): Promise<{
88
+ content: string;
89
+ nextOffset: number;
90
+ }>;
91
+ updateJobState(jobId: string, state: JobState, meta?: Record<string, unknown>): Promise<void>;
92
+ cancelJob(jobId: string, options?: {
93
+ force?: boolean;
94
+ reason?: string;
95
+ }): Promise<void>;
96
+ }
97
+ //# sourceMappingURL=JobInsightsService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobInsightsService.d.ts","sourceRoot":"","sources":["../../../src/services/jobs/JobInsightsService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,263 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { PathHelper } from "@mcoda/shared";
4
+ import { JobService } from "./JobService.js";
5
+ import { JobsApiClient } from "./JobsApiClient.js";
6
+ import { TelemetryService } from "../telemetry/TelemetryService.js";
7
+ const parseSinceInput = (input) => {
8
+ if (!input)
9
+ return undefined;
10
+ const trimmed = input.trim();
11
+ const durationMatch = trimmed.match(/^(\d+)([smhdw])$/i);
12
+ if (durationMatch) {
13
+ const amount = Number(durationMatch[1]);
14
+ const unit = durationMatch[2].toLowerCase();
15
+ const multipliers = {
16
+ s: 1000,
17
+ m: 60 * 1000,
18
+ h: 60 * 60 * 1000,
19
+ d: 24 * 60 * 60 * 1000,
20
+ w: 7 * 24 * 60 * 60 * 1000,
21
+ };
22
+ if (multipliers[unit]) {
23
+ return new Date(Date.now() - amount * multipliers[unit]).toISOString();
24
+ }
25
+ }
26
+ const parsed = Date.parse(trimmed);
27
+ if (!Number.isNaN(parsed)) {
28
+ return new Date(parsed).toISOString();
29
+ }
30
+ return undefined;
31
+ };
32
+ const computeProgress = (job) => {
33
+ const total = job.totalUnits ?? job.totalItems ?? null;
34
+ const completed = job.completedUnits ?? job.processedItems ?? 0;
35
+ if (!total || total <= 0)
36
+ return null;
37
+ return Math.round((completed / total) * 100);
38
+ };
39
+ const mapJobRow = (row) => {
40
+ const payload = row.payload_json ? JSON.parse(row.payload_json) : undefined;
41
+ const totalUnits = row.total_units ?? row.totalUnits ?? row.total_items ?? row.totalItems ?? undefined;
42
+ const completedUnits = row.completed_units ?? row.completedUnits ?? row.processed_items ?? row.processedItems ?? undefined;
43
+ const progressPct = computeProgress({ totalItems: totalUnits, processedItems: completedUnits });
44
+ return {
45
+ id: row.id,
46
+ type: row.type,
47
+ state: row.state ?? row.job_state,
48
+ jobState: row.job_state ?? row.state,
49
+ jobStateDetail: row.job_state_detail ?? row.state_detail ?? row.errorSummary,
50
+ stateDetail: row.job_state_detail ?? row.state_detail ?? row.errorSummary,
51
+ commandName: row.command_name ?? row.commandName,
52
+ commandRunId: row.command_run_id ?? row.commandRunId,
53
+ workspaceId: row.workspace_id ?? row.workspaceId,
54
+ projectKey: row.projectKey,
55
+ payload,
56
+ totalItems: totalUnits,
57
+ processedItems: completedUnits,
58
+ totalUnits,
59
+ completedUnits,
60
+ lastCheckpoint: row.last_checkpoint ?? row.lastCheckpoint,
61
+ createdAt: row.created_at ?? row.createdAt,
62
+ updatedAt: row.updated_at ?? row.updatedAt,
63
+ completedAt: row.completed_at ?? row.completedAt,
64
+ errorSummary: row.error_summary ?? row.errorSummary,
65
+ progressPct,
66
+ };
67
+ };
68
+ const matchesProject = (payload, projectKey) => {
69
+ if (!projectKey)
70
+ return true;
71
+ if (!payload)
72
+ return false;
73
+ const candidates = [
74
+ payload.projectKey,
75
+ payload.project_id,
76
+ payload.project,
77
+ payload.projectId,
78
+ ].filter(Boolean);
79
+ return candidates.includes(projectKey);
80
+ };
81
+ export class JobInsightsService {
82
+ constructor(workspace, jobService, apiBaseUrl) {
83
+ this.workspace = workspace;
84
+ this.jobService = jobService;
85
+ if (apiBaseUrl) {
86
+ this.apiClient = new JobsApiClient(workspace, apiBaseUrl);
87
+ }
88
+ }
89
+ static async create(workspace) {
90
+ const jobService = new JobService(workspace, undefined, { requireRepo: true });
91
+ const apiBaseUrl = workspace.config?.api?.baseUrl ??
92
+ process.env.MCODA_API_BASE_URL ??
93
+ process.env.MCODA_JOBS_API_URL ??
94
+ undefined;
95
+ return new JobInsightsService(workspace, jobService, apiBaseUrl);
96
+ }
97
+ async close() {
98
+ await this.jobService.close();
99
+ }
100
+ async listJobs(filters = {}) {
101
+ if (!this.apiClient) {
102
+ throw new Error("Jobs API is not configured; set MCODA_API_BASE_URL/MCODA_JOBS_API_URL or workspace api.baseUrl to query jobs.");
103
+ }
104
+ const remote = (await this.apiClient.listJobs({
105
+ status: filters.status,
106
+ type: filters.type,
107
+ project: filters.projectKey,
108
+ since: filters.since,
109
+ limit: filters.limit,
110
+ })) ?? [];
111
+ const rows = remote.map(mapJobRow);
112
+ const sinceIso = parseSinceInput(filters.since);
113
+ return rows
114
+ .filter((job) => {
115
+ const state = job.jobState ?? job.state;
116
+ return !filters.status || state === filters.status;
117
+ })
118
+ .filter((job) => (!filters.type || job.type === filters.type))
119
+ .filter((job) => matchesProject(job.payload, filters.projectKey))
120
+ .filter((job) => {
121
+ if (!sinceIso)
122
+ return true;
123
+ const updated = job.updatedAt ?? job.createdAt;
124
+ if (!updated)
125
+ return true;
126
+ return Date.parse(updated) >= Date.parse(sinceIso);
127
+ })
128
+ .slice(0, Number.isFinite(filters.limit) ? filters.limit : rows.length)
129
+ .map((job) => ({ ...job, progressPct: computeProgress(job) }));
130
+ }
131
+ async getJob(jobId) {
132
+ if (!this.apiClient) {
133
+ throw new Error("Jobs API is not configured; set MCODA_API_BASE_URL/MCODA_JOBS_API_URL or workspace api.baseUrl to read job status.");
134
+ }
135
+ const remote = await this.apiClient.getJob(jobId);
136
+ const job = remote ? mapJobRow(remote) : undefined;
137
+ if (!job)
138
+ return undefined;
139
+ const detail = job.job_state_detail ?? job.jobStateDetail ?? job.errorSummary;
140
+ const totalUnits = job.totalUnits ?? job.totalItems ?? job.total_units ?? undefined;
141
+ const completedUnits = job.completedUnits ?? job.processedItems ?? job.completed_units ?? undefined;
142
+ return {
143
+ ...job,
144
+ jobState: job.job_state ?? job.state,
145
+ jobStateDetail: detail,
146
+ stateDetail: detail,
147
+ totalUnits,
148
+ completedUnits,
149
+ progressPct: computeProgress({ totalItems: totalUnits, processedItems: completedUnits }),
150
+ };
151
+ }
152
+ async latestCheckpoint(jobId) {
153
+ if (!this.apiClient) {
154
+ throw new Error("Jobs API is not configured; set MCODA_API_BASE_URL/MCODA_JOBS_API_URL or workspace api.baseUrl to read checkpoints.");
155
+ }
156
+ const remote = await this.apiClient.getCheckpoint(jobId);
157
+ if (remote && (remote.stage || remote.status || remote.timestamp)) {
158
+ const data = remote;
159
+ return {
160
+ stage: data.stage ?? data.status,
161
+ timestamp: data.timestamp ?? data.created_at,
162
+ details: data.details ?? data.progress,
163
+ };
164
+ }
165
+ const checkpoints = await this.jobService.readCheckpoints(jobId);
166
+ if (!checkpoints.length)
167
+ return undefined;
168
+ const last = checkpoints[checkpoints.length - 1];
169
+ return {
170
+ stage: last.stage ?? last.status,
171
+ timestamp: last.timestamp ?? last.created_at,
172
+ details: last.details,
173
+ };
174
+ }
175
+ async getJobLogs(jobId, options = {}) {
176
+ if (!this.apiClient) {
177
+ throw new Error("Jobs API is not configured; set MCODA_API_BASE_URL/MCODA_JOBS_API_URL or workspace api.baseUrl to stream job logs.");
178
+ }
179
+ const remote = await this.apiClient.getLogs(jobId, options);
180
+ if (!remote)
181
+ return { entries: [], cursor: undefined };
182
+ return remote;
183
+ }
184
+ async summarizeTasks(jobId) {
185
+ if (!this.apiClient) {
186
+ throw new Error("Jobs API is not configured; set MCODA_API_BASE_URL/MCODA_JOBS_API_URL or workspace api.baseUrl to read task summaries.");
187
+ }
188
+ const remote = (await this.apiClient.getTasksSummary(jobId)) ?? { totals: {}, tasks: [] };
189
+ const runs = (remote.tasks ?? []).map((t) => {
190
+ const taskId = t.taskId ?? t.task_id ?? null;
191
+ const taskKey = t.taskKey ?? t.task_key ?? null;
192
+ const startedAt = t.startedAt ?? t.started_at ?? null;
193
+ const finishedAt = t.finishedAt ?? t.finished_at ?? null;
194
+ const command = t.command ?? null;
195
+ return { taskId, taskKey, status: t.status ?? null, startedAt, finishedAt, command };
196
+ });
197
+ const totalsRemote = remote.totals ?? {};
198
+ const totals = {};
199
+ for (const run of runs) {
200
+ const status = run.status ?? "unknown";
201
+ totals[status] = (totals[status] ?? 0) + 1;
202
+ }
203
+ Object.entries(totalsRemote ?? {}).forEach(([k, v]) => {
204
+ totals[k] = v;
205
+ });
206
+ const tasks = runs.map((run) => ({
207
+ taskId: run.taskId ?? undefined,
208
+ taskKey: run.taskKey ?? undefined,
209
+ status: run.status ?? undefined,
210
+ startedAt: run.startedAt ?? undefined,
211
+ finishedAt: run.finishedAt ?? undefined,
212
+ command: run.command ?? undefined,
213
+ }));
214
+ return { totals, tasks };
215
+ }
216
+ async summarizeTokenUsage(jobId) {
217
+ const telemetry = await TelemetryService.create(this.workspace, { allowMissingTelemetry: false, requireApi: true });
218
+ try {
219
+ const summary = await telemetry.getSummary({
220
+ jobId,
221
+ groupBy: ["command", "agent", "model"],
222
+ since: undefined,
223
+ until: undefined,
224
+ });
225
+ return summary.map((row) => ({
226
+ commandName: row.command_name ?? null,
227
+ agentId: row.agent_id ?? null,
228
+ modelName: row.model_name ?? null,
229
+ tokensPrompt: row.tokens_prompt ?? null,
230
+ tokensCompletion: row.tokens_completion ?? null,
231
+ tokensTotal: row.tokens_total ?? null,
232
+ cost: row.cost_estimate ?? null,
233
+ }));
234
+ }
235
+ finally {
236
+ await telemetry.close();
237
+ }
238
+ }
239
+ async readJobLog(jobId) {
240
+ return this.jobService.readLog(jobId);
241
+ }
242
+ async readJobLogTail(jobId, offset) {
243
+ const logPath = path.join(PathHelper.getWorkspaceDir(this.workspace.workspaceRoot), "jobs", jobId, "logs", "stream.log");
244
+ try {
245
+ const content = await fs.readFile(logPath, "utf8");
246
+ const slice = offset > 0 ? content.slice(offset) : content;
247
+ return { content: slice, nextOffset: content.length };
248
+ }
249
+ catch {
250
+ return { content: "", nextOffset: offset };
251
+ }
252
+ }
253
+ async updateJobState(jobId, state, meta) {
254
+ await this.jobService.updateJobStatus(jobId, state, meta);
255
+ }
256
+ async cancelJob(jobId, options = {}) {
257
+ if (this.apiClient) {
258
+ await this.apiClient.cancelJob(jobId, options);
259
+ return;
260
+ }
261
+ throw new Error("Cancel requires the jobs API; set MCODA_API_BASE_URL or workspace baseUrl so the cancel endpoint can enforce state transitions.");
262
+ }
263
+ }
@@ -0,0 +1,16 @@
1
+ import { WorkspaceResolution } from "../../workspace/WorkspaceManager.js";
2
+ import { JobService } from "./JobService.js";
3
+ export interface ResumeOptions {
4
+ agentName?: string;
5
+ noTelemetry?: boolean;
6
+ }
7
+ export declare class JobResumeService {
8
+ private workspace;
9
+ private jobService;
10
+ constructor(workspace: WorkspaceResolution, jobService: JobService);
11
+ static create(workspace: WorkspaceResolution): Promise<JobResumeService>;
12
+ private readManifest;
13
+ private assertResumeAllowed;
14
+ resume(jobId: string, options?: ResumeOptions): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=JobResumeService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobResumeService.d.ts","sourceRoot":"","sources":["../../../src/services/jobs/JobResumeService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAK7C,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,gBAAgB;IACf,OAAO,CAAC,SAAS;IAAuB,OAAO,CAAC,UAAU;gBAAlD,SAAS,EAAE,mBAAmB,EAAU,UAAU,EAAE,UAAU;WAErE,MAAM,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAKhE,YAAY;IAU1B,OAAO,CAAC,mBAAmB;IA8BrB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CAyDxE"}
@@ -0,0 +1,113 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { JobService } from "./JobService.js";
4
+ import { CodeReviewService } from "../review/CodeReviewService.js";
5
+ import { QaTasksService } from "../execution/QaTasksService.js";
6
+ import { DocsService } from "../docs/DocsService.js";
7
+ export class JobResumeService {
8
+ constructor(workspace, jobService) {
9
+ this.workspace = workspace;
10
+ this.jobService = jobService;
11
+ }
12
+ static async create(workspace) {
13
+ const jobService = new JobService(workspace, undefined, { requireRepo: true });
14
+ return new JobResumeService(workspace, jobService);
15
+ }
16
+ async readManifest(jobId) {
17
+ const manifestPath = path.join(this.workspace.workspaceRoot, ".mcoda", "jobs", jobId, "manifest.json");
18
+ try {
19
+ const raw = await fs.readFile(manifestPath, "utf8");
20
+ return JSON.parse(raw);
21
+ }
22
+ catch {
23
+ return undefined;
24
+ }
25
+ }
26
+ assertResumeAllowed(job, manifest) {
27
+ const state = job.jobState ?? job.state ?? "unknown";
28
+ if (["completed", "cancelled"].includes(state)) {
29
+ throw new Error(`Job ${job.id} is ${state}; cannot resume.`);
30
+ }
31
+ if (["running", "queued", "checkpointing"].includes(state)) {
32
+ throw new Error(`Job ${job.id} is ${state}; wait for it to finish or cancel before resuming.`);
33
+ }
34
+ const supported = job.resumeSupported ?? job.resume_supported ?? job.payload?.resumeSupported ?? job.payload?.resume_supported;
35
+ if (supported === 0 || supported === false) {
36
+ throw new Error(`Job ${job.id} does not support resume.`);
37
+ }
38
+ if (!manifest) {
39
+ throw new Error(`Missing manifest for job ${job.id}; cannot resume safely.`);
40
+ }
41
+ const manifestJobId = manifest.job_id ?? manifest.id;
42
+ if (manifestJobId && manifestJobId !== job.id) {
43
+ throw new Error(`Checkpoint manifest for ${job.id} does not match job id (${manifestJobId}); aborting resume.`);
44
+ }
45
+ const manifestType = manifest.type ?? manifest.job_type;
46
+ if (manifestType && manifestType !== job.type) {
47
+ throw new Error(`Checkpoint manifest type (${manifestType}) does not match job type (${job.type}); cannot resume.`);
48
+ }
49
+ const manifestCommand = manifest.command ?? manifest.command_name ?? manifest.commandName;
50
+ if (manifestCommand && job.commandName && manifestCommand !== job.commandName) {
51
+ throw new Error(`Checkpoint manifest command (${manifestCommand}) does not match job command (${job.commandName}); cannot resume.`);
52
+ }
53
+ }
54
+ async resume(jobId, options = {}) {
55
+ const job = await this.jobService.getJob(jobId);
56
+ if (!job)
57
+ throw new Error(`Job not found: ${jobId}`);
58
+ const checkpoints = await this.jobService.readCheckpoints(jobId);
59
+ if (!checkpoints.length)
60
+ throw new Error(`No checkpoints found for job ${jobId}; cannot resume.`);
61
+ const manifest = await this.readManifest(jobId);
62
+ this.assertResumeAllowed(job, manifest);
63
+ await this.jobService.updateJobStatus(jobId, "running", { job_state_detail: "resuming" });
64
+ const command = (job.commandName ?? job.type ?? "").toLowerCase();
65
+ if (command === "code-review" || job.type === "review") {
66
+ const service = await CodeReviewService.create(this.workspace);
67
+ try {
68
+ await service.reviewTasks({
69
+ workspace: this.workspace,
70
+ resumeJobId: jobId,
71
+ agentName: options.agentName,
72
+ agentStream: true,
73
+ });
74
+ }
75
+ finally {
76
+ await service.close();
77
+ }
78
+ return;
79
+ }
80
+ if (command === "qa-tasks" || job.type === "qa") {
81
+ const qaService = await QaTasksService.create(this.workspace, { noTelemetry: options.noTelemetry });
82
+ try {
83
+ await qaService.run({
84
+ workspace: this.workspace,
85
+ resumeJobId: jobId,
86
+ projectKey: job.projectKey ?? job.payload?.projectKey,
87
+ agentName: options.agentName,
88
+ agentStream: true,
89
+ });
90
+ }
91
+ finally {
92
+ await qaService.close();
93
+ }
94
+ return;
95
+ }
96
+ if (command.includes("sds") || job.type === "sds_generate" || command.includes("pdr") || job.type === "pdr_generate") {
97
+ const docs = await DocsService.create(this.workspace);
98
+ try {
99
+ if (command.includes("sds") || job.type === "sds_generate") {
100
+ await docs.generateSds({ workspace: this.workspace, resumeJobId: jobId, agentName: options.agentName });
101
+ }
102
+ else {
103
+ await docs.generatePdr({ workspace: this.workspace, resumeJobId: jobId, agentName: options.agentName });
104
+ }
105
+ }
106
+ finally {
107
+ await docs.close();
108
+ }
109
+ return;
110
+ }
111
+ throw new Error(`Resume is not implemented for job type ${job.type ?? job.commandName ?? "unknown"}.`);
112
+ }
113
+ }
@@ -0,0 +1,149 @@
1
+ import { WorkspaceRepository, CommandStatus, JobStatus, TokenUsageInsert } from "@mcoda/db";
2
+ export type JobState = JobStatus;
3
+ export type CommandRunStatus = CommandStatus;
4
+ export interface CommandRunRecord {
5
+ id: string;
6
+ commandName: string;
7
+ workspaceId: string;
8
+ projectKey?: string;
9
+ jobId?: string;
10
+ taskIds?: string[];
11
+ gitBranch?: string;
12
+ gitBaseBranch?: string;
13
+ startedAt: string;
14
+ completedAt?: string;
15
+ status: CommandRunStatus;
16
+ errorSummary?: string;
17
+ durationSeconds?: number;
18
+ spProcessed?: number | null;
19
+ }
20
+ export interface JobRecord {
21
+ id: string;
22
+ type: string;
23
+ state: JobState;
24
+ jobState?: JobState;
25
+ jobStateDetail?: string;
26
+ commandRunId?: string;
27
+ commandName?: string;
28
+ workspaceId: string;
29
+ projectKey?: string;
30
+ payload?: Record<string, unknown>;
31
+ totalItems?: number;
32
+ processedItems?: number;
33
+ totalUnits?: number;
34
+ completedUnits?: number;
35
+ lastCheckpoint?: string;
36
+ createdAt: string;
37
+ updatedAt: string;
38
+ completedAt?: string;
39
+ errorSummary?: string;
40
+ durationSeconds?: number;
41
+ }
42
+ export interface TokenUsageRecord extends TokenUsageInsert {
43
+ commandName?: string;
44
+ action?: string;
45
+ promptTokens?: number;
46
+ completionTokens?: number;
47
+ costUsd?: number;
48
+ metadata?: Record<string, unknown>;
49
+ }
50
+ export interface JobCheckpoint {
51
+ stage: string;
52
+ timestamp: string;
53
+ details?: Record<string, unknown>;
54
+ }
55
+ export interface JobLogRow {
56
+ timestamp: string;
57
+ sequence?: number | null;
58
+ level?: string | null;
59
+ source?: string | null;
60
+ message?: string | null;
61
+ taskId?: string | null;
62
+ taskKey?: string | null;
63
+ phase?: string | null;
64
+ details?: Record<string, unknown> | null;
65
+ }
66
+ export interface TaskRunSnapshotRow {
67
+ taskId?: string | null;
68
+ taskKey?: string | null;
69
+ status?: string | null;
70
+ startedAt?: string | null;
71
+ finishedAt?: string | null;
72
+ command?: string | null;
73
+ }
74
+ export declare class JobService {
75
+ private workspaceRepo?;
76
+ private checkpointCounters;
77
+ private workspaceRepoInit;
78
+ private telemetryConfig?;
79
+ private telemetryWarningShown;
80
+ private telemetryRemoteWarningShown;
81
+ private perRunTelemetryDisabled;
82
+ private envTelemetryDisabled;
83
+ private requireRepo;
84
+ private workspaceRoot;
85
+ private workspaceId;
86
+ constructor(workspace: string | {
87
+ workspaceRoot: string;
88
+ workspaceId?: string;
89
+ }, workspaceRepo?: WorkspaceRepository | undefined, options?: {
90
+ noTelemetry?: boolean;
91
+ requireRepo?: boolean;
92
+ });
93
+ private get mcodaDir();
94
+ private get commandRunsPath();
95
+ private get jobsStorePath();
96
+ private get tokenUsagePath();
97
+ private jobDir;
98
+ private manifestPath;
99
+ private checkpointDir;
100
+ private logsDir;
101
+ private ensureMcoda;
102
+ private readJsonArray;
103
+ private writeJsonArray;
104
+ private appendJsonArray;
105
+ listJobs(): Promise<JobRecord[]>;
106
+ getJob(jobId: string): Promise<JobRecord | undefined>;
107
+ readCheckpoints(jobId: string): Promise<JobCheckpoint[]>;
108
+ readLog(jobId: string): Promise<string>;
109
+ listJobLogs(jobId: string, options?: {
110
+ since?: string;
111
+ after?: {
112
+ timestamp: string;
113
+ sequence?: number | null;
114
+ };
115
+ }): Promise<JobLogRow[]>;
116
+ summarizeTaskRuns(jobId: string): Promise<TaskRunSnapshotRow[]>;
117
+ startCommandRun(commandName: string, projectKey?: string, options?: {
118
+ gitBranch?: string;
119
+ gitBaseBranch?: string;
120
+ taskIds?: string[];
121
+ jobId?: string;
122
+ }): Promise<CommandRunRecord>;
123
+ finishCommandRun(runId: string, status: CommandRunStatus, errorSummary?: string, spProcessed?: number): Promise<void>;
124
+ startJob(type: string, commandRunId?: string, projectKey?: string, options?: {
125
+ payload?: Record<string, unknown>;
126
+ commandName?: string;
127
+ totalItems?: number;
128
+ processedItems?: number;
129
+ }): Promise<JobRecord>;
130
+ private attachCommandRunToJob;
131
+ updateJobStatus(jobId: string, state: JobState, metadata?: {
132
+ payload?: Record<string, unknown>;
133
+ totalItems?: number;
134
+ processedItems?: number;
135
+ totalUnits?: number;
136
+ completedUnits?: number;
137
+ lastCheckpoint?: string;
138
+ errorSummary?: string;
139
+ [key: string]: unknown;
140
+ }): Promise<void>;
141
+ writeCheckpoint(jobId: string, checkpoint: JobCheckpoint): Promise<void>;
142
+ appendLog(jobId: string, content: string): Promise<void>;
143
+ private readTelemetryConfig;
144
+ private shouldRecordTokenUsage;
145
+ recordTokenUsage(entry: TokenUsageRecord): Promise<void>;
146
+ writeManifest(job: JobRecord, extras?: Record<string, unknown>): Promise<void>;
147
+ close(): Promise<void>;
148
+ }
149
+ //# sourceMappingURL=JobService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobService.d.ts","sourceRoot":"","sources":["../../../src/services/jobs/JobService.ts"],"names":[],"mappings":"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"}