@engineeros/connector 0.14.4 → 0.14.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,7 +47,7 @@ npx --yes @engineeros/connector@latest pair PAIRING-CODE --url https://your-engi
47
47
 
48
48
  The connector uploads a bounded ZIP snapshot for a safe file inventory, then stays online for deep assessments, rescans, and Goal Runs. Inventory never executes repository code. It excludes known secrets, dependency directories, build output, compiled binaries, files larger than 5 MB, agent-tool caches, Git metadata, and connector state before upload.
49
49
 
50
- From **Project steering -> Workspace**, run the workspace assessment to use the connected agent subscription already authenticated on that computer. Select any combination of fifteen brownfield assessment domains, collectively covering 133 baseline checks from product and architecture through security, privacy, project-specific compliance, delivery, reliability, governance, and modernization planning. Every domain uses a detailed structured-Markdown contract. EngineerOS stores each completed stage, resumes unfinished work after a connector restart, retry, or temporary connection loss, and then synthesizes the selected results into System State. Connector `0.14.4` runs up to three independent assessment stages for every supported coding-agent protocol, including ACP agents such as OpenCode. The connector owns the worker pool and sends one aggregate heartbeat containing every active worker's phase, progress, last activity, and event count; workers no longer compete to send individual WebSocket progress heartbeats. Live output remains coalesced separately because it is durable report content. Capability detail and project-specific compliance controls fan out after their catalogs, and final synthesis waits for every selected result. Compliance findings describe repository-verifiable engineering readiness and missing external context, never legal compliance or certification. Each result, live output, validation correction, and retry remains independently durable. The connector prints each worker's safe activity and elapsed time every 30 seconds, stops a worker that produces no agent activity for ten minutes instead of waiting indefinitely, and gives an incomplete report one bounded correction turn instead of repeatedly restarting it. Assessment cannot modify the workspace.
50
+ From **Project steering -> Workspace**, run the workspace assessment to use the connected agent subscription already authenticated on that computer. Select any combination of fifteen brownfield assessment domains, collectively covering 133 baseline checks from product and architecture through security, privacy, project-specific compliance, delivery, reliability, governance, and modernization planning. Every domain uses a detailed structured-Markdown contract. EngineerOS stores each completed stage, resumes unfinished work after a connector restart, retry, or temporary connection loss, and then synthesizes the selected results into System State. Connector `0.14.5` runs up to three independent assessment stages for every supported coding-agent protocol. ACP agents such as OpenCode use isolated stage sessions within one persistent coding-agent process, avoiding the CPU and memory spike from launching three full agent runtimes. The connector owns the worker pool and sends one aggregate heartbeat containing every active worker's phase, progress, last activity, and event count; workers no longer compete to send individual WebSocket progress heartbeats. Live output remains coalesced separately because it is durable report content. Capability detail and project-specific compliance controls fan out after their catalogs, and final synthesis waits for every selected result. Compliance findings describe repository-verifiable engineering readiness and missing external context, never legal compliance or certification. Each result, live output, validation correction, and retry remains independently durable. The connector prints each worker's safe activity and elapsed time every 30 seconds, stops a worker that produces no agent activity for ten minutes instead of waiting indefinitely, and gives an incomplete report one bounded correction turn instead of repeatedly restarting it. Assessment cannot modify the workspace.
51
51
 
52
52
  After onboarding, every project prompt is routed to this connection. Copilot, shaping, planning, architecture, and experience generation use the connected agent subscription and workspace context. Interactive prompts run independently from assessments and Goal scheduling. Prompt runs are read-only; only an explicitly registered Goal Run receives workspace-write access. If the connector is offline, EngineerOS asks the user to reconnect instead of silently switching models.
53
53
 
@@ -206,7 +206,7 @@ const ASSESSMENT_WORKER_LIMIT = workspaceAssessmentWorkerLimit(
206
206
  codingAgent.protocol,
207
207
  );
208
208
  console.log(
209
- `Assessment supervisor can run up to ${ASSESSMENT_WORKER_LIMIT} independent ${codingAgent.name} workers.`,
209
+ `Assessment supervisor can run up to ${ASSESSMENT_WORKER_LIMIT} independent ${codingAgent.name} stages.`,
210
210
  );
211
211
  const available = [];
212
212
  const assessments = [];
@@ -506,6 +506,7 @@ function pump() {
506
506
  runId: assessment.assessment_id,
507
507
  stage: assessment.stage,
508
508
  child: null,
509
+ controller: null,
509
510
  resumeAssignment: null,
510
511
  phase: "starting",
511
512
  progressPercent: 5,
@@ -626,6 +627,14 @@ async function cancelPrompt(promptState) {
626
627
  await stopProcess(promptState.child);
627
628
  }
628
629
 
630
+ async function cancelAssessment(assessmentState) {
631
+ if (typeof assessmentState.controller?.cancel === "function") {
632
+ await assessmentState.controller.cancel();
633
+ return;
634
+ }
635
+ await stopProcess(assessmentState.child);
636
+ }
637
+
629
638
  async function executeAssessment(assignment, assessmentState) {
630
639
  const assessmentId = assignment.assessment_id;
631
640
  const stage = assignment.stage;
@@ -722,7 +731,7 @@ async function executeAssessment(assignment, assessmentState) {
722
731
  if (!inactivityFailure && nextInactivityFailure) {
723
732
  inactivityFailure = nextInactivityFailure;
724
733
  console.error(`[assessment:${stage}] ${inactivityFailure}`);
725
- void stopProcess(assessmentState.child);
734
+ void cancelAssessment(assessmentState);
726
735
  return;
727
736
  }
728
737
  if (inactivityFailure) return;
@@ -741,6 +750,9 @@ async function executeAssessment(assignment, assessmentState) {
741
750
  reportProgress("Calculating changed files and affected behavior");
742
751
  }
743
752
  let result = await executeWorkspaceAssessment(assignment, config, {
753
+ onController: (controller) => {
754
+ if (isActiveAssessment()) assessmentState.controller = controller;
755
+ },
744
756
  onProcess: (child) => {
745
757
  if (isActiveAssessment()) {
746
758
  assessmentState.child = child;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@engineeros/connector",
3
- "version": "0.14.4",
3
+ "version": "0.14.5",
4
4
  "description": "Connect a local coding agent to EngineerOS, using ACP when supported.",
5
5
  "private": false,
6
6
  "type": "module",
package/src/runner.mjs CHANGED
@@ -357,6 +357,28 @@ export async function executeWorkspaceAssessment(
357
357
  callbacks,
358
358
  ) {
359
359
  const execution = workspaceAssessmentExecution(assignment);
360
+ const assessmentAcpContext =
361
+ config.agent_protocol === "acp"
362
+ ? {
363
+ persistentAcp: true,
364
+ sessionKey: `assessment:${assignment.assessment_id}:${assignment.stage}`,
365
+ }
366
+ : undefined;
367
+ const launchAssessmentAgent = (turnPrompt, previousSessionId) => {
368
+ const controller = launchAgentProcess(
369
+ config.workspace,
370
+ turnPrompt,
371
+ execution.sandboxMode,
372
+ config,
373
+ callbacks,
374
+ execution.profile,
375
+ previousSessionId,
376
+ assessmentAcpContext,
377
+ );
378
+ callbacks.onController?.(controller);
379
+ callbacks.onProcess?.(controller.child);
380
+ return controller;
381
+ };
360
382
  const startingRevision = await run(
361
383
  "git",
362
384
  ["rev-parse", "HEAD"],
@@ -389,15 +411,7 @@ export async function executeWorkspaceAssessment(
389
411
  changeImpact.markdown,
390
412
  )
391
413
  : execution.prompt;
392
- const controller = launchAgentProcess(
393
- config.workspace,
394
- prompt,
395
- execution.sandboxMode,
396
- config,
397
- callbacks,
398
- execution.profile,
399
- );
400
- callbacks.onProcess?.(controller.child);
414
+ const controller = launchAssessmentAgent(prompt);
401
415
  let completed = await controller.completed;
402
416
  const recovered = await recoverAssessmentStageOutput({
403
417
  completed,
@@ -408,16 +422,10 @@ export async function executeWorkspaceAssessment(
408
422
  type: "assessment.output_correction",
409
423
  message: "The Agent is completing the required stage report structure",
410
424
  });
411
- const correction = launchAgentProcess(
412
- config.workspace,
425
+ const correction = launchAssessmentAgent(
413
426
  correctionPrompt,
414
- execution.sandboxMode,
415
- config,
416
- callbacks,
417
- execution.profile,
418
427
  previousSessionId,
419
428
  );
420
- callbacks.onProcess?.(correction.child);
421
429
  return correction.completed;
422
430
  },
423
431
  });
@@ -457,19 +465,13 @@ export async function executeWorkspaceAssessment(
457
465
  type: "assessment.output_correction",
458
466
  message: "The Agent is correcting the rejected stage report",
459
467
  });
460
- const correction = launchAgentProcess(
461
- config.workspace,
468
+ const correction = launchAssessmentAgent(
462
469
  assessmentRejectionCorrectionPrompt(
463
470
  validationMessage,
464
471
  execution.requiredOutputHeading,
465
472
  ),
466
- execution.sandboxMode,
467
- config,
468
- callbacks,
469
- execution.profile,
470
473
  completed.sessionId,
471
474
  );
472
- callbacks.onProcess?.(correction.child);
473
475
  const corrected = await correction.completed;
474
476
  const correctedReport = normalizeAgentStructuredOutput(
475
477
  corrected.finalMessage,