@engineeros/connector 0.12.5 → 0.13.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/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. EngineerOS stores the source-cited findings in System State and promotes the highest-return corrective action in Steering. 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 Architecture, Capabilities, Quality, or any combination when only part of the workspace needs reassessment. EngineerOS stores every completed assessment stage before starting the next one, resumes the unfinished stage after a connector restart or retry, and then synthesizes the selected results into System State. Capabilities are assessed one discovered capability at a time so a large repository does not depend on one unbounded agent turn. 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
 
@@ -276,9 +276,12 @@ async function connect() {
276
276
  }
277
277
  if (message.type === "workspace.assessment") {
278
278
  if (
279
- active?.runId !== message.assessment_id &&
279
+ (active?.runId !== message.assessment_id ||
280
+ active?.stage !== message.stage) &&
280
281
  !assessments.some(
281
- (candidate) => candidate.assessment_id === message.assessment_id,
282
+ (candidate) =>
283
+ candidate.assessment_id === message.assessment_id &&
284
+ candidate.stage === message.stage,
282
285
  )
283
286
  ) {
284
287
  assessments.push(message);
@@ -463,6 +466,7 @@ function pump() {
463
466
  active = {
464
467
  kind: "assessment",
465
468
  runId: assessment.assessment_id,
469
+ stage: assessment.stage,
466
470
  child: null,
467
471
  };
468
472
  void executeAssessment(assessment);
@@ -577,14 +581,19 @@ async function cancelPrompt(promptState) {
577
581
 
578
582
  async function executeAssessment(assignment) {
579
583
  const assessmentId = assignment.assessment_id;
580
- console.log(`Agent is assessing the workspace (${assessmentId}).`);
584
+ const stage = assignment.stage;
585
+ console.log(`Agent is running assessment stage ${stage} (${assessmentId}).`);
581
586
  let progress = 10;
582
587
  let outputBuffer = "";
583
588
  let outputLength = 0;
584
589
  let outputTimer;
585
590
  const reportedMilestones = new Set();
586
591
  const reportProgress = (message, { milestone = true } = {}) => {
587
- if (socket.readyState !== WebSocket.OPEN || active?.runId !== assessmentId)
592
+ if (
593
+ socket.readyState !== WebSocket.OPEN ||
594
+ active?.runId !== assessmentId ||
595
+ active?.stage !== stage
596
+ )
588
597
  return;
589
598
  if (milestone && reportedMilestones.has(message)) return;
590
599
  if (milestone) reportedMilestones.add(message);
@@ -592,6 +601,7 @@ async function executeAssessment(assignment) {
592
601
  JSON.stringify({
593
602
  type: "workspace.assessment.progress",
594
603
  assessment_id: assessmentId,
604
+ stage,
595
605
  progress_percent: progress,
596
606
  message: String(message).slice(0, 500),
597
607
  }),
@@ -605,7 +615,8 @@ async function executeAssessment(assignment) {
605
615
  if (
606
616
  !output ||
607
617
  socket.readyState !== WebSocket.OPEN ||
608
- active?.runId !== assessmentId
618
+ active?.runId !== assessmentId ||
619
+ active?.stage !== stage
609
620
  ) {
610
621
  return;
611
622
  }
@@ -614,6 +625,7 @@ async function executeAssessment(assignment) {
614
625
  JSON.stringify({
615
626
  type: "workspace.assessment.output",
616
627
  assessment_id: assessmentId,
628
+ stage,
617
629
  delta: output.slice(offset, offset + 50_000),
618
630
  }),
619
631
  );
@@ -631,7 +643,7 @@ async function executeAssessment(assignment) {
631
643
  outputTimer = setTimeout(flushOutput, 500);
632
644
  }
633
645
  };
634
- reportProgress("Starting read-only repository assessment");
646
+ reportProgress(`Starting ${stage} assessment stage`);
635
647
  const heartbeat = setInterval(() => {
636
648
  progress = Math.min(90, progress + 5);
637
649
  reportProgress("Assessment in progress", { milestone: false });
@@ -643,7 +655,9 @@ async function executeAssessment(assignment) {
643
655
  }
644
656
  const result = await executeWorkspaceAssessment(assignment, config, {
645
657
  onProcess: (child) => {
646
- if (active?.runId === assessmentId) active.child = child;
658
+ if (active?.runId === assessmentId && active?.stage === stage) {
659
+ active.child = child;
660
+ }
647
661
  },
648
662
  onEvent: (event) => {
649
663
  reportOutput(assessmentStreamDelta(event));
@@ -668,7 +682,7 @@ async function executeAssessment(assignment) {
668
682
  await describeRejectedResponse(response, "the assessment"),
669
683
  );
670
684
  }
671
- console.log("Workspace assessment is current in EngineerOS.");
685
+ console.log(`Workspace assessment stage ${stage} was accepted by EngineerOS.`);
672
686
  } catch (error) {
673
687
  flushOutput();
674
688
  const message = protocolFailureMessage(error);
@@ -677,6 +691,7 @@ async function executeAssessment(assignment) {
677
691
  JSON.stringify({
678
692
  type: "workspace.assessment.failed",
679
693
  assessment_id: assessmentId,
694
+ stage,
680
695
  message,
681
696
  }),
682
697
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@engineeros/connector",
3
- "version": "0.12.5",
3
+ "version": "0.13.0",
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
@@ -414,8 +414,9 @@ export async function executeWorkspaceAssessment(
414
414
  "The Git commit changed during assessment. Refresh the workspace inventory and assess the new commit.",
415
415
  );
416
416
  }
417
- return {
418
- report_markdown: report,
417
+ return {
418
+ stage: assignment.stage,
419
+ report_markdown: report,
419
420
  observed_head_revision: endingHead,
420
421
  changed_files: changeImpact.changedFiles,
421
422
  change_impact_markdown: changeImpact.markdown,
@@ -761,11 +762,22 @@ function assessmentCommandMilestone(command) {
761
762
  return "Tracing architecture and code relationships";
762
763
  }
763
764
 
764
- export function workspaceAssessmentExecution(assignment) {
765
- const requiredOutputHeading =
766
- assignment?.assessment_mode === "incremental"
767
- ? "# Workspace Assessment Delta"
768
- : "# Workspace Assessment";
765
+ export function workspaceAssessmentExecution(assignment) {
766
+ const stage = assignment?.stage;
767
+ const requiredOutputHeading =
768
+ stage === "synthesis"
769
+ ? "# Assessment Stage: Synthesis"
770
+ : stage === "capability_catalog"
771
+ ? "# Assessment Stage: Capability Catalog"
772
+ : String(stage || "").startsWith("capability:")
773
+ ? "# Assessment Stage: Capabilities"
774
+ : `# Assessment Stage: ${String(stage || "").replace(/^./, (value) => value.toUpperCase())}`;
775
+ if (
776
+ !new Set(["architecture", "capability_catalog", "quality", "synthesis"]).has(stage) &&
777
+ !String(stage || "").startsWith("capability:")
778
+ ) {
779
+ throw new Error("EngineerOS assessment assignment has an unsupported stage.");
780
+ }
769
781
  return {
770
782
  ...connectorExecution(assignment, { requiredOutputHeading }),
771
783
  requiredOutputHeading,