@engineeros/connector 0.4.4 → 0.4.6
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/bin/engineeros-connector.mjs +18 -6
- package/package.json +1 -1
- package/src/runner.mjs +126 -11
|
@@ -147,7 +147,9 @@ async function connect() {
|
|
|
147
147
|
if (message.type === "workspace.assessment") {
|
|
148
148
|
if (
|
|
149
149
|
active?.runId !== message.assessment_id &&
|
|
150
|
-
!assessments.some(
|
|
150
|
+
!assessments.some(
|
|
151
|
+
(candidate) => candidate.assessment_id === message.assessment_id,
|
|
152
|
+
)
|
|
151
153
|
) {
|
|
152
154
|
assessments.push(message);
|
|
153
155
|
}
|
|
@@ -327,7 +329,9 @@ function pump() {
|
|
|
327
329
|
|
|
328
330
|
async function executePrompt(assignment) {
|
|
329
331
|
const promptId = assignment.prompt_id;
|
|
330
|
-
console.log(
|
|
332
|
+
console.log(
|
|
333
|
+
`Answering ${assignment.purpose || "project"} prompt with Codex CLI.`,
|
|
334
|
+
);
|
|
331
335
|
try {
|
|
332
336
|
const result = await executeConnectedPrompt(assignment, config, {
|
|
333
337
|
onProcess: (child) => {
|
|
@@ -366,8 +370,12 @@ async function executeAssessment(assignment) {
|
|
|
366
370
|
const assessmentId = assignment.assessment_id;
|
|
367
371
|
console.log(`Assessing workspace with Codex CLI (${assessmentId}).`);
|
|
368
372
|
let progress = 10;
|
|
369
|
-
const
|
|
370
|
-
|
|
373
|
+
const reportedMilestones = new Set();
|
|
374
|
+
const reportProgress = (message, { milestone = true } = {}) => {
|
|
375
|
+
if (socket.readyState !== WebSocket.OPEN || active?.runId !== assessmentId)
|
|
376
|
+
return;
|
|
377
|
+
if (milestone && reportedMilestones.has(message)) return;
|
|
378
|
+
if (milestone) reportedMilestones.add(message);
|
|
371
379
|
socket.send(
|
|
372
380
|
JSON.stringify({
|
|
373
381
|
type: "workspace.assessment.progress",
|
|
@@ -377,12 +385,16 @@ async function executeAssessment(assignment) {
|
|
|
377
385
|
}),
|
|
378
386
|
);
|
|
379
387
|
};
|
|
380
|
-
reportProgress("
|
|
388
|
+
reportProgress("Starting read-only repository assessment");
|
|
381
389
|
const heartbeat = setInterval(() => {
|
|
382
390
|
progress = Math.min(90, progress + 5);
|
|
383
|
-
reportProgress("
|
|
391
|
+
reportProgress("Assessment in progress", { milestone: false });
|
|
384
392
|
}, 15_000);
|
|
385
393
|
try {
|
|
394
|
+
if (assignment.assessment_mode === "incremental") {
|
|
395
|
+
progress = 15;
|
|
396
|
+
reportProgress("Calculating changed files and affected evidence");
|
|
397
|
+
}
|
|
386
398
|
const result = await executeWorkspaceAssessment(assignment, config, {
|
|
387
399
|
onProcess: (child) => {
|
|
388
400
|
if (active?.runId === assessmentId) active.child = child;
|
package/package.json
CHANGED
package/src/runner.mjs
CHANGED
|
@@ -145,9 +145,23 @@ export async function executeWorkspaceAssessment(
|
|
|
145
145
|
"This workspace is no longer at the commit inventoried by EngineerOS. Refresh the workspace inventory before assessing it.",
|
|
146
146
|
);
|
|
147
147
|
}
|
|
148
|
+
const changeImpact =
|
|
149
|
+
assignment.assessment_mode === "incremental"
|
|
150
|
+
? await workspaceChangeImpact(
|
|
151
|
+
config.workspace,
|
|
152
|
+
assignment.base_head_revision,
|
|
153
|
+
assignment.target_head_revision,
|
|
154
|
+
)
|
|
155
|
+
: { changedFiles: [], markdown: null };
|
|
156
|
+
const prompt = changeImpact.markdown
|
|
157
|
+
? execution.prompt.replace(
|
|
158
|
+
"<!-- ENGINEEROS_CHANGE_IMPACT -->",
|
|
159
|
+
changeImpact.markdown,
|
|
160
|
+
)
|
|
161
|
+
: execution.prompt;
|
|
148
162
|
const controller = launchCodexProcess(
|
|
149
163
|
config.workspace,
|
|
150
|
-
|
|
164
|
+
prompt,
|
|
151
165
|
execution.sandboxMode,
|
|
152
166
|
callbacks,
|
|
153
167
|
);
|
|
@@ -173,9 +187,97 @@ export async function executeWorkspaceAssessment(
|
|
|
173
187
|
return {
|
|
174
188
|
report_markdown: report,
|
|
175
189
|
observed_head_revision: endingHead,
|
|
190
|
+
changed_files: changeImpact.changedFiles,
|
|
191
|
+
change_impact_markdown: changeImpact.markdown,
|
|
176
192
|
};
|
|
177
193
|
}
|
|
178
194
|
|
|
195
|
+
export async function workspaceChangeImpact(workspace, baseRevision, targetRevision) {
|
|
196
|
+
if (!baseRevision || !targetRevision) {
|
|
197
|
+
throw new Error(
|
|
198
|
+
"Incremental assessment requires both the previously assessed and current Git commits. Run a full assessment instead.",
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
const range = `${baseRevision}..${targetRevision}`;
|
|
202
|
+
const names = await run(
|
|
203
|
+
"git",
|
|
204
|
+
["diff", "--name-status", "--find-renames", range],
|
|
205
|
+
workspace,
|
|
206
|
+
{ allowFailure: true },
|
|
207
|
+
);
|
|
208
|
+
if (names.code !== 0) {
|
|
209
|
+
throw new Error(
|
|
210
|
+
"Codex could not compare the assessed and current commits. Fetch the missing Git history or run a full assessment.",
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
const committedFiles = await run(
|
|
214
|
+
"git",
|
|
215
|
+
["-c", "core.quotepath=false", "diff", "--name-only", range],
|
|
216
|
+
workspace,
|
|
217
|
+
{ allowFailure: true },
|
|
218
|
+
);
|
|
219
|
+
const workingFiles = await run(
|
|
220
|
+
"git",
|
|
221
|
+
["-c", "core.quotepath=false", "ls-files", "--others", "--modified", "--deleted", "--exclude-standard"],
|
|
222
|
+
workspace,
|
|
223
|
+
{ allowFailure: true },
|
|
224
|
+
);
|
|
225
|
+
const status = await run("git", ["status", "--short"], workspace, {
|
|
226
|
+
allowFailure: true,
|
|
227
|
+
});
|
|
228
|
+
const stat = await run(
|
|
229
|
+
"git",
|
|
230
|
+
["diff", "--stat", "--compact-summary", range],
|
|
231
|
+
workspace,
|
|
232
|
+
{ allowFailure: true },
|
|
233
|
+
);
|
|
234
|
+
const allChangedFiles = [...new Set([
|
|
235
|
+
...pathLines(committedFiles.stdout),
|
|
236
|
+
...pathLines(workingFiles.stdout),
|
|
237
|
+
])];
|
|
238
|
+
if (allChangedFiles.length > 500) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
`This change affects ${allChangedFiles.length} paths, above the 500-path incremental limit. Run a full reassessment instead.`,
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
const changedFiles = allChangedFiles;
|
|
244
|
+
if (!changedFiles.length) {
|
|
245
|
+
throw new Error(
|
|
246
|
+
"The inventoried repository changed but Git reports no assessable paths. Refresh inventory or run a full assessment.",
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
const lines = [
|
|
250
|
+
`Comparison: \`${range}\``,
|
|
251
|
+
`Changed paths: ${changedFiles.length}`,
|
|
252
|
+
"",
|
|
253
|
+
"### Name status",
|
|
254
|
+
"",
|
|
255
|
+
"```text",
|
|
256
|
+
boundedText(names.stdout, 12_000),
|
|
257
|
+
"```",
|
|
258
|
+
];
|
|
259
|
+
if (status.stdout.trim()) {
|
|
260
|
+
lines.push("", "### Working tree", "", "```text", boundedText(status.stdout, 6_000), "```");
|
|
261
|
+
}
|
|
262
|
+
if (stat.stdout.trim()) {
|
|
263
|
+
lines.push("", "### Diff summary", "", "```text", boundedText(stat.stdout, 6_000), "```");
|
|
264
|
+
}
|
|
265
|
+
return { changedFiles, markdown: lines.join("\n") };
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function pathLines(output) {
|
|
269
|
+
return String(output || "")
|
|
270
|
+
.split(/\r?\n/)
|
|
271
|
+
.map((line) => line.trim())
|
|
272
|
+
.filter(Boolean)
|
|
273
|
+
.map((line) => line.replace(/^"|"$/g, ""));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function boundedText(value, maximum) {
|
|
277
|
+
const text = String(value || "").trim();
|
|
278
|
+
return text.length <= maximum ? text : `${text.slice(0, maximum)}\n... truncated by EngineerOS`;
|
|
279
|
+
}
|
|
280
|
+
|
|
179
281
|
export async function executeConnectedPrompt(assignment, config, callbacks) {
|
|
180
282
|
const execution = connectorExecution(assignment);
|
|
181
283
|
const controller = launchCodexProcess(
|
|
@@ -229,32 +331,45 @@ export function codexFailureMessage(output, code) {
|
|
|
229
331
|
export function assessmentProgressMessage(event) {
|
|
230
332
|
if (!event || typeof event !== "object") return null;
|
|
231
333
|
if (event.type === "turn.started")
|
|
232
|
-
return "
|
|
334
|
+
return "Reviewing repository structure and current Git state";
|
|
233
335
|
if (event.type === "item.started") {
|
|
234
336
|
if (event.item?.type === "command_execution") {
|
|
235
|
-
|
|
236
|
-
return command
|
|
237
|
-
? `Inspecting with ${command}`
|
|
238
|
-
: "Inspecting repository files";
|
|
337
|
+
return assessmentCommandMilestone(event.item.command);
|
|
239
338
|
}
|
|
240
339
|
if (event.item?.type === "mcp_tool_call")
|
|
241
|
-
return "
|
|
340
|
+
return "Tracing architecture and code relationships";
|
|
242
341
|
if (event.item?.type === "web_search")
|
|
243
342
|
return "Checking an external technical reference";
|
|
244
343
|
return null;
|
|
245
344
|
}
|
|
246
345
|
if (event.type === "item.completed" && event.item?.type === "agent_message") {
|
|
247
|
-
return "
|
|
346
|
+
return "Synthesizing findings and highest-return actions";
|
|
248
347
|
}
|
|
249
348
|
return null;
|
|
250
349
|
}
|
|
251
350
|
|
|
252
|
-
function
|
|
351
|
+
function assessmentCommandMilestone(command) {
|
|
253
352
|
const value = Array.isArray(command)
|
|
254
353
|
? command.join(" ")
|
|
255
354
|
: String(command || "");
|
|
256
|
-
const
|
|
257
|
-
|
|
355
|
+
const normalized = value.replace(/\s+/g, " ").trim().toLowerCase();
|
|
356
|
+
if (!normalized) return "Inspecting repository evidence";
|
|
357
|
+
if (/\bgit\s+(status|log|diff|show|rev-parse)\b/.test(normalized)) {
|
|
358
|
+
return "Comparing Git history and workspace changes";
|
|
359
|
+
}
|
|
360
|
+
if (
|
|
361
|
+
/\b(test|pytest|vitest|jest|ruff|eslint|tsc|build|lint)\b/.test(normalized)
|
|
362
|
+
) {
|
|
363
|
+
return "Checking verification and delivery signals";
|
|
364
|
+
}
|
|
365
|
+
if (
|
|
366
|
+
/\b(audit|dependency|dependencies|lockfile|package-lock|pnpm-lock|requirements)\b/.test(
|
|
367
|
+
normalized,
|
|
368
|
+
)
|
|
369
|
+
) {
|
|
370
|
+
return "Reviewing dependencies and security signals";
|
|
371
|
+
}
|
|
372
|
+
return "Tracing architecture and code relationships";
|
|
258
373
|
}
|
|
259
374
|
|
|
260
375
|
export function connectorExecution(assignment) {
|