opcrew 0.1.0 → 0.1.2
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 +84 -1
- package/dist/cli.js +251 -0
- package/dist/core/Agent.d.ts +1 -1
- package/dist/crew/Scout.d.ts +2 -0
- package/dist/crew/index.d.ts +3 -2
- package/dist/opencode-plugin.js +12492 -12
- package/dist/tools/edit-logbook.d.ts +32 -0
- package/package.json +6 -3
- package/src/cli/index.ts +0 -70
package/README.md
CHANGED
|
@@ -2,6 +2,75 @@
|
|
|
2
2
|
|
|
3
3
|
Opcrew provides a crew of structured agents and an OpenCode plugin that registers them automatically.
|
|
4
4
|
|
|
5
|
+
## Crew Roles
|
|
6
|
+
|
|
7
|
+
| Agent | Role | Responsibility |
|
|
8
|
+
|-------|------|----------------|
|
|
9
|
+
| **Captain** | Orchestrator | Coordinates, delegates, verifies - never executes directly |
|
|
10
|
+
| **Navigator** | Planner | Charts implementation path, decomposes work, creates todo lists |
|
|
11
|
+
| **Boatswain** | Executor | Executes tasks, writes code, makes file changes |
|
|
12
|
+
| **Quartermaster** | Reviewer | Verifies work, runs tests, ensures quality |
|
|
13
|
+
| **Scout** | Researcher | Gathers external information - libraries, APIs, best practices |
|
|
14
|
+
|
|
15
|
+
## Workflow
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────┐ ┌───────────┐
|
|
19
|
+
│ User │ ──── intent ─────► │ Captain │
|
|
20
|
+
└─────────────┘ └─────┬─────┘
|
|
21
|
+
│
|
|
22
|
+
┌──────────────────────────────┼──────────────────────────────┐
|
|
23
|
+
│ │ │
|
|
24
|
+
│ delegates via task tool │ may summon for research │
|
|
25
|
+
▼ │ ▼
|
|
26
|
+
┌───────────┐ │ ┌───────────┐
|
|
27
|
+
│ Navigator │ ◄───────────────────────┘ │ Scout │
|
|
28
|
+
└─────┬─────┘ may summon for research └───────────┘
|
|
29
|
+
│ ▲
|
|
30
|
+
│ creates plan + todo list │
|
|
31
|
+
│ │
|
|
32
|
+
▼ │
|
|
33
|
+
┌───────────┐ │
|
|
34
|
+
│ Captain │ ◄── reviews plan ─── │
|
|
35
|
+
└─────┬─────┘ │
|
|
36
|
+
│ │
|
|
37
|
+
│ delegates via task tool │
|
|
38
|
+
▼ │
|
|
39
|
+
┌───────────┐ may need research ─────────────────────────┘
|
|
40
|
+
│ Boatswain │
|
|
41
|
+
└─────┬─────┘
|
|
42
|
+
│
|
|
43
|
+
│ executes tasks
|
|
44
|
+
▼
|
|
45
|
+
┌──────────────┐
|
|
46
|
+
│ Quartermaster│
|
|
47
|
+
└──────┬───────┘
|
|
48
|
+
│
|
|
49
|
+
│ verifies & reports
|
|
50
|
+
▼
|
|
51
|
+
┌───────────┐
|
|
52
|
+
│ Captain │
|
|
53
|
+
└───────────┘
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Flow Description
|
|
57
|
+
|
|
58
|
+
1. **Intent** → Captain receives user intent, classifies task type
|
|
59
|
+
2. **Planning** → Captain delegates to Navigator, who creates plan and todo list
|
|
60
|
+
- Navigator may summon Scout for external research (libraries, APIs, docs)
|
|
61
|
+
3. **Review** → Captain reviews Navigator's plan
|
|
62
|
+
4. **Execution** → Captain delegates to Boatswain to execute tasks
|
|
63
|
+
- Boatswain may trigger Scout if implementation requires external info
|
|
64
|
+
5. **Verification** → Captain delegates to Quartermaster for testing/review
|
|
65
|
+
6. **Completion** → Quartermaster reports to Captain
|
|
66
|
+
|
|
67
|
+
### Scout Activation
|
|
68
|
+
|
|
69
|
+
Scout can be summoned by:
|
|
70
|
+
- **Navigator** - During planning to research libraries, frameworks, best practices
|
|
71
|
+
- **Captain** - When external information is needed for decision-making
|
|
72
|
+
- **Boatswain** - During execution if implementation requires API docs or examples
|
|
73
|
+
|
|
5
74
|
## Setup
|
|
6
75
|
|
|
7
76
|
Install dependencies:
|
|
@@ -33,12 +102,26 @@ Publish the package and add it to your OpenCode config:
|
|
|
33
102
|
|
|
34
103
|
```json
|
|
35
104
|
{
|
|
36
|
-
"plugin": ["opcrew@0.1.
|
|
105
|
+
"plugin": ["opcrew@0.1.2"]
|
|
37
106
|
}
|
|
38
107
|
```
|
|
39
108
|
|
|
40
109
|
The plugin entrypoint is `src/opencode-plugin.ts` and the published bundle is `dist/opencode-plugin.js`.
|
|
41
110
|
|
|
111
|
+
## Logbook
|
|
112
|
+
|
|
113
|
+
The crew tracks progress in `.opcrew/logbook.json`:
|
|
114
|
+
|
|
115
|
+
| Section | Purpose |
|
|
116
|
+
|---------|---------|
|
|
117
|
+
| `voyage` | Current session status (idle/active/blocked/completed) |
|
|
118
|
+
| `missions` | Tasks with intent, status, and outcome |
|
|
119
|
+
| `decisions` | Key decisions with rationale |
|
|
120
|
+
| `blockers` | Impediments blocking progress |
|
|
121
|
+
| `notes` | General observations |
|
|
122
|
+
|
|
123
|
+
Use the `edit_logbook` tool to update the logbook.
|
|
124
|
+
|
|
42
125
|
## Knowledge Base
|
|
43
126
|
|
|
44
127
|
Project context lives under `docs/knowledge/`:
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
|
|
4
|
+
// src/cli/index.ts
|
|
5
|
+
import process from "process";
|
|
6
|
+
|
|
7
|
+
// src/cli/install.ts
|
|
8
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
9
|
+
import path from "path";
|
|
10
|
+
|
|
11
|
+
// src/core/Agent.ts
|
|
12
|
+
class OpCrewAgent {
|
|
13
|
+
config;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
compileToMarkdown() {
|
|
18
|
+
const frontmatter = `---
|
|
19
|
+
name: ${this.config.name}
|
|
20
|
+
role: ${this.config.role}
|
|
21
|
+
tools: [${this.config.tools.join(", ")}]
|
|
22
|
+
---`;
|
|
23
|
+
return `${frontmatter}
|
|
24
|
+
${this.buildMarkdownBody()}`;
|
|
25
|
+
}
|
|
26
|
+
compileToOpenCodeMarkdown() {
|
|
27
|
+
const permissionByRole = {
|
|
28
|
+
Orchestrator: { edit: "deny", bash: "ask", webfetch: "deny" },
|
|
29
|
+
Planner: { edit: "deny", bash: "ask", webfetch: "allow" },
|
|
30
|
+
Executor: { edit: "allow", bash: "allow", webfetch: "ask" },
|
|
31
|
+
Reviewer: { edit: "deny", bash: "ask", webfetch: "deny" },
|
|
32
|
+
Researcher: { edit: "deny", bash: "deny", webfetch: "allow" }
|
|
33
|
+
};
|
|
34
|
+
const permission = permissionByRole[this.config.role];
|
|
35
|
+
const frontmatter = `---
|
|
36
|
+
description: ${this.config.name}
|
|
37
|
+
mode: ${this.config.mode}
|
|
38
|
+
permission:
|
|
39
|
+
edit: ${permission.edit}
|
|
40
|
+
bash: ${permission.bash}
|
|
41
|
+
webfetch: ${permission.webfetch}
|
|
42
|
+
---`;
|
|
43
|
+
return `${frontmatter}
|
|
44
|
+
${this.buildMarkdownBody()}`;
|
|
45
|
+
}
|
|
46
|
+
buildMarkdownBody() {
|
|
47
|
+
const instructionsList = this.config.instructions.map((instruction) => `- ${instruction}`).join(`
|
|
48
|
+
`);
|
|
49
|
+
return `
|
|
50
|
+
# ${this.config.name}
|
|
51
|
+
${instructionsList}
|
|
52
|
+
|
|
53
|
+
## Shared Context
|
|
54
|
+
Refer to \`.opcrew/logbook.json\` for the current voyage status.
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/crew/Captain.ts
|
|
60
|
+
var Captain = new OpCrewAgent({
|
|
61
|
+
name: "Captain",
|
|
62
|
+
role: "Orchestrator",
|
|
63
|
+
mode: "primary",
|
|
64
|
+
instructions: [
|
|
65
|
+
"You are the orchestrator - you NEVER execute work directly. Your role is to coordinate, delegate, and verify.",
|
|
66
|
+
"Define mission intent with explicit scope, constraints, and success criteria before any execution.",
|
|
67
|
+
"Assign roles in order: Navigator plans, Boatswain executes, Quartermaster reviews; resolve conflicts quickly.",
|
|
68
|
+
"Require a logbook entry that captures decisions, risks, and acceptance checks for every mission.",
|
|
69
|
+
"Escalate blockers immediately and re-sequence work to unblock the critical path.",
|
|
70
|
+
"Enforce conventions: small, reviewable diffs; no scope creep; verification required before declaring done.",
|
|
71
|
+
"Intent gate: restate user intent, classify task type (trivial/explicit/exploratory/open-ended/ambiguous), and choose the workflow before action.",
|
|
72
|
+
"Delegation mandate: ALWAYS delegate work to specialists using the task tool. Never perform file edits, code changes, or direct execution yourself.",
|
|
73
|
+
"Delegation protocol: require task/outcome/tools/must-do/must-not/context in every order; reject vague asks.",
|
|
74
|
+
"Parallel exploration: launch explore/librarian tasks concurrently for non-trivial discovery, and avoid duplicate searches.",
|
|
75
|
+
"Verification gate: delegate verification to Quartermaster; ensure diagnostics/tests run and evidence is logged before marking complete.",
|
|
76
|
+
"Knowledge discipline: require crew to read/update docs/knowledge (project map, glossary, relevant ADRs) for any decision or scope change.",
|
|
77
|
+
"Ensure every material decision is captured as an ADR in docs/knowledge/decisions."
|
|
78
|
+
],
|
|
79
|
+
tools: ["read_fs", "edit_logbook", "task"]
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// src/crew/Navigator.ts
|
|
83
|
+
var Navigator = new OpCrewAgent({
|
|
84
|
+
name: "Navigator",
|
|
85
|
+
role: "Planner",
|
|
86
|
+
mode: "subagent",
|
|
87
|
+
instructions: [
|
|
88
|
+
"Chart the implementation path based on the Captain's intent and constraints.",
|
|
89
|
+
"Decompose work into atomic, ordered tasks with clear inputs, outputs, and ownership.",
|
|
90
|
+
"Record the plan in the logbook with file targets, dependencies, and acceptance checks.",
|
|
91
|
+
"Maintain a current project map (key files, modules, and ownership boundaries).",
|
|
92
|
+
"Flag ambiguity early, propose alternatives, and surface risks before execution starts.",
|
|
93
|
+
"Apply the intent gate: classify the request and select the correct workflow (explore vs. implement vs. clarify).",
|
|
94
|
+
"Create and manage todo/task lists for any multi-step plan; enforce one in-progress item at a time.",
|
|
95
|
+
"Mandate parallel discovery for unknowns: launch multiple explore/librarian threads and consolidate findings.",
|
|
96
|
+
"Delegate external research to Scout when you need information from outside the project: libraries, APIs, best practices, or documentation.",
|
|
97
|
+
"Define verification steps explicitly (diagnostics/tests/build) and include success evidence in the plan.",
|
|
98
|
+
"Consult docs/knowledge before planning; update project-map/glossary/ADRs when scope or definitions change."
|
|
99
|
+
],
|
|
100
|
+
tools: ["read_fs", "web_search", "edit_logbook", "todowrite"]
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// src/crew/Boatswain.ts
|
|
104
|
+
var Boatswain = new OpCrewAgent({
|
|
105
|
+
name: "Boatswain",
|
|
106
|
+
role: "Executor",
|
|
107
|
+
mode: "subagent",
|
|
108
|
+
instructions: [
|
|
109
|
+
"Turn approved Navigator steps into precise edits without scope creep.",
|
|
110
|
+
"Follow existing patterns, naming, and formatting; avoid speculative changes.",
|
|
111
|
+
"Keep diffs lean and standards-compliant; update only what the plan calls for.",
|
|
112
|
+
"Run required sanity tests and record results in the logbook.",
|
|
113
|
+
"Log completion status, assumptions, and blockers immediately for the Captain.",
|
|
114
|
+
"Do not re-run delegated exploration; wait for Navigator findings before implementing dependent changes.",
|
|
115
|
+
"Use verification gates: lsp diagnostics on touched files plus relevant tests/builds before completion.",
|
|
116
|
+
"Update docs/knowledge when execution changes assumptions, definitions, or operational steps."
|
|
117
|
+
],
|
|
118
|
+
tools: ["read_fs", "edit_code", "run_tests"]
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// src/crew/Quartermaster.ts
|
|
122
|
+
var Quartermaster = new OpCrewAgent({
|
|
123
|
+
name: "Quartermaster",
|
|
124
|
+
role: "Reviewer",
|
|
125
|
+
mode: "subagent",
|
|
126
|
+
instructions: [
|
|
127
|
+
"Inspect each diff for regression risks, scope drift, and missing context.",
|
|
128
|
+
"Confirm tests, docs, and logbook entries prove the change is complete.",
|
|
129
|
+
"Verify acceptance checks and ensure the plan-to-implementation trace is intact.",
|
|
130
|
+
"Escalate unresolved quality gaps to the Captain before approval.",
|
|
131
|
+
"Require rework when verification is missing or conventions are violated.",
|
|
132
|
+
"Reject approvals lacking evidence (diagnostics/tests/build logs) or missing todo/task tracking.",
|
|
133
|
+
"Verify delegation protocol compliance when specialists were involved (task/outcome/tools/must-do/must-not/context).",
|
|
134
|
+
"Reject approval if docs/knowledge changes are missing for material decisions or scope shifts."
|
|
135
|
+
],
|
|
136
|
+
tools: ["read", "grep", "bash", "write"]
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// src/crew/Scout.ts
|
|
140
|
+
var Scout = new OpCrewAgent({
|
|
141
|
+
name: "Scout",
|
|
142
|
+
role: "Researcher",
|
|
143
|
+
mode: "subagent",
|
|
144
|
+
instructions: [
|
|
145
|
+
"You are the crew's eyes to the outside world - research and gather information when summoned by Captain or Navigator.",
|
|
146
|
+
"Focus exclusively on external research: web searches, documentation lookup, API references, and best practices.",
|
|
147
|
+
"Never modify project files - your job is to gather intelligence, not execute changes.",
|
|
148
|
+
"Provide concise, actionable findings with clear sources and citations.",
|
|
149
|
+
"When researching libraries or frameworks, include: version info, installation methods, key APIs, and gotchas.",
|
|
150
|
+
"Compare alternatives when relevant: pros/cons, trade-offs, and recommendations with rationale.",
|
|
151
|
+
"Flag deprecated or outdated information; always verify against official sources when possible.",
|
|
152
|
+
"Summarize findings in a structured format: problem, findings, recommendations, sources.",
|
|
153
|
+
"If research reveals the task is more complex than expected, escalate to Navigator for replanning.",
|
|
154
|
+
"Cache useful references in docs/knowledge for future crew reference."
|
|
155
|
+
],
|
|
156
|
+
tools: ["web_search", "web_fetch", "read_fs"]
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// src/crew/index.ts
|
|
160
|
+
var crew = [
|
|
161
|
+
Captain,
|
|
162
|
+
Navigator,
|
|
163
|
+
Boatswain,
|
|
164
|
+
Quartermaster,
|
|
165
|
+
Scout
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
// src/cli/install.ts
|
|
169
|
+
var CLAUDE_DIR = path.join(".claudecode", "agents");
|
|
170
|
+
var OPENCODE_DIR = path.join(".opencode", "agents");
|
|
171
|
+
var CODEX_FILE = path.join(".codex", "instructions.md");
|
|
172
|
+
async function ensureDir(targetDir) {
|
|
173
|
+
await mkdir(targetDir, { recursive: true });
|
|
174
|
+
}
|
|
175
|
+
async function installToTool(tool) {
|
|
176
|
+
if (tool === "codex") {
|
|
177
|
+
await installForCodex();
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const targetDir = tool === "claude" ? CLAUDE_DIR : OPENCODE_DIR;
|
|
181
|
+
await ensureDir(targetDir);
|
|
182
|
+
for (const agent of crew) {
|
|
183
|
+
const filename = `${agent.config.name.toLowerCase()}.md`;
|
|
184
|
+
const filePath = path.join(targetDir, filename);
|
|
185
|
+
const content = tool === "opencode" ? agent.compileToOpenCodeMarkdown() : agent.compileToMarkdown();
|
|
186
|
+
await writeFile(filePath, content);
|
|
187
|
+
console.log(`Synced ${agent.config.name} to ${targetDir}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function installForCodex() {
|
|
191
|
+
const codexDir = path.dirname(CODEX_FILE);
|
|
192
|
+
await ensureDir(codexDir);
|
|
193
|
+
const compiled = crew.map((agent) => agent.compileToMarkdown()).join(`
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
`);
|
|
198
|
+
await writeFile(CODEX_FILE, compiled);
|
|
199
|
+
console.log(`Synced Codex instructions to ${CODEX_FILE}`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/cli/index.ts
|
|
203
|
+
var usage = `Usage:
|
|
204
|
+
bunx opcrew install [--claude] [--opencode] [--codex]
|
|
205
|
+
|
|
206
|
+
At least one flag is required.
|
|
207
|
+
`;
|
|
208
|
+
var FLAG_TO_TOOL = {
|
|
209
|
+
"--claude": "claude",
|
|
210
|
+
"--opencode": "opencode",
|
|
211
|
+
"--codex": "codex"
|
|
212
|
+
};
|
|
213
|
+
function showUsage(message) {
|
|
214
|
+
if (message) {
|
|
215
|
+
console.error(message);
|
|
216
|
+
}
|
|
217
|
+
console.error(usage.trimEnd());
|
|
218
|
+
process.exit(1);
|
|
219
|
+
}
|
|
220
|
+
async function main() {
|
|
221
|
+
const [subcommand, ...flags] = process.argv.slice(2);
|
|
222
|
+
if (subcommand !== "install") {
|
|
223
|
+
showUsage("Missing or invalid subcommand. Use 'install'.");
|
|
224
|
+
}
|
|
225
|
+
if (flags.length === 0) {
|
|
226
|
+
showUsage("No install target provided.");
|
|
227
|
+
}
|
|
228
|
+
const selectedTools = [];
|
|
229
|
+
const seen = new Set;
|
|
230
|
+
for (const flag of flags) {
|
|
231
|
+
const tool = FLAG_TO_TOOL[flag];
|
|
232
|
+
if (!tool) {
|
|
233
|
+
showUsage(`Unknown flag: ${flag}`);
|
|
234
|
+
}
|
|
235
|
+
if (seen.has(tool)) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
seen.add(tool);
|
|
239
|
+
selectedTools.push(tool);
|
|
240
|
+
}
|
|
241
|
+
if (selectedTools.length === 0) {
|
|
242
|
+
showUsage("No valid flags provided.");
|
|
243
|
+
}
|
|
244
|
+
for (const tool of selectedTools) {
|
|
245
|
+
await installToTool(tool);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
await main().catch((error) => {
|
|
249
|
+
console.error("Installation failed:", error);
|
|
250
|
+
process.exit(1);
|
|
251
|
+
});
|
package/dist/core/Agent.d.ts
CHANGED
package/dist/crew/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ import { Captain } from "./Captain";
|
|
|
2
2
|
import { Navigator } from "./Navigator";
|
|
3
3
|
import { Boatswain } from "./Boatswain";
|
|
4
4
|
import { Quartermaster } from "./Quartermaster";
|
|
5
|
-
|
|
6
|
-
export
|
|
5
|
+
import { Scout } from "./Scout";
|
|
6
|
+
export declare const crew: readonly [import("../core/Agent").OpCrewAgent, import("../core/Agent").OpCrewAgent, import("../core/Agent").OpCrewAgent, import("../core/Agent").OpCrewAgent, import("../core/Agent").OpCrewAgent];
|
|
7
|
+
export { Captain, Navigator, Boatswain, Quartermaster, Scout };
|