@engineeros/connector 0.8.9 → 0.9.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 +11 -5
- package/package.json +2 -2
- package/src/agent-harness.mjs +108 -0
- package/src/capabilities.mjs +2 -0
- package/src/runner.mjs +22 -4
- package/src/skills/change-planning/SKILL.md +12 -0
- package/src/skills/change-verification/SKILL.md +12 -0
- package/src/skills/codebase-research/SKILL.md +12 -0
- package/src/skills/goal-execution/SKILL.md +12 -0
package/README.md
CHANGED
|
@@ -26,10 +26,16 @@ npx --yes @engineeros/connector@latest pair PAIRING-CODE --url http://localhost:
|
|
|
26
26
|
|
|
27
27
|
Connect a local Codex CLI workspace to EngineerOS through an outbound WebSocket.
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
## Agent roles and skills
|
|
30
|
+
|
|
31
|
+
The selected ACP or Codex agent is the execution engine. EngineerOS chooses a provider-neutral role for each activity and the connector injects only that role's bundled skill:
|
|
32
|
+
|
|
33
|
+
- `research` uses `codebase-research` with read-only access for questions and workspace assessment.
|
|
34
|
+
- `planning` uses `change-planning` with read-only access for shaping, specifications, architecture, and design work.
|
|
35
|
+
- `implementation` uses `goal-execution` with workspace-write access only for a registered Goal.
|
|
36
|
+
- `verification` uses `change-verification` with read-only access for artifact review and independent Goal proof.
|
|
37
|
+
|
|
38
|
+
The connector rejects a role whose access does not match the assignment before starting the agent. Role-specific sessions preserve useful context without mixing planning, research, implementation, or verification responsibilities. A shared interaction contract makes the Agent infer the current project situation, lead with the useful outcome, and suggest one concrete next activity only when it genuinely helps. User-visible responses refer neutrally to the Agent; provider and harness details remain operational metadata.
|
|
33
39
|
|
|
34
40
|
## Onboard a workspace
|
|
35
41
|
|
|
@@ -45,7 +51,7 @@ From **Project steering -> Workspace**, run the workspace assessment to use the
|
|
|
45
51
|
|
|
46
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.
|
|
47
53
|
|
|
48
|
-
Project prompts use resumable, purpose-specific
|
|
54
|
+
Project prompts use resumable, role- and purpose-specific agent sessions. The connector keeps the external session identifiers in its local configuration, so Copilot and artifact conversations survive connector restarts. Changing the role, purpose, model, or reasoning effort starts a separate session. Goal implementation and verification remain isolated runs.
|
|
49
55
|
|
|
50
56
|
An empty or document-only folder establishes a greenfield baseline. A code-bearing folder is assessed as brownfield. Use **Rescan** in Steering after the local workspace changes.
|
|
51
57
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@engineeros/connector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Connect a local coding agent to EngineerOS, using ACP when supported.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"start": "node ./bin/engineeros-connector.mjs",
|
|
18
18
|
"test": "node --test --test-concurrency=1",
|
|
19
|
-
"type-check": "node --check ./bin/engineeros-connector.mjs && node --check ./src/acp-client.mjs && node --check ./src/agent-registry.mjs && node --check ./src/capabilities.mjs && node --check ./src/cli-args.mjs && node --check ./src/config.mjs && node --check ./src/connection.mjs && node --check ./src/mcp-server.mjs && node --check ./src/runner.mjs"
|
|
19
|
+
"type-check": "node --check ./bin/engineeros-connector.mjs && node --check ./src/acp-client.mjs && node --check ./src/agent-harness.mjs && node --check ./src/agent-registry.mjs && node --check ./src/capabilities.mjs && node --check ./src/cli-args.mjs && node --check ./src/config.mjs && node --check ./src/connection.mjs && node --check ./src/mcp-server.mjs && node --check ./src/runner.mjs"
|
|
20
20
|
},
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=22"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
const ROLE_DEFINITIONS = Object.freeze({
|
|
4
|
+
research: Object.freeze({
|
|
5
|
+
title: "Repository Research",
|
|
6
|
+
sandboxMode: "read-only",
|
|
7
|
+
skill: "codebase-research",
|
|
8
|
+
instruction:
|
|
9
|
+
"Investigate the connected workspace deeply enough to answer from observed evidence. Trace relevant relationships, distinguish facts from inference, and do not change the workspace.",
|
|
10
|
+
}),
|
|
11
|
+
planning: Object.freeze({
|
|
12
|
+
title: "Change Planning",
|
|
13
|
+
sandboxMode: "read-only",
|
|
14
|
+
skill: "change-planning",
|
|
15
|
+
instruction:
|
|
16
|
+
"Turn the request and current workspace evidence into a decision-complete change plan. Resolve discoverable questions through inspection, state consequential assumptions, and do not implement the plan.",
|
|
17
|
+
}),
|
|
18
|
+
implementation: Object.freeze({
|
|
19
|
+
title: "Goal Implementation",
|
|
20
|
+
sandboxMode: "workspace-write",
|
|
21
|
+
skill: "goal-execution",
|
|
22
|
+
instruction:
|
|
23
|
+
"Execute the bounded Goal autonomously, keep changes inside its boundary, and verify the result. EngineerOS owns the final commit and acceptance workflow.",
|
|
24
|
+
}),
|
|
25
|
+
verification: Object.freeze({
|
|
26
|
+
title: "Independent Verification",
|
|
27
|
+
sandboxMode: "read-only",
|
|
28
|
+
skill: "change-verification",
|
|
29
|
+
instruction:
|
|
30
|
+
"Independently inspect and test the supplied revision. Report only directly observed evidence and do not repair or otherwise modify the workspace.",
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const skillCache = new Map();
|
|
35
|
+
|
|
36
|
+
export const AGENT_ROLE_IDS = Object.freeze(Object.keys(ROLE_DEFINITIONS));
|
|
37
|
+
export const AGENT_SKILL_IDS = Object.freeze(
|
|
38
|
+
AGENT_ROLE_IDS.map((roleId) => ROLE_DEFINITIONS[roleId].skill),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export function agentHarnessCapabilities() {
|
|
42
|
+
return {
|
|
43
|
+
agent_roles: [...AGENT_ROLE_IDS],
|
|
44
|
+
agent_skills: [...AGENT_SKILL_IDS],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function buildAgentHarnessPrompt({ agentRole, prompt, sandboxMode }) {
|
|
49
|
+
const role = ROLE_DEFINITIONS[agentRole];
|
|
50
|
+
if (!role) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`EngineerOS assignment has an unsupported agent_role. Expected one of: ${AGENT_ROLE_IDS.join(", ")}.`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (role.sandboxMode !== sandboxMode) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`EngineerOS ${agentRole} role requires ${role.sandboxMode} access, but the assignment requested ${sandboxMode}.`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
const assignment = String(prompt || "").trim();
|
|
61
|
+
if (!assignment) {
|
|
62
|
+
throw new Error("EngineerOS assignment is missing prompt_markdown.");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return [
|
|
66
|
+
"# EngineerOS Agent Assignment",
|
|
67
|
+
"",
|
|
68
|
+
"## Active Role",
|
|
69
|
+
"",
|
|
70
|
+
`- Role: ${role.title}`,
|
|
71
|
+
`- Access: ${role.sandboxMode}`,
|
|
72
|
+
`- Responsibility: ${role.instruction}`,
|
|
73
|
+
"- User-facing language: refer to yourself neutrally as the Agent. Do not expose internal role, harness, provider, or coding-agent terminology unless the user asks.",
|
|
74
|
+
"",
|
|
75
|
+
"## Interaction Contract",
|
|
76
|
+
"",
|
|
77
|
+
"- Infer the current project situation from the assignment and workspace evidence before responding.",
|
|
78
|
+
"- Lead with the useful answer or outcome. Do not narrate routine searches, tool calls, or internal work.",
|
|
79
|
+
"- When one next activity clearly follows and would help, offer exactly one short, concrete suggestion. Do not force a next step when none is useful.",
|
|
80
|
+
"- Ask a question only when a consequential choice cannot be resolved from available evidence.",
|
|
81
|
+
"",
|
|
82
|
+
"## Active Skill",
|
|
83
|
+
"",
|
|
84
|
+
bundledSkill(role.skill),
|
|
85
|
+
"",
|
|
86
|
+
"## Assignment",
|
|
87
|
+
"",
|
|
88
|
+
assignment,
|
|
89
|
+
].join("\n");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function bundledSkill(skillName) {
|
|
93
|
+
const cached = skillCache.get(skillName);
|
|
94
|
+
if (cached) return cached;
|
|
95
|
+
try {
|
|
96
|
+
const content = readFileSync(
|
|
97
|
+
new URL(`./skills/${skillName}/SKILL.md`, import.meta.url),
|
|
98
|
+
"utf8",
|
|
99
|
+
).trim();
|
|
100
|
+
skillCache.set(skillName, content);
|
|
101
|
+
return content;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`EngineerOS bundled skill '${skillName}' is unavailable. Reinstall @engineeros/connector.`,
|
|
105
|
+
{ cause: error },
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
}
|
package/src/capabilities.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { agentHarnessCapabilities } from "./agent-harness.mjs";
|
|
2
3
|
|
|
3
4
|
export function advertisedCapabilities(config, codingAgent) {
|
|
4
5
|
const configuredModels = String(
|
|
@@ -15,6 +16,7 @@ export function advertisedCapabilities(config, codingAgent) {
|
|
|
15
16
|
workspace_name: path.basename(config.workspace),
|
|
16
17
|
agent_name: codingAgent.name,
|
|
17
18
|
agent_version: codingAgent.version,
|
|
19
|
+
...agentHarnessCapabilities(),
|
|
18
20
|
execution_profiles: {
|
|
19
21
|
model_selection: codingAgent.protocol === "codex",
|
|
20
22
|
models: codingAgent.protocol === "codex" ? configuredModels : [],
|
package/src/runner.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import path from "node:path";
|
|
|
12
12
|
import { promisify } from "node:util";
|
|
13
13
|
import { deflateRaw } from "node:zlib";
|
|
14
14
|
import { launchAcpAgent } from "./acp-client.mjs";
|
|
15
|
+
import { buildAgentHarnessPrompt } from "./agent-harness.mjs";
|
|
15
16
|
|
|
16
17
|
const deflate = promisify(deflateRaw);
|
|
17
18
|
const MAX_ARCHIVE_BYTES = 25 * 1024 * 1024;
|
|
@@ -117,7 +118,15 @@ export async function executeAssignment(assignment, config, callbacks) {
|
|
|
117
118
|
);
|
|
118
119
|
const verifier = launchAgentProcess(
|
|
119
120
|
runWorkspace,
|
|
120
|
-
|
|
121
|
+
buildAgentHarnessPrompt({
|
|
122
|
+
agentRole: "verification",
|
|
123
|
+
prompt: verificationPrompt(
|
|
124
|
+
assignment,
|
|
125
|
+
committed.revision,
|
|
126
|
+
committed.changedFiles,
|
|
127
|
+
),
|
|
128
|
+
sandboxMode: "read-only",
|
|
129
|
+
}),
|
|
121
130
|
"read-only",
|
|
122
131
|
config,
|
|
123
132
|
callbacks,
|
|
@@ -656,8 +665,8 @@ function assessmentCommandMilestone(command) {
|
|
|
656
665
|
}
|
|
657
666
|
|
|
658
667
|
export function connectorExecution(assignment) {
|
|
659
|
-
const
|
|
660
|
-
if (typeof
|
|
668
|
+
const rawPrompt = assignment?.prompt_markdown;
|
|
669
|
+
if (typeof rawPrompt !== "string" || !rawPrompt.trim()) {
|
|
661
670
|
throw new Error("EngineerOS assignment is missing prompt_markdown.");
|
|
662
671
|
}
|
|
663
672
|
const sandboxMode = assignment?.sandbox_mode;
|
|
@@ -676,14 +685,23 @@ export function connectorExecution(assignment) {
|
|
|
676
685
|
"EngineerOS assignment has an unsupported reasoning effort.",
|
|
677
686
|
);
|
|
678
687
|
}
|
|
688
|
+
const agentRole = assignment?.agent_role;
|
|
689
|
+
const prompt = buildAgentHarnessPrompt({
|
|
690
|
+
agentRole,
|
|
691
|
+
prompt: rawPrompt,
|
|
692
|
+
sandboxMode,
|
|
693
|
+
});
|
|
679
694
|
return {
|
|
680
695
|
prompt,
|
|
696
|
+
agentRole,
|
|
681
697
|
sandboxMode,
|
|
682
698
|
sessionKey:
|
|
683
699
|
typeof assignment.session_key === "string" &&
|
|
684
700
|
assignment.session_key.trim()
|
|
685
701
|
? assignment.session_key.trim()
|
|
686
|
-
: `project-${String(
|
|
702
|
+
: `project-${String(agentRole)}-${String(
|
|
703
|
+
assignment.purpose || "general",
|
|
704
|
+
)
|
|
687
705
|
.toLowerCase()
|
|
688
706
|
.replace(/[^a-z0-9]+/g, "-")
|
|
689
707
|
.slice(0, 80)}`,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: change-planning
|
|
3
|
+
description: Produce a decision-complete implementation plan grounded in the connected repository.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Change Planning
|
|
7
|
+
|
|
8
|
+
1. Inspect current behavior, ownership boundaries, call paths, tests, and project instructions before proposing changes.
|
|
9
|
+
2. Define the intended outcome, affected components, non-goals, risks, and proof of completion.
|
|
10
|
+
3. Resolve questions answerable from the repository. Label only genuinely unavailable facts as assumptions.
|
|
11
|
+
4. Sequence bounded implementation steps with the files or symbols each step affects and the verification it requires.
|
|
12
|
+
5. Stay read-only and hand off a plan that an implementation Agent can execute without rediscovering the problem.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: change-verification
|
|
3
|
+
description: Independently verify a completed change against its explicit proof contract.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Change Verification
|
|
7
|
+
|
|
8
|
+
1. Inspect the exact supplied revision, changed paths, Goal boundaries, constraints, and every Proof item.
|
|
9
|
+
2. Run or inspect each check independently; do not rely on the implementation Agent's claims.
|
|
10
|
+
3. Stay read-only. Do not repair failures, edit files, install dependencies, commit, or push.
|
|
11
|
+
4. Mark a check passed only when directly observed evidence matches its expected result.
|
|
12
|
+
5. Return the requested structured verification report with concise commands, exit codes, and evidence.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codebase-research
|
|
3
|
+
description: Investigate a connected repository and answer from directly observed evidence.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Codebase Research
|
|
7
|
+
|
|
8
|
+
1. Define the exact question and inspect the smallest relevant surface first.
|
|
9
|
+
2. Trace callers, dependencies, data flow, configuration, and tests when they materially affect the answer.
|
|
10
|
+
3. Separate observed facts from inferences and cite concrete repository paths for important claims.
|
|
11
|
+
4. Stay read-only. Do not install, generate, edit, delete, commit, or start long-running services.
|
|
12
|
+
5. Return the answer first, followed by supporting evidence and unresolved gaps only when they matter.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: goal-execution
|
|
3
|
+
description: Implement one bounded EngineerOS Goal and prove the resulting behavior.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Goal Execution
|
|
7
|
+
|
|
8
|
+
1. Read the complete Goal packet, repository instructions, current Git state, and relevant implementation paths.
|
|
9
|
+
2. Implement the smallest coherent change that satisfies the included outcome and constraints.
|
|
10
|
+
3. Preserve unrelated user changes and stay inside the stated boundary; stop only for a genuine missing authority or prerequisite.
|
|
11
|
+
4. Run focused checks while working, then the proportionate final tests, lint, type checks, or build required by the Goal.
|
|
12
|
+
5. Do not commit or push. EngineerOS creates the isolated run commit after the implementation completes.
|