@cat-factory/orchestration 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/container.d.ts +460 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +657 -0
- package/dist/container.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/board/BoardService.d.ts +125 -0
- package/dist/modules/board/BoardService.d.ts.map +1 -0
- package/dist/modules/board/BoardService.js +496 -0
- package/dist/modules/board/BoardService.js.map +1 -0
- package/dist/modules/board/board.logic.d.ts +17 -0
- package/dist/modules/board/board.logic.d.ts.map +1 -0
- package/dist/modules/board/board.logic.js +51 -0
- package/dist/modules/board/board.logic.js.map +1 -0
- package/dist/modules/boardScan/BoardScanService.d.ts +35 -0
- package/dist/modules/boardScan/BoardScanService.d.ts.map +1 -0
- package/dist/modules/boardScan/BoardScanService.js +91 -0
- package/dist/modules/boardScan/BoardScanService.js.map +1 -0
- package/dist/modules/boardScan/board-scan.logic.d.ts +10 -0
- package/dist/modules/boardScan/board-scan.logic.d.ts.map +1 -0
- package/dist/modules/boardScan/board-scan.logic.js +26 -0
- package/dist/modules/boardScan/board-scan.logic.js.map +1 -0
- package/dist/modules/bootstrap/BootstrapService.d.ts +114 -0
- package/dist/modules/bootstrap/BootstrapService.d.ts.map +1 -0
- package/dist/modules/bootstrap/BootstrapService.js +516 -0
- package/dist/modules/bootstrap/BootstrapService.js.map +1 -0
- package/dist/modules/clarity/ClarityReviewService.d.ts +48 -0
- package/dist/modules/clarity/ClarityReviewService.d.ts.map +1 -0
- package/dist/modules/clarity/ClarityReviewService.js +63 -0
- package/dist/modules/clarity/ClarityReviewService.js.map +1 -0
- package/dist/modules/clarity/clarity.logic.d.ts +36 -0
- package/dist/modules/clarity/clarity.logic.d.ts.map +1 -0
- package/dist/modules/clarity/clarity.logic.js +98 -0
- package/dist/modules/clarity/clarity.logic.js.map +1 -0
- package/dist/modules/estimation/estimate.logic.d.ts +11 -0
- package/dist/modules/estimation/estimate.logic.d.ts.map +1 -0
- package/dist/modules/estimation/estimate.logic.js +37 -0
- package/dist/modules/estimation/estimate.logic.js.map +1 -0
- package/dist/modules/execution/AgentContextBuilder.d.ts +114 -0
- package/dist/modules/execution/AgentContextBuilder.d.ts.map +1 -0
- package/dist/modules/execution/AgentContextBuilder.js +316 -0
- package/dist/modules/execution/AgentContextBuilder.js.map +1 -0
- package/dist/modules/execution/CompanionController.d.ts +60 -0
- package/dist/modules/execution/CompanionController.d.ts.map +1 -0
- package/dist/modules/execution/CompanionController.js +216 -0
- package/dist/modules/execution/CompanionController.js.map +1 -0
- package/dist/modules/execution/ExecutionService.d.ts +874 -0
- package/dist/modules/execution/ExecutionService.d.ts.map +1 -0
- package/dist/modules/execution/ExecutionService.js +2921 -0
- package/dist/modules/execution/ExecutionService.js.map +1 -0
- package/dist/modules/execution/MergeResolver.d.ts +34 -0
- package/dist/modules/execution/MergeResolver.d.ts.map +1 -0
- package/dist/modules/execution/MergeResolver.js +81 -0
- package/dist/modules/execution/MergeResolver.js.map +1 -0
- package/dist/modules/execution/ReviewGateController.d.ts +163 -0
- package/dist/modules/execution/ReviewGateController.d.ts.map +1 -0
- package/dist/modules/execution/ReviewGateController.js +251 -0
- package/dist/modules/execution/ReviewGateController.js.map +1 -0
- package/dist/modules/execution/TesterController.d.ts +61 -0
- package/dist/modules/execution/TesterController.d.ts.map +1 -0
- package/dist/modules/execution/TesterController.js +215 -0
- package/dist/modules/execution/TesterController.js.map +1 -0
- package/dist/modules/execution/advance.d.ts +84 -0
- package/dist/modules/execution/advance.d.ts.map +1 -0
- package/dist/modules/execution/advance.js +2 -0
- package/dist/modules/execution/advance.js.map +1 -0
- package/dist/modules/execution/artifact-review.logic.d.ts +25 -0
- package/dist/modules/execution/artifact-review.logic.d.ts.map +1 -0
- package/dist/modules/execution/artifact-review.logic.js +39 -0
- package/dist/modules/execution/artifact-review.logic.js.map +1 -0
- package/dist/modules/execution/ci.logic.d.ts +101 -0
- package/dist/modules/execution/ci.logic.d.ts.map +1 -0
- package/dist/modules/execution/ci.logic.js +117 -0
- package/dist/modules/execution/ci.logic.js.map +1 -0
- package/dist/modules/execution/drive.d.ts +47 -0
- package/dist/modules/execution/drive.d.ts.map +1 -0
- package/dist/modules/execution/drive.js +112 -0
- package/dist/modules/execution/drive.js.map +1 -0
- package/dist/modules/execution/gates.d.ts +97 -0
- package/dist/modules/execution/gates.d.ts.map +1 -0
- package/dist/modules/execution/gates.js +2 -0
- package/dist/modules/execution/gates.js.map +1 -0
- package/dist/modules/execution/individualVendors.logic.d.ts +22 -0
- package/dist/modules/execution/individualVendors.logic.d.ts.map +1 -0
- package/dist/modules/execution/individualVendors.logic.js +33 -0
- package/dist/modules/execution/individualVendors.logic.js.map +1 -0
- package/dist/modules/execution/job.logic.d.ts +52 -0
- package/dist/modules/execution/job.logic.d.ts.map +1 -0
- package/dist/modules/execution/job.logic.js +56 -0
- package/dist/modules/execution/job.logic.js.map +1 -0
- package/dist/modules/execution/release.logic.d.ts +43 -0
- package/dist/modules/execution/release.logic.d.ts.map +1 -0
- package/dist/modules/execution/release.logic.js +49 -0
- package/dist/modules/execution/release.logic.js.map +1 -0
- package/dist/modules/execution/retry.logic.d.ts +40 -0
- package/dist/modules/execution/retry.logic.d.ts.map +1 -0
- package/dist/modules/execution/retry.logic.js +83 -0
- package/dist/modules/execution/retry.logic.js.map +1 -0
- package/dist/modules/execution/stepGating.logic.d.ts +15 -0
- package/dist/modules/execution/stepGating.logic.d.ts.map +1 -0
- package/dist/modules/execution/stepGating.logic.js +29 -0
- package/dist/modules/execution/stepGating.logic.js.map +1 -0
- package/dist/modules/execution/stepResolvers.d.ts +41 -0
- package/dist/modules/execution/stepResolvers.d.ts.map +1 -0
- package/dist/modules/execution/stepResolvers.js +2 -0
- package/dist/modules/execution/stepResolvers.js.map +1 -0
- package/dist/modules/execution/tester-infra.logic.d.ts +42 -0
- package/dist/modules/execution/tester-infra.logic.d.ts.map +1 -0
- package/dist/modules/execution/tester-infra.logic.js +46 -0
- package/dist/modules/execution/tester-infra.logic.js.map +1 -0
- package/dist/modules/merge/MergePresetService.d.ts +32 -0
- package/dist/modules/merge/MergePresetService.d.ts.map +1 -0
- package/dist/modules/merge/MergePresetService.js +109 -0
- package/dist/modules/merge/MergePresetService.js.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsService.d.ts +22 -0
- package/dist/modules/modelDefaults/ModelDefaultsService.d.ts.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsService.js +28 -0
- package/dist/modules/modelDefaults/ModelDefaultsService.js.map +1 -0
- package/dist/modules/notifications/NotificationService.d.ts +74 -0
- package/dist/modules/notifications/NotificationService.d.ts.map +1 -0
- package/dist/modules/notifications/NotificationService.js +131 -0
- package/dist/modules/notifications/NotificationService.js.map +1 -0
- package/dist/modules/observability/LlmObservabilityService.d.ts +121 -0
- package/dist/modules/observability/LlmObservabilityService.d.ts.map +1 -0
- package/dist/modules/observability/LlmObservabilityService.js +140 -0
- package/dist/modules/observability/LlmObservabilityService.js.map +1 -0
- package/dist/modules/observability/observability.logic.d.ts +57 -0
- package/dist/modules/observability/observability.logic.d.ts.map +1 -0
- package/dist/modules/observability/observability.logic.js +186 -0
- package/dist/modules/observability/observability.logic.js.map +1 -0
- package/dist/modules/pipelines/PipelineService.d.ts +54 -0
- package/dist/modules/pipelines/PipelineService.d.ts.map +1 -0
- package/dist/modules/pipelines/PipelineService.js +226 -0
- package/dist/modules/pipelines/PipelineService.js.map +1 -0
- package/dist/modules/pipelines/pipelineShape.d.ts +53 -0
- package/dist/modules/pipelines/pipelineShape.d.ts.map +1 -0
- package/dist/modules/pipelines/pipelineShape.js +74 -0
- package/dist/modules/pipelines/pipelineShape.js.map +1 -0
- package/dist/modules/recurring/RecurringPipelineService.d.ts +76 -0
- package/dist/modules/recurring/RecurringPipelineService.d.ts.map +1 -0
- package/dist/modules/recurring/RecurringPipelineService.js +295 -0
- package/dist/modules/recurring/RecurringPipelineService.js.map +1 -0
- package/dist/modules/recurring/TrackerSettingsService.d.ts +16 -0
- package/dist/modules/recurring/TrackerSettingsService.d.ts.map +1 -0
- package/dist/modules/recurring/TrackerSettingsService.js +30 -0
- package/dist/modules/recurring/TrackerSettingsService.js.map +1 -0
- package/dist/modules/recurring/schedule.logic.d.ts +14 -0
- package/dist/modules/recurring/schedule.logic.d.ts.map +1 -0
- package/dist/modules/recurring/schedule.logic.js +85 -0
- package/dist/modules/recurring/schedule.logic.js.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthService.d.ts +38 -0
- package/dist/modules/releaseHealth/ReleaseHealthService.d.ts.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthService.js +96 -0
- package/dist/modules/releaseHealth/ReleaseHealthService.js.map +1 -0
- package/dist/modules/requirements/RequirementReviewService.d.ts +48 -0
- package/dist/modules/requirements/RequirementReviewService.d.ts.map +1 -0
- package/dist/modules/requirements/RequirementReviewService.js +83 -0
- package/dist/modules/requirements/RequirementReviewService.js.map +1 -0
- package/dist/modules/requirements/requirements.logic.d.ts +93 -0
- package/dist/modules/requirements/requirements.logic.d.ts.map +1 -0
- package/dist/modules/requirements/requirements.logic.js +203 -0
- package/dist/modules/requirements/requirements.logic.js.map +1 -0
- package/dist/modules/review/IterativeReviewService.d.ts +175 -0
- package/dist/modules/review/IterativeReviewService.d.ts.map +1 -0
- package/dist/modules/review/IterativeReviewService.js +327 -0
- package/dist/modules/review/IterativeReviewService.js.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.d.ts +20 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.d.ts.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.js +26 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.js.map +1 -0
- package/dist/modules/services/ServiceMountService.d.ts +48 -0
- package/dist/modules/services/ServiceMountService.d.ts.map +1 -0
- package/dist/modules/services/ServiceMountService.js +90 -0
- package/dist/modules/services/ServiceMountService.js.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsService.d.ts +22 -0
- package/dist/modules/settings/WorkspaceSettingsService.d.ts.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsService.js +50 -0
- package/dist/modules/settings/WorkspaceSettingsService.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
import { assertFound, ConflictError, getErrorMessage, sameSubtasks } from '@cat-factory/kernel';
|
|
2
|
+
import { registerServiceForFrame, requireWorkspace } from '@cat-factory/kernel';
|
|
3
|
+
function toReferenceArchitecture(record) {
|
|
4
|
+
return {
|
|
5
|
+
id: record.id,
|
|
6
|
+
workspaceId: record.workspaceId,
|
|
7
|
+
name: record.name,
|
|
8
|
+
description: record.description,
|
|
9
|
+
repoOwner: record.repoOwner,
|
|
10
|
+
repoName: record.repoName,
|
|
11
|
+
defaultInstructions: record.defaultInstructions,
|
|
12
|
+
createdAt: record.createdAt,
|
|
13
|
+
updatedAt: record.updatedAt,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function toBootstrapJob(record) {
|
|
17
|
+
return {
|
|
18
|
+
id: record.id,
|
|
19
|
+
workspaceId: record.workspaceId,
|
|
20
|
+
referenceArchitectureId: record.referenceArchitectureId,
|
|
21
|
+
referenceArchitectureName: record.referenceArchitectureName,
|
|
22
|
+
repoName: record.repoName,
|
|
23
|
+
repoOwner: record.repoOwner,
|
|
24
|
+
repoUrl: record.repoUrl,
|
|
25
|
+
instructions: record.instructions,
|
|
26
|
+
status: record.status,
|
|
27
|
+
blockId: record.blockId,
|
|
28
|
+
subtasks: record.subtasks,
|
|
29
|
+
error: record.error,
|
|
30
|
+
failure: record.failure,
|
|
31
|
+
createdAt: record.createdAt,
|
|
32
|
+
updatedAt: record.updatedAt,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Join the reference architecture's default instructions with per-run extras. */
|
|
36
|
+
function composeInstructions(defaults, extra) {
|
|
37
|
+
return [defaults.trim(), extra.trim()].filter((part) => part.length > 0).join('\n\n');
|
|
38
|
+
}
|
|
39
|
+
export class BootstrapService {
|
|
40
|
+
deps;
|
|
41
|
+
constructor(deps) {
|
|
42
|
+
this.deps = deps;
|
|
43
|
+
}
|
|
44
|
+
/** True when a bootstrap run can actually be performed (the bootstrapper is wired). */
|
|
45
|
+
get canBootstrap() {
|
|
46
|
+
return this.deps.repoBootstrapper !== undefined;
|
|
47
|
+
}
|
|
48
|
+
// ---- reference architecture management ----------------------------------
|
|
49
|
+
async listReferenceArchitectures(workspaceId) {
|
|
50
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
51
|
+
const records = await this.deps.referenceArchitectureRepository.listByWorkspace(workspaceId);
|
|
52
|
+
return records.map(toReferenceArchitecture);
|
|
53
|
+
}
|
|
54
|
+
async createReferenceArchitecture(workspaceId, input) {
|
|
55
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
56
|
+
const now = this.deps.clock.now();
|
|
57
|
+
const record = {
|
|
58
|
+
id: this.deps.idGenerator.next('refarch'),
|
|
59
|
+
workspaceId,
|
|
60
|
+
name: input.name,
|
|
61
|
+
description: input.description,
|
|
62
|
+
repoOwner: input.repoOwner,
|
|
63
|
+
repoName: input.repoName,
|
|
64
|
+
defaultInstructions: input.defaultInstructions,
|
|
65
|
+
createdAt: now,
|
|
66
|
+
updatedAt: now,
|
|
67
|
+
deletedAt: null,
|
|
68
|
+
};
|
|
69
|
+
await this.deps.referenceArchitectureRepository.insert(record);
|
|
70
|
+
return toReferenceArchitecture(record);
|
|
71
|
+
}
|
|
72
|
+
async updateReferenceArchitecture(workspaceId, id, input) {
|
|
73
|
+
const existing = assertFound(await this.deps.referenceArchitectureRepository.get(workspaceId, id), 'Reference architecture', id);
|
|
74
|
+
await this.deps.referenceArchitectureRepository.update(workspaceId, id, {
|
|
75
|
+
...input,
|
|
76
|
+
updatedAt: this.deps.clock.now(),
|
|
77
|
+
});
|
|
78
|
+
return toReferenceArchitecture({ ...existing, ...input, updatedAt: this.deps.clock.now() });
|
|
79
|
+
}
|
|
80
|
+
async deleteReferenceArchitecture(workspaceId, id) {
|
|
81
|
+
assertFound(await this.deps.referenceArchitectureRepository.get(workspaceId, id), 'Reference architecture', id);
|
|
82
|
+
await this.deps.referenceArchitectureRepository.softDelete(workspaceId, id, this.deps.clock.now());
|
|
83
|
+
}
|
|
84
|
+
// ---- bootstrap jobs -----------------------------------------------------
|
|
85
|
+
async listJobs(workspaceId) {
|
|
86
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
87
|
+
// The workspace's own bootstrap runs UNION the runs of every shared service it mounts, so a
|
|
88
|
+
// service bootstrapped on another board shows its live "bootstrapping…" card here too (the
|
|
89
|
+
// run is one row that fires once per org). Dedup by id. No mount repo → own runs only.
|
|
90
|
+
const seen = new Set();
|
|
91
|
+
const out = [];
|
|
92
|
+
const add = (record) => {
|
|
93
|
+
if (seen.has(record.id))
|
|
94
|
+
return;
|
|
95
|
+
seen.add(record.id);
|
|
96
|
+
out.push(toBootstrapJob(record));
|
|
97
|
+
};
|
|
98
|
+
for (const record of await this.deps.bootstrapJobRepository.listByWorkspace(workspaceId)) {
|
|
99
|
+
add(record);
|
|
100
|
+
}
|
|
101
|
+
if (this.deps.workspaceMountRepository) {
|
|
102
|
+
const mounts = await this.deps.workspaceMountRepository.listByWorkspace(workspaceId);
|
|
103
|
+
// One batched query for every mounted service's runs (not one round-trip per mount).
|
|
104
|
+
for (const record of await this.deps.bootstrapJobRepository.listByServices(mounts.map((m) => m.serviceId))) {
|
|
105
|
+
add(record);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
async getJob(workspaceId, id) {
|
|
111
|
+
return toBootstrapJob(assertFound(await this.deps.bootstrapJobRepository.get(workspaceId, id), 'Bootstrap job', id));
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Kick off a "bootstrap repo" run and return immediately with the `running`
|
|
115
|
+
* job. The run is asynchronous and observable: it pre-flights GitHub + the
|
|
116
|
+
* target repo, dispatches the bootstrapper container, materialises a provisional
|
|
117
|
+
* **service frame** on the board (so the user sees a "bootstrapping…" card right
|
|
118
|
+
* away), then asks the durable runner to drive the poll loop — which streams
|
|
119
|
+
* live subtask progress and, on success, links the new repo to the frame so it
|
|
120
|
+
* becomes a real, droppable service. On a dispatch/pre-flight failure the job is
|
|
121
|
+
* returned already `failed` (no frame is left behind). Requires {@link canBootstrap}.
|
|
122
|
+
*/
|
|
123
|
+
async bootstrap(workspaceId, input) {
|
|
124
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
125
|
+
const bootstrapper = this.deps.repoBootstrapper;
|
|
126
|
+
if (!bootstrapper) {
|
|
127
|
+
throw new Error('Repository bootstrapping is not configured');
|
|
128
|
+
}
|
|
129
|
+
// Pre-flight: a bootstrap run creates and pushes to a GitHub repo, so the
|
|
130
|
+
// workspace must be connected to GitHub first. Check before recording any job
|
|
131
|
+
// so an unconnected workspace fails fast with a clear 409 instead of leaving a
|
|
132
|
+
// job that immediately fails deep inside the container run.
|
|
133
|
+
if (!(await bootstrapper.isWorkspaceConnected(workspaceId))) {
|
|
134
|
+
throw new ConflictError('Workspace is not connected to GitHub. Install the GitHub App for this workspace before bootstrapping a repository.');
|
|
135
|
+
}
|
|
136
|
+
// A reference architecture is optional: when supplied the run clones and adapts
|
|
137
|
+
// its base repo; when omitted the run scaffolds a new repo from the freeform
|
|
138
|
+
// instructions alone. The contract guarantees at least one is present.
|
|
139
|
+
const reference = input.referenceArchitectureId
|
|
140
|
+
? assertFound(await this.deps.referenceArchitectureRepository.get(workspaceId, input.referenceArchitectureId), 'Reference architecture', input.referenceArchitectureId)
|
|
141
|
+
: null;
|
|
142
|
+
const instructions = composeInstructions(reference?.defaultInstructions ?? '', input.instructions);
|
|
143
|
+
const now = this.deps.clock.now();
|
|
144
|
+
const record = {
|
|
145
|
+
id: this.deps.idGenerator.next('boot'),
|
|
146
|
+
workspaceId,
|
|
147
|
+
referenceArchitectureId: reference?.id ?? null,
|
|
148
|
+
referenceArchitectureName: reference?.name ?? null,
|
|
149
|
+
repoName: input.repoName,
|
|
150
|
+
repoOwner: null,
|
|
151
|
+
repoUrl: null,
|
|
152
|
+
instructions,
|
|
153
|
+
status: 'running',
|
|
154
|
+
blockId: null,
|
|
155
|
+
subtasks: null,
|
|
156
|
+
error: null,
|
|
157
|
+
failure: null,
|
|
158
|
+
createdAt: now,
|
|
159
|
+
updatedAt: now,
|
|
160
|
+
};
|
|
161
|
+
await this.deps.bootstrapJobRepository.insert(record);
|
|
162
|
+
// Dispatch the container first: its pre-flight (target exists, reachable,
|
|
163
|
+
// empty-or-boilerplate) is the gate that most runs fail on, so failing here
|
|
164
|
+
// before creating a board frame keeps the board clean on the common errors.
|
|
165
|
+
try {
|
|
166
|
+
await bootstrapper.startBootstrap({
|
|
167
|
+
workspaceId,
|
|
168
|
+
jobId: record.id,
|
|
169
|
+
referenceRepo: reference
|
|
170
|
+
? { owner: reference.repoOwner, name: reference.repoName }
|
|
171
|
+
: undefined,
|
|
172
|
+
target: {
|
|
173
|
+
name: input.repoName,
|
|
174
|
+
description: input.description,
|
|
175
|
+
private: input.private,
|
|
176
|
+
},
|
|
177
|
+
instructions,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
const message = getErrorMessage(error);
|
|
182
|
+
// A dispatch HTTP/network fault is `dispatch`; everything else here is a
|
|
183
|
+
// pre-flight rejection (repo missing / not empty / not connected).
|
|
184
|
+
const kind = /dispatch failed/i.test(message) ? 'dispatch' : 'preflight';
|
|
185
|
+
const failure = this.buildFailure(kind, message, null, null);
|
|
186
|
+
const patch = {
|
|
187
|
+
status: 'failed',
|
|
188
|
+
error: message,
|
|
189
|
+
failure,
|
|
190
|
+
updatedAt: this.deps.clock.now(),
|
|
191
|
+
};
|
|
192
|
+
await this.deps.bootstrapJobRepository.update(workspaceId, record.id, patch);
|
|
193
|
+
// A failed dispatch may still have spun a container up; reclaim it best-effort.
|
|
194
|
+
await this.stopContainer(workspaceId, record.id);
|
|
195
|
+
const failed = toBootstrapJob({ ...record, ...patch });
|
|
196
|
+
await this.emitBootstrap(workspaceId, failed, null);
|
|
197
|
+
return failed;
|
|
198
|
+
}
|
|
199
|
+
// Accepted: materialise the provisional service frame and record it on the job
|
|
200
|
+
// so the board shows a live "bootstrapping…" card the poll loop then updates.
|
|
201
|
+
const frame = await this.createServiceFrame(workspaceId, input.repoName);
|
|
202
|
+
const started = { blockId: frame.id, updatedAt: this.deps.clock.now() };
|
|
203
|
+
await this.deps.bootstrapJobRepository.update(workspaceId, record.id, started);
|
|
204
|
+
const job = toBootstrapJob({ ...record, ...started });
|
|
205
|
+
// Hand off the long poll loop to the durable driver (the worker's
|
|
206
|
+
// BootstrapWorkflow). Without a runner (tests) the caller polls directly.
|
|
207
|
+
await this.deps.bootstrapRunner?.startRun(workspaceId, record.id);
|
|
208
|
+
await this.emitBootstrap(workspaceId, job, frame);
|
|
209
|
+
return job;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Retry a failed "bootstrap repo" run. Spins a **fresh** container (and a new
|
|
213
|
+
* durable driver instance) for the same target, reusing the original job's
|
|
214
|
+
* service frame so the board card stays put — it flips from the failed badge
|
|
215
|
+
* back to "bootstrapping…". A new job record is created (the prior one is kept as
|
|
216
|
+
* history and so the durable driver, keyed by job id, gets a clean instance).
|
|
217
|
+
* Only a `failed` job can be retried. Returns the new running job.
|
|
218
|
+
*/
|
|
219
|
+
async retry(workspaceId, jobId) {
|
|
220
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
221
|
+
const bootstrapper = this.deps.repoBootstrapper;
|
|
222
|
+
if (!bootstrapper)
|
|
223
|
+
throw new Error('Repository bootstrapping is not configured');
|
|
224
|
+
const previous = assertFound(await this.deps.bootstrapJobRepository.get(workspaceId, jobId), 'Bootstrap job', jobId);
|
|
225
|
+
if (previous.status !== 'failed') {
|
|
226
|
+
throw new ConflictError(`Only a failed bootstrap can be retried (job is '${previous.status}').`);
|
|
227
|
+
}
|
|
228
|
+
// The original job stored only the reference architecture id, so re-resolve the
|
|
229
|
+
// base repo to clone. If the architecture was since deleted there's nothing to
|
|
230
|
+
// clone from — fail clearly rather than silently scaffolding from scratch.
|
|
231
|
+
let referenceRepo;
|
|
232
|
+
if (previous.referenceArchitectureId) {
|
|
233
|
+
const reference = await this.deps.referenceArchitectureRepository.get(workspaceId, previous.referenceArchitectureId);
|
|
234
|
+
if (!reference) {
|
|
235
|
+
throw new ConflictError(`The reference architecture this run was based on no longer exists; recreate it or start a new bootstrap.`);
|
|
236
|
+
}
|
|
237
|
+
referenceRepo = { owner: reference.repoOwner, name: reference.repoName };
|
|
238
|
+
}
|
|
239
|
+
const now = this.deps.clock.now();
|
|
240
|
+
const record = {
|
|
241
|
+
id: this.deps.idGenerator.next('boot'),
|
|
242
|
+
workspaceId,
|
|
243
|
+
referenceArchitectureId: previous.referenceArchitectureId,
|
|
244
|
+
referenceArchitectureName: previous.referenceArchitectureName,
|
|
245
|
+
repoName: previous.repoName,
|
|
246
|
+
repoOwner: null,
|
|
247
|
+
repoUrl: null,
|
|
248
|
+
// `instructions` is already the composed brief from the original run — reuse
|
|
249
|
+
// it verbatim (don't re-compose, which would double the reference defaults).
|
|
250
|
+
instructions: previous.instructions,
|
|
251
|
+
status: 'running',
|
|
252
|
+
blockId: null,
|
|
253
|
+
subtasks: null,
|
|
254
|
+
error: null,
|
|
255
|
+
failure: null,
|
|
256
|
+
createdAt: now,
|
|
257
|
+
updatedAt: now,
|
|
258
|
+
};
|
|
259
|
+
await this.deps.bootstrapJobRepository.insert(record);
|
|
260
|
+
// Dispatch a fresh container under the new job id (description/private aren't
|
|
261
|
+
// forwarded — the target repo already exists — so defaults are harmless).
|
|
262
|
+
try {
|
|
263
|
+
await bootstrapper.startBootstrap({
|
|
264
|
+
workspaceId,
|
|
265
|
+
jobId: record.id,
|
|
266
|
+
referenceRepo,
|
|
267
|
+
target: { name: record.repoName, description: '', private: true },
|
|
268
|
+
instructions: record.instructions,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
const message = getErrorMessage(error);
|
|
273
|
+
const kind = /dispatch failed/i.test(message) ? 'dispatch' : 'preflight';
|
|
274
|
+
const patch = {
|
|
275
|
+
status: 'failed',
|
|
276
|
+
error: message,
|
|
277
|
+
failure: this.buildFailure(kind, message, null, null),
|
|
278
|
+
updatedAt: this.deps.clock.now(),
|
|
279
|
+
};
|
|
280
|
+
await this.deps.bootstrapJobRepository.update(workspaceId, record.id, patch);
|
|
281
|
+
await this.stopContainer(workspaceId, record.id);
|
|
282
|
+
// Re-mark the reused frame blocked (it briefly belonged to this attempt).
|
|
283
|
+
const block = previous.blockId
|
|
284
|
+
? await this.markFrame(workspaceId, previous.blockId, 'blocked', `Bootstrap failed: ${message}`)
|
|
285
|
+
: null;
|
|
286
|
+
const failed = toBootstrapJob({ ...record, blockId: previous.blockId, ...patch });
|
|
287
|
+
await this.deps.bootstrapJobRepository.update(workspaceId, record.id, {
|
|
288
|
+
blockId: previous.blockId,
|
|
289
|
+
});
|
|
290
|
+
await this.emitBootstrap(workspaceId, failed, block);
|
|
291
|
+
return failed;
|
|
292
|
+
}
|
|
293
|
+
// Accepted: reuse the original frame (flip it back to in-progress) so the card
|
|
294
|
+
// stays in place; if the prior run never made one, materialise a fresh frame.
|
|
295
|
+
const frame = previous.blockId
|
|
296
|
+
? await this.markFrame(workspaceId, previous.blockId, 'in_progress', 'Bootstrapping repository… retrying after a failed run.')
|
|
297
|
+
: await this.createServiceFrame(workspaceId, record.repoName);
|
|
298
|
+
const blockId = frame?.id ?? previous.blockId;
|
|
299
|
+
const started = { blockId, updatedAt: this.deps.clock.now() };
|
|
300
|
+
await this.deps.bootstrapJobRepository.update(workspaceId, record.id, started);
|
|
301
|
+
const job = toBootstrapJob({ ...record, ...started });
|
|
302
|
+
await this.deps.bootstrapRunner?.startRun(workspaceId, record.id);
|
|
303
|
+
await this.emitBootstrap(workspaceId, job, frame);
|
|
304
|
+
return job;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Advance one running bootstrap job by polling its container once: stream the
|
|
308
|
+
* latest subtask counts while it runs, and on a terminal outcome finalise the
|
|
309
|
+
* job and its board frame (link the repo + flip to a ready service on success,
|
|
310
|
+
* mark blocked on failure). Idempotent — a job already in a terminal state is
|
|
311
|
+
* returned as-is, so the durable driver's retries/replays are safe. Returns the
|
|
312
|
+
* poll's terminal-ness so the driver knows when to stop.
|
|
313
|
+
*/
|
|
314
|
+
async pollBootstrapJob(workspaceId, jobId) {
|
|
315
|
+
const record = assertFound(await this.deps.bootstrapJobRepository.get(workspaceId, jobId), 'Bootstrap job', jobId);
|
|
316
|
+
if (record.status === 'succeeded')
|
|
317
|
+
return { state: 'done' };
|
|
318
|
+
if (record.status === 'failed')
|
|
319
|
+
return { state: 'failed', error: record.error ?? undefined };
|
|
320
|
+
const bootstrapper = this.deps.repoBootstrapper;
|
|
321
|
+
if (!bootstrapper)
|
|
322
|
+
throw new Error('Repository bootstrapping is not configured');
|
|
323
|
+
const update = await bootstrapper.pollBootstrap({ workspaceId, jobId });
|
|
324
|
+
if (update.state === 'running') {
|
|
325
|
+
// Only persist + push when the counts actually changed, to avoid a write +
|
|
326
|
+
// broadcast on every idle poll.
|
|
327
|
+
if (update.subtasks && !sameSubtasks(record.subtasks, update.subtasks)) {
|
|
328
|
+
const patch = { subtasks: update.subtasks, updatedAt: this.deps.clock.now() };
|
|
329
|
+
await this.deps.bootstrapJobRepository.update(workspaceId, jobId, patch);
|
|
330
|
+
await this.emitBootstrap(workspaceId, toBootstrapJob({ ...record, ...patch }), null);
|
|
331
|
+
}
|
|
332
|
+
return { state: 'running' };
|
|
333
|
+
}
|
|
334
|
+
if (update.state === 'failed') {
|
|
335
|
+
const message = update.error ?? 'Bootstrap failed';
|
|
336
|
+
const failure = this.buildFailure(update.failureKind ?? 'unknown', message, update.detail ?? null, record.subtasks);
|
|
337
|
+
const patch = {
|
|
338
|
+
status: 'failed',
|
|
339
|
+
error: message,
|
|
340
|
+
failure,
|
|
341
|
+
updatedAt: this.deps.clock.now(),
|
|
342
|
+
};
|
|
343
|
+
await this.deps.bootstrapJobRepository.update(workspaceId, jobId, patch);
|
|
344
|
+
// Reclaim the per-run container so a faulted/leaked instance doesn't idle
|
|
345
|
+
// until its sleep timer (best-effort; an evicted container is already gone).
|
|
346
|
+
await this.stopContainer(workspaceId, jobId);
|
|
347
|
+
const block = await this.markFrame(workspaceId, record.blockId, 'blocked', `Bootstrap failed: ${message}`);
|
|
348
|
+
await this.emitBootstrap(workspaceId, toBootstrapJob({ ...record, ...patch }), block);
|
|
349
|
+
return { state: 'failed', error: message };
|
|
350
|
+
}
|
|
351
|
+
// Done: record the repo, link it to the frame (so dropped tasks target it),
|
|
352
|
+
// and flip the frame to a ready, droppable service.
|
|
353
|
+
const outcome = update.outcome;
|
|
354
|
+
if (!outcome)
|
|
355
|
+
throw new Error('Bootstrap reported done without an outcome');
|
|
356
|
+
const patch = {
|
|
357
|
+
status: 'succeeded',
|
|
358
|
+
repoOwner: outcome.owner,
|
|
359
|
+
repoUrl: outcome.repoUrl,
|
|
360
|
+
updatedAt: this.deps.clock.now(),
|
|
361
|
+
};
|
|
362
|
+
await this.deps.bootstrapJobRepository.update(workspaceId, jobId, patch);
|
|
363
|
+
// Reclaim the per-run container on success too (the failure path above already
|
|
364
|
+
// does): a bootstrapped repo otherwise leaves its container to idle out its
|
|
365
|
+
// sleep timer. Best-effort — an evicted/auto-slept container is already gone.
|
|
366
|
+
await this.stopContainer(workspaceId, jobId);
|
|
367
|
+
if (record.blockId) {
|
|
368
|
+
// Best-effort: a failure to link must not flip a successful run to failed —
|
|
369
|
+
// the repo is bootstrapped; the projection reconciles on the next sync.
|
|
370
|
+
try {
|
|
371
|
+
await bootstrapper.linkRepoToBlock(workspaceId, outcome, record.blockId);
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
// swallow — see above
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const block = await this.markFrame(workspaceId, record.blockId, 'ready', `Service bootstrapped from ${outcome.owner}/${outcome.name}. Drop tasks here to implement against it.`);
|
|
378
|
+
await this.emitBootstrap(workspaceId, toBootstrapJob({ ...record, ...patch }), block);
|
|
379
|
+
// Name the service frame so the refresh fans out to every board mounting this service.
|
|
380
|
+
await this.deps.eventPublisher?.boardChanged(workspaceId, 'bootstrap-succeeded', record.blockId);
|
|
381
|
+
// Kick off the initial blueprint run for the new repo (best-effort): it maps
|
|
382
|
+
// the bootstrapped code into the in-repo `blueprints/` folder and reconciles
|
|
383
|
+
// the board from it. A failure here must not flip the successful bootstrap to
|
|
384
|
+
// failed — the repo is live; the user can re-run the mapping.
|
|
385
|
+
if (record.blockId) {
|
|
386
|
+
try {
|
|
387
|
+
await this.deps.onBootstrapSucceeded?.(workspaceId, record.blockId);
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
// swallow — see above
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return { state: 'done' };
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Explicitly stop a *running* bootstrap (the unified `POST /agent-runs/:id/stop`
|
|
397
|
+
* surface): kill its per-run container, tear down the durable driver, then mark
|
|
398
|
+
* the job `failed` (kind `cancelled`) and its service frame `blocked` so the board
|
|
399
|
+
* shows it stopped — with retry — instead of "bootstrapping…" forever. Idempotent:
|
|
400
|
+
* a job already in a terminal state is returned unchanged. `opts.reason`/`opts.kind`
|
|
401
|
+
* let the orphan sweep reuse this with its own wording.
|
|
402
|
+
*/
|
|
403
|
+
async stop(workspaceId, jobId, opts = {}) {
|
|
404
|
+
await requireWorkspace(this.deps.workspaceRepository, workspaceId);
|
|
405
|
+
const record = assertFound(await this.deps.bootstrapJobRepository.get(workspaceId, jobId), 'Bootstrap job', jobId);
|
|
406
|
+
if (record.status === 'succeeded' || record.status === 'failed')
|
|
407
|
+
return toBootstrapJob(record);
|
|
408
|
+
// Kill the per-run container first, then the durable driver, so neither is left
|
|
409
|
+
// running once the job is marked terminal. Both are best-effort/idempotent.
|
|
410
|
+
await this.stopContainer(workspaceId, jobId);
|
|
411
|
+
await this.deps.bootstrapRunner?.cancelRun(workspaceId, jobId);
|
|
412
|
+
const message = opts.reason ?? 'Stopped by the user.';
|
|
413
|
+
const patch = {
|
|
414
|
+
status: 'failed',
|
|
415
|
+
error: message,
|
|
416
|
+
failure: this.buildFailure(opts.kind ?? 'cancelled', message, null, record.subtasks),
|
|
417
|
+
updatedAt: this.deps.clock.now(),
|
|
418
|
+
};
|
|
419
|
+
await this.deps.bootstrapJobRepository.update(workspaceId, jobId, patch);
|
|
420
|
+
const block = await this.markFrame(workspaceId, record.blockId, 'blocked', `Bootstrap stopped: ${message}`);
|
|
421
|
+
await this.emitBootstrap(workspaceId, toBootstrapJob({ ...record, ...patch }), block);
|
|
422
|
+
return toBootstrapJob({ ...record, ...patch });
|
|
423
|
+
}
|
|
424
|
+
// ---- helpers ------------------------------------------------------------
|
|
425
|
+
/** The workspace default fragment ids a new service inherits; empty / never throws. */
|
|
426
|
+
async defaultServiceFragmentIds(workspaceId) {
|
|
427
|
+
if (!this.deps.serviceFragmentDefaultsRepository)
|
|
428
|
+
return [];
|
|
429
|
+
try {
|
|
430
|
+
return await this.deps.serviceFragmentDefaultsRepository.get(workspaceId);
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
return [];
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
/** Create the provisional, in-progress service frame a bootstrap run materialises. */
|
|
437
|
+
async createServiceFrame(workspaceId, repoName) {
|
|
438
|
+
const blocks = await this.deps.blockRepository.listByWorkspace(workspaceId);
|
|
439
|
+
const frames = blocks.filter((b) => b.level === 'frame').length;
|
|
440
|
+
const type = 'service';
|
|
441
|
+
const serviceFragmentIds = await this.defaultServiceFragmentIds(workspaceId);
|
|
442
|
+
const block = {
|
|
443
|
+
id: this.deps.idGenerator.next('blk'),
|
|
444
|
+
title: repoName,
|
|
445
|
+
type,
|
|
446
|
+
description: 'Bootstrapping repository… a container is adapting and pushing the initial commit.',
|
|
447
|
+
// Stagger so a fresh frame doesn't land exactly on an existing one.
|
|
448
|
+
position: { x: 80 + (frames % 5) * 48, y: 80 + (frames % 5) * 48 },
|
|
449
|
+
status: 'in_progress',
|
|
450
|
+
progress: 0,
|
|
451
|
+
dependsOn: [],
|
|
452
|
+
executionId: null,
|
|
453
|
+
level: 'frame',
|
|
454
|
+
parentId: null,
|
|
455
|
+
...(serviceFragmentIds.length ? { serviceFragmentIds } : {}),
|
|
456
|
+
};
|
|
457
|
+
// Register the bootstrapped frame as an account-owned service + mount (no-op when sharing
|
|
458
|
+
// isn't wired), so a bootstrapped service is shareable and its run is service-discoverable.
|
|
459
|
+
const serviceId = await registerServiceForFrame({
|
|
460
|
+
serviceRepository: this.deps.serviceRepository,
|
|
461
|
+
workspaceMountRepository: this.deps.workspaceMountRepository,
|
|
462
|
+
workspaceRepository: this.deps.workspaceRepository,
|
|
463
|
+
idGenerator: this.deps.idGenerator,
|
|
464
|
+
clock: this.deps.clock,
|
|
465
|
+
}, workspaceId, block);
|
|
466
|
+
await this.deps.blockRepository.insert(workspaceId, block, serviceId);
|
|
467
|
+
return block;
|
|
468
|
+
}
|
|
469
|
+
/** Flip a bootstrap's frame to a terminal status + description; null-safe. */
|
|
470
|
+
async markFrame(workspaceId, blockId, status, description) {
|
|
471
|
+
if (!blockId)
|
|
472
|
+
return null;
|
|
473
|
+
const existing = await this.deps.blockRepository.get(workspaceId, blockId);
|
|
474
|
+
if (!existing)
|
|
475
|
+
return null;
|
|
476
|
+
const progress = status === 'ready' ? 1 : existing.progress;
|
|
477
|
+
await this.deps.blockRepository.update(workspaceId, blockId, { status, description, progress });
|
|
478
|
+
return { ...existing, status, description, progress };
|
|
479
|
+
}
|
|
480
|
+
/** Assemble the structured failure diagnostics stored on a faulted job. */
|
|
481
|
+
buildFailure(kind, message, detail, lastSubtasks) {
|
|
482
|
+
return {
|
|
483
|
+
kind,
|
|
484
|
+
message,
|
|
485
|
+
detail,
|
|
486
|
+
hint: FAILURE_HINTS[kind],
|
|
487
|
+
occurredAt: this.deps.clock.now(),
|
|
488
|
+
lastSubtasks: lastSubtasks ?? null,
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
/** Best-effort: reclaim a job's per-run container (never throws). */
|
|
492
|
+
async stopContainer(workspaceId, jobId) {
|
|
493
|
+
try {
|
|
494
|
+
await this.deps.repoBootstrapper?.stopBootstrap({ workspaceId, jobId });
|
|
495
|
+
}
|
|
496
|
+
catch {
|
|
497
|
+
// The container may already be gone (the common case for an eviction); the
|
|
498
|
+
// job is already recorded failed, so a stop failure changes nothing.
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
/** Best-effort push of a bootstrap transition to subscribed clients. */
|
|
502
|
+
async emitBootstrap(workspaceId, job, block) {
|
|
503
|
+
await this.deps.eventPublisher?.bootstrapChanged?.(workspaceId, job, block);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/** A next-step pointer per failure kind, surfaced on the board's failed card. */
|
|
507
|
+
const FAILURE_HINTS = {
|
|
508
|
+
preflight: 'Check the target repository exists under the connected account, is empty (or holds only README/.gitignore/license/AGENTS.md), and that the GitHub App is installed on it. Then retry.',
|
|
509
|
+
dispatch: 'The container could not be reached to start the job. This is usually transient — retry. If it persists, check the Worker logs in the Cloudflare dashboard.',
|
|
510
|
+
evicted: 'The container that was running this job no longer has it — it was evicted, restarted, or crashed before completing. Inspect its stdout/stderr in the Cloudflare dashboard (Workers Observability → container logs, filtered by this job id), then retry to spin a fresh container.',
|
|
511
|
+
timeout: 'A container watchdog fired (no agent activity, or the max run duration was exceeded). Check the container logs for where it stalled, then retry.',
|
|
512
|
+
agent: 'The bootstrapper agent or the git push reported a failure. See the detail below and the container logs, fix the cause if needed, then retry.',
|
|
513
|
+
cancelled: 'You stopped this run; its container was killed. Retry to start it again.',
|
|
514
|
+
unknown: 'See the detail below and the container logs in the Cloudflare dashboard, then retry.',
|
|
515
|
+
};
|
|
516
|
+
//# sourceMappingURL=BootstrapService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BootstrapService.js","sourceRoot":"","sources":["../../../src/modules/bootstrap/BootstrapService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Block, ClarityReview, RequirementReviewItem } from '@cat-factory/kernel';
|
|
2
|
+
import type { ClarityReviewRepository } from '@cat-factory/kernel';
|
|
3
|
+
import { type IterativeReviewDeps, IterativeReviewService, type ReviewCommon, type ReviewRepository } from '../review/IterativeReviewService.js';
|
|
4
|
+
import { type ClarityContext } from './clarity.logic.js';
|
|
5
|
+
export interface ClarityReviewServiceDependencies extends IterativeReviewDeps {
|
|
6
|
+
clarityReviewRepository: ClarityReviewRepository;
|
|
7
|
+
}
|
|
8
|
+
/** The extra per-call input the clarity reviewer threads into its context. */
|
|
9
|
+
interface ClarityContextInput {
|
|
10
|
+
/** An upstream `bug-investigator` step's enriched prose report — the primary triage subject. */
|
|
11
|
+
investigation?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The clarity-review (bug-report triage) agent. A single LLM call triages a block's bug
|
|
15
|
+
* report for fixability and raises findings, humans answer them, and a second LLM call folds
|
|
16
|
+
* the answers into a clarified report. The iterative loop lives in
|
|
17
|
+
* {@link IterativeReviewService}; this class supplies only the bug-report subject (optionally
|
|
18
|
+
* enriched by an investigator), the prompts and the persisted document field
|
|
19
|
+
* (`clarifiedReport`).
|
|
20
|
+
*/
|
|
21
|
+
export declare class ClarityReviewService extends IterativeReviewService<ClarityReview, ClarityContext, ClarityContextInput> {
|
|
22
|
+
protected readonly repository: ReviewRepository<ClarityReview>;
|
|
23
|
+
constructor(deps: ClarityReviewServiceDependencies);
|
|
24
|
+
protected readonly entityName = "Clarity review";
|
|
25
|
+
protected readonly reviewerLabel = "clarity reviewer";
|
|
26
|
+
protected readonly reviewAgentKind = "clarity-review";
|
|
27
|
+
protected readonly reworkAgentKind = "clarity-rework";
|
|
28
|
+
protected readonly reviewSystemPrompt: string;
|
|
29
|
+
protected readonly reworkSystemPrompt: string;
|
|
30
|
+
protected readonly reviewIdPrefix = "clr";
|
|
31
|
+
protected readonly itemIdPrefix = "clri";
|
|
32
|
+
protected readonly revisedNoun = "revised bug report";
|
|
33
|
+
protected readonly truncationMessage: string;
|
|
34
|
+
protected readonly notificationType: 'clarity_review';
|
|
35
|
+
protected readonly notificationSubject = "The clarity reviewer";
|
|
36
|
+
protected notificationTitle(block: Block): string;
|
|
37
|
+
protected buildReviewPrompt(ctx: ClarityContext): string;
|
|
38
|
+
protected buildReworkPrompt(ctx: ClarityContext, items: RequirementReviewItem[]): string;
|
|
39
|
+
protected applyIncorporatedDoc(ctx: ClarityContext, doc: string): void;
|
|
40
|
+
protected applyFeedback(ctx: ClarityContext, feedback: string): void;
|
|
41
|
+
protected readDoc(review: ClarityReview): string | null;
|
|
42
|
+
protected withDoc(review: ClarityReview, doc: string): ClarityReview;
|
|
43
|
+
protected newReview(common: ReviewCommon): ClarityReview;
|
|
44
|
+
/** Assemble the bug report under review (block + optional investigation). */
|
|
45
|
+
protected gatherContext(_workspaceId: string, block: Block, input: ClarityContextInput): Promise<ClarityContext>;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=ClarityReviewService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClarityReviewService.d.ts","sourceRoot":"","sources":["../../../src/modules/clarity/ClarityReviewService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AACtF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAElE,OAAO,EACL,KAAK,mBAAmB,EACxB,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,oBAAoB,CAAA;AAE3B,MAAM,WAAW,gCAAiC,SAAQ,mBAAmB;IAC3E,uBAAuB,EAAE,uBAAuB,CAAA;CACjD;AAED,8EAA8E;AAC9E,UAAU,mBAAmB;IAC3B,gGAAgG;IAChG,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;;;;GAOG;AACH,qBAAa,oBAAqB,SAAQ,sBAAsB,CAC9D,aAAa,EACb,cAAc,EACd,mBAAmB,CACpB;IACC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAA;IAE9D,YAAY,IAAI,EAAE,gCAAgC,EAGjD;IAED,SAAS,CAAC,QAAQ,CAAC,UAAU,oBAAmB;IAChD,SAAS,CAAC,QAAQ,CAAC,aAAa,sBAAqB;IACrD,SAAS,CAAC,QAAQ,CAAC,eAAe,oBAAmB;IACrD,SAAS,CAAC,QAAQ,CAAC,eAAe,oBAAmB;IACrD,SAAS,CAAC,QAAQ,CAAC,kBAAkB,SAA+B;IACpE,SAAS,CAAC,QAAQ,CAAC,kBAAkB,SAA+B;IACpE,SAAS,CAAC,QAAQ,CAAC,cAAc,SAAQ;IACzC,SAAS,CAAC,QAAQ,CAAC,YAAY,UAAS;IACxC,SAAS,CAAC,QAAQ,CAAC,WAAW,wBAAuB;IACrD,SAAS,CAAC,QAAQ,CAAC,iBAAiB,SAE8B;IAClE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAG,gBAAgB,CAAS;IAC/D,SAAS,CAAC,QAAQ,CAAC,mBAAmB,0BAAyB;IAE/D,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEhD;IAED,SAAS,CAAC,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAEvD;IAED,SAAS,CAAC,iBAAiB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,MAAM,CAEvF;IAED,SAAS,CAAC,oBAAoB,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAErE;IAED,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEnE;IAED,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAEtD;IAED,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,CAEnE;IAED,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,aAAa,CAEvD;IAED,6EAA6E;IAC7E,UAAgB,aAAa,CAC3B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,cAAc,CAAC,CAKzB;CACF"}
|