opcrew 0.1.6 → 0.1.8
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/dist/cli.js +81 -10
- package/dist/opencode-plugin.js +14 -9
- package/dist/skills/find-skills/SKILL.md +531 -0
- package/dist/skills/skills/find-skills/SKILL.md +531 -0
- package/dist/templates/knowledge/README.md +67 -0
- package/dist/templates/knowledge/glossary.md +10 -0
- package/dist/templates/knowledge/project-map.md +13 -0
- package/dist/templates/logbook.schema.json +82 -0
- package/dist/templates/logbook.template.json +8 -0
- package/dist/templates/templates/knowledge/README.md +67 -0
- package/dist/templates/templates/knowledge/glossary.md +10 -0
- package/dist/templates/templates/knowledge/project-map.md +13 -0
- package/dist/templates/templates/logbook.schema.json +82 -0
- package/dist/templates/templates/logbook.template.json +8 -0
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
import process from "process";
|
|
6
6
|
|
|
7
7
|
// src/cli/install.ts
|
|
8
|
-
import { mkdir, writeFile, cp, rm } from "fs/promises";
|
|
8
|
+
import { mkdir, writeFile, cp, rm, stat } from "fs/promises";
|
|
9
|
+
import { existsSync } from "fs";
|
|
9
10
|
import path2 from "path";
|
|
11
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
12
|
+
import { dirname } from "path";
|
|
10
13
|
// src/core/tools/translations.ts
|
|
11
14
|
var CLAUDE_TOOLS = {
|
|
12
15
|
read: "Read",
|
|
@@ -94,7 +97,7 @@ description: ${this.config.description}
|
|
|
94
97
|
tools: [${translatedTools.join(", ")}]
|
|
95
98
|
---`;
|
|
96
99
|
return `${frontmatter}
|
|
97
|
-
${this.buildMarkdownBody()}`;
|
|
100
|
+
${this.buildMarkdownBody("claude")}`;
|
|
98
101
|
}
|
|
99
102
|
compileToOpenCodeMarkdown() {
|
|
100
103
|
const permissionByRole = {
|
|
@@ -114,7 +117,7 @@ permission:
|
|
|
114
117
|
webfetch: ${permission.webfetch}
|
|
115
118
|
---`;
|
|
116
119
|
return `${frontmatter}
|
|
117
|
-
${this.buildMarkdownBody()}`;
|
|
120
|
+
${this.buildMarkdownBody("opencode")}`;
|
|
118
121
|
}
|
|
119
122
|
compileToCodexMarkdown() {
|
|
120
123
|
const translatedTools = translateTools(this.getAllowedTools(), "codex");
|
|
@@ -124,13 +127,23 @@ role: ${this.config.role}
|
|
|
124
127
|
tools: [${translatedTools.join(", ")}]
|
|
125
128
|
---`;
|
|
126
129
|
return `${frontmatter}
|
|
127
|
-
${this.buildMarkdownBody()}`;
|
|
130
|
+
${this.buildMarkdownBody("codex")}`;
|
|
128
131
|
}
|
|
129
|
-
|
|
132
|
+
buildToolBoundary(platform) {
|
|
133
|
+
const translatedTools = translateTools(this.getAllowedTools(), platform);
|
|
134
|
+
if (translatedTools.length === 0) {
|
|
135
|
+
return "TOOL BOUNDARY: No tools are available for this agent on this platform.";
|
|
136
|
+
}
|
|
137
|
+
const toolList = translatedTools.join(", ");
|
|
138
|
+
return `TOOL BOUNDARY: You are ONLY permitted to use these tools: ${toolList}. Using any other tool is a violation.`;
|
|
139
|
+
}
|
|
140
|
+
buildMarkdownBody(platform) {
|
|
141
|
+
const toolBoundary = this.buildToolBoundary(platform);
|
|
130
142
|
const instructionsList = this.config.instructions.map((instruction) => `- ${instruction}`).join(`
|
|
131
143
|
`);
|
|
132
144
|
return `
|
|
133
145
|
# ${this.config.name}
|
|
146
|
+
- ${toolBoundary}
|
|
134
147
|
${instructionsList}
|
|
135
148
|
|
|
136
149
|
## Shared Context
|
|
@@ -146,7 +159,6 @@ var Captain = new OpCrewAgent({
|
|
|
146
159
|
role: "Orchestrator",
|
|
147
160
|
mode: "primary",
|
|
148
161
|
instructions: [
|
|
149
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: read, logbook, delegate, skill. Using any other tool is a violation.",
|
|
150
162
|
"You are the orchestrator - you NEVER execute work directly. Your role is to coordinate, delegate, and verify.",
|
|
151
163
|
"Workstream Fan-out: divide missions into independent Workstreams (e.g., Logic, Testing, Documentation) to enable parallel specialists.",
|
|
152
164
|
"Assign roles in order: Navigator plans, Boatswain executes, Quartermaster reviews; resolve conflicts quickly.",
|
|
@@ -171,7 +183,6 @@ var Navigator = new OpCrewAgent({
|
|
|
171
183
|
role: "Planner",
|
|
172
184
|
mode: "subagent",
|
|
173
185
|
instructions: [
|
|
174
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: read, websearch, logbook, todo, skill. Using any other tool is a violation.",
|
|
175
186
|
"Chart the implementation path based on the Captain's intent and constraints.",
|
|
176
187
|
"Decompose work into atomic, ordered tasks with clear inputs, outputs, and ownership.",
|
|
177
188
|
"Workstream Decomposition: break the plan into atomic, parallel tracks. Define File Ownership (e.g., Boatswain-A owns src/, Boatswain-B owns tests/).",
|
|
@@ -200,7 +211,6 @@ var Boatswain = new OpCrewAgent({
|
|
|
200
211
|
role: "Executor",
|
|
201
212
|
mode: "subagent",
|
|
202
213
|
instructions: [
|
|
203
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: read, edit, write, test, todo, glob, grep, skill. Using any other tool is a violation.",
|
|
204
214
|
"Scope Guarding: ONLY touch files assigned to your Workstream ID. If you must edit a file owned by another agent, escalate to Captain for a plan revision.",
|
|
205
215
|
"Follow existing patterns, naming, and formatting; avoid speculative changes.",
|
|
206
216
|
"Context Anchoring: before editing, read the surrounding code to match indentation, casing, and comment styles. Maintain the project's local laws.",
|
|
@@ -223,7 +233,6 @@ var Quartermaster = new OpCrewAgent({
|
|
|
223
233
|
role: "Reviewer",
|
|
224
234
|
mode: "subagent",
|
|
225
235
|
instructions: [
|
|
226
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: read, grep, execute, write, skill. Using any other tool is a violation.",
|
|
227
236
|
"Inspect each diff for regression risks, scope drift, and missing context.",
|
|
228
237
|
"Integration Audit: once all parallel Boatswains report Complete, verify the combined diff for logic conflicts or signature mismatches.",
|
|
229
238
|
"Documentation Gate: REJECT approval if code changed but docs/project-map.md or docs/glossary.md were not updated to reflect the new state.",
|
|
@@ -246,7 +255,6 @@ var Scout = new OpCrewAgent({
|
|
|
246
255
|
role: "Researcher",
|
|
247
256
|
mode: "subagent",
|
|
248
257
|
instructions: [
|
|
249
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: websearch, webfetch, read, skill. Using any other tool is a violation.",
|
|
250
258
|
"You are the crew's eyes to the outside world - research and gather information when summoned by Captain or Navigator.",
|
|
251
259
|
"Focus exclusively on external research: web searches, documentation lookup, API references, and best practices.",
|
|
252
260
|
"Never modify project files - your job is to gather intelligence, not execute changes.",
|
|
@@ -333,10 +341,73 @@ var CLAUDE_SKILLS_DIR = path2.join(".claude", "skills");
|
|
|
333
341
|
var OPENCODE_AGENTS_DIR = path2.join(".opencode", "agents");
|
|
334
342
|
var OPENCODE_SKILLS_DIR = path2.join(".opencode", "skills");
|
|
335
343
|
var CODEX_FILE = path2.join(".codex", "instructions.md");
|
|
344
|
+
var OPCREW_DIR = ".opcrew";
|
|
345
|
+
var KNOWLEDGE_DIR = path2.join("docs", "knowledge");
|
|
346
|
+
var __dirname3 = dirname(fileURLToPath2(import.meta.url));
|
|
347
|
+
var builtTemplateDir = path2.join(__dirname3, "templates");
|
|
348
|
+
var sourceTemplateDir = path2.join(__dirname3, "..", "templates");
|
|
349
|
+
var TEMPLATE_DIR = existsSync(builtTemplateDir) ? builtTemplateDir : sourceTemplateDir;
|
|
336
350
|
async function ensureDir(targetDir) {
|
|
337
351
|
await mkdir(targetDir, { recursive: true });
|
|
338
352
|
}
|
|
353
|
+
async function fileExists(filePath) {
|
|
354
|
+
try {
|
|
355
|
+
await stat(filePath);
|
|
356
|
+
return true;
|
|
357
|
+
} catch {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
async function bootstrapLogbook() {
|
|
362
|
+
const logbookPath = path2.join(OPCREW_DIR, "logbook.json");
|
|
363
|
+
const schemaPath = path2.join(OPCREW_DIR, "logbook.schema.json");
|
|
364
|
+
await ensureDir(OPCREW_DIR);
|
|
365
|
+
if (await fileExists(logbookPath)) {
|
|
366
|
+
console.log(`Skipped ${logbookPath} (already exists)`);
|
|
367
|
+
} else {
|
|
368
|
+
const templatePath = path2.join(TEMPLATE_DIR, "logbook.template.json");
|
|
369
|
+
await cp(templatePath, logbookPath);
|
|
370
|
+
console.log(`Created ${logbookPath}`);
|
|
371
|
+
}
|
|
372
|
+
if (await fileExists(schemaPath)) {
|
|
373
|
+
console.log(`Skipped ${schemaPath} (already exists)`);
|
|
374
|
+
} else {
|
|
375
|
+
const schemaTemplatePath = path2.join(TEMPLATE_DIR, "logbook.schema.json");
|
|
376
|
+
await cp(schemaTemplatePath, schemaPath);
|
|
377
|
+
console.log(`Created ${schemaPath}`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
async function bootstrapKnowledgeBase() {
|
|
381
|
+
const decisionsDir = path2.join(KNOWLEDGE_DIR, "decisions");
|
|
382
|
+
const readmePath = path2.join(KNOWLEDGE_DIR, "README.md");
|
|
383
|
+
const glossaryPath = path2.join(KNOWLEDGE_DIR, "glossary.md");
|
|
384
|
+
const projectMapPath = path2.join(KNOWLEDGE_DIR, "project-map.md");
|
|
385
|
+
await ensureDir(decisionsDir);
|
|
386
|
+
if (await fileExists(readmePath)) {
|
|
387
|
+
console.log(`Skipped ${readmePath} (already exists)`);
|
|
388
|
+
} else {
|
|
389
|
+
const templatePath = path2.join(TEMPLATE_DIR, "knowledge", "README.md");
|
|
390
|
+
await cp(templatePath, readmePath);
|
|
391
|
+
console.log(`Created ${readmePath}`);
|
|
392
|
+
}
|
|
393
|
+
if (await fileExists(glossaryPath)) {
|
|
394
|
+
console.log(`Skipped ${glossaryPath} (already exists)`);
|
|
395
|
+
} else {
|
|
396
|
+
const templatePath = path2.join(TEMPLATE_DIR, "knowledge", "glossary.md");
|
|
397
|
+
await cp(templatePath, glossaryPath);
|
|
398
|
+
console.log(`Created ${glossaryPath}`);
|
|
399
|
+
}
|
|
400
|
+
if (await fileExists(projectMapPath)) {
|
|
401
|
+
console.log(`Skipped ${projectMapPath} (already exists)`);
|
|
402
|
+
} else {
|
|
403
|
+
const templatePath = path2.join(TEMPLATE_DIR, "knowledge", "project-map.md");
|
|
404
|
+
await cp(templatePath, projectMapPath);
|
|
405
|
+
console.log(`Created ${projectMapPath}`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
339
408
|
async function installToTool(tool) {
|
|
409
|
+
await bootstrapLogbook();
|
|
410
|
+
await bootstrapKnowledgeBase();
|
|
340
411
|
if (tool === "codex") {
|
|
341
412
|
await installForCodex();
|
|
342
413
|
return;
|
package/dist/opencode-plugin.js
CHANGED
|
@@ -100,7 +100,7 @@ description: ${this.config.description}
|
|
|
100
100
|
tools: [${translatedTools.join(", ")}]
|
|
101
101
|
---`;
|
|
102
102
|
return `${frontmatter}
|
|
103
|
-
${this.buildMarkdownBody()}`;
|
|
103
|
+
${this.buildMarkdownBody("claude")}`;
|
|
104
104
|
}
|
|
105
105
|
compileToOpenCodeMarkdown() {
|
|
106
106
|
const permissionByRole = {
|
|
@@ -120,7 +120,7 @@ permission:
|
|
|
120
120
|
webfetch: ${permission.webfetch}
|
|
121
121
|
---`;
|
|
122
122
|
return `${frontmatter}
|
|
123
|
-
${this.buildMarkdownBody()}`;
|
|
123
|
+
${this.buildMarkdownBody("opencode")}`;
|
|
124
124
|
}
|
|
125
125
|
compileToCodexMarkdown() {
|
|
126
126
|
const translatedTools = translateTools(this.getAllowedTools(), "codex");
|
|
@@ -130,13 +130,23 @@ role: ${this.config.role}
|
|
|
130
130
|
tools: [${translatedTools.join(", ")}]
|
|
131
131
|
---`;
|
|
132
132
|
return `${frontmatter}
|
|
133
|
-
${this.buildMarkdownBody()}`;
|
|
133
|
+
${this.buildMarkdownBody("codex")}`;
|
|
134
134
|
}
|
|
135
|
-
|
|
135
|
+
buildToolBoundary(platform) {
|
|
136
|
+
const translatedTools = translateTools(this.getAllowedTools(), platform);
|
|
137
|
+
if (translatedTools.length === 0) {
|
|
138
|
+
return "TOOL BOUNDARY: No tools are available for this agent on this platform.";
|
|
139
|
+
}
|
|
140
|
+
const toolList = translatedTools.join(", ");
|
|
141
|
+
return `TOOL BOUNDARY: You are ONLY permitted to use these tools: ${toolList}. Using any other tool is a violation.`;
|
|
142
|
+
}
|
|
143
|
+
buildMarkdownBody(platform) {
|
|
144
|
+
const toolBoundary = this.buildToolBoundary(platform);
|
|
136
145
|
const instructionsList = this.config.instructions.map((instruction) => `- ${instruction}`).join(`
|
|
137
146
|
`);
|
|
138
147
|
return `
|
|
139
148
|
# ${this.config.name}
|
|
149
|
+
- ${toolBoundary}
|
|
140
150
|
${instructionsList}
|
|
141
151
|
|
|
142
152
|
## Shared Context
|
|
@@ -152,7 +162,6 @@ var Captain = new OpCrewAgent({
|
|
|
152
162
|
role: "Orchestrator",
|
|
153
163
|
mode: "primary",
|
|
154
164
|
instructions: [
|
|
155
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: read, logbook, delegate, skill. Using any other tool is a violation.",
|
|
156
165
|
"You are the orchestrator - you NEVER execute work directly. Your role is to coordinate, delegate, and verify.",
|
|
157
166
|
"Workstream Fan-out: divide missions into independent Workstreams (e.g., Logic, Testing, Documentation) to enable parallel specialists.",
|
|
158
167
|
"Assign roles in order: Navigator plans, Boatswain executes, Quartermaster reviews; resolve conflicts quickly.",
|
|
@@ -177,7 +186,6 @@ var Navigator = new OpCrewAgent({
|
|
|
177
186
|
role: "Planner",
|
|
178
187
|
mode: "subagent",
|
|
179
188
|
instructions: [
|
|
180
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: read, websearch, logbook, todo, skill. Using any other tool is a violation.",
|
|
181
189
|
"Chart the implementation path based on the Captain's intent and constraints.",
|
|
182
190
|
"Decompose work into atomic, ordered tasks with clear inputs, outputs, and ownership.",
|
|
183
191
|
"Workstream Decomposition: break the plan into atomic, parallel tracks. Define File Ownership (e.g., Boatswain-A owns src/, Boatswain-B owns tests/).",
|
|
@@ -206,7 +214,6 @@ var Boatswain = new OpCrewAgent({
|
|
|
206
214
|
role: "Executor",
|
|
207
215
|
mode: "subagent",
|
|
208
216
|
instructions: [
|
|
209
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: read, edit, write, test, todo, glob, grep, skill. Using any other tool is a violation.",
|
|
210
217
|
"Scope Guarding: ONLY touch files assigned to your Workstream ID. If you must edit a file owned by another agent, escalate to Captain for a plan revision.",
|
|
211
218
|
"Follow existing patterns, naming, and formatting; avoid speculative changes.",
|
|
212
219
|
"Context Anchoring: before editing, read the surrounding code to match indentation, casing, and comment styles. Maintain the project's local laws.",
|
|
@@ -229,7 +236,6 @@ var Quartermaster = new OpCrewAgent({
|
|
|
229
236
|
role: "Reviewer",
|
|
230
237
|
mode: "subagent",
|
|
231
238
|
instructions: [
|
|
232
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: read, grep, execute, write, skill. Using any other tool is a violation.",
|
|
233
239
|
"Inspect each diff for regression risks, scope drift, and missing context.",
|
|
234
240
|
"Integration Audit: once all parallel Boatswains report Complete, verify the combined diff for logic conflicts or signature mismatches.",
|
|
235
241
|
"Documentation Gate: REJECT approval if code changed but docs/project-map.md or docs/glossary.md were not updated to reflect the new state.",
|
|
@@ -252,7 +258,6 @@ var Scout = new OpCrewAgent({
|
|
|
252
258
|
role: "Researcher",
|
|
253
259
|
mode: "subagent",
|
|
254
260
|
instructions: [
|
|
255
|
-
"TOOL BOUNDARY: You are ONLY permitted to use these tools: websearch, webfetch, read, skill. Using any other tool is a violation.",
|
|
256
261
|
"You are the crew's eyes to the outside world - research and gather information when summoned by Captain or Navigator.",
|
|
257
262
|
"Focus exclusively on external research: web searches, documentation lookup, API references, and best practices.",
|
|
258
263
|
"Never modify project files - your job is to gather intelligence, not execute changes.",
|