@cloudpftc/opencode-orchestrator 3.5.15 → 3.6.1
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/.opencode/helpers/auto-memory-hook.mjs +104 -0
- package/.opencode/helpers/hook-handler.cjs +223 -0
- package/.opencode/helpers/intelligence.cjs +197 -0
- package/.opencode/helpers/memory.js +83 -0
- package/.opencode/helpers/post-commit +16 -0
- package/.opencode/helpers/pre-commit +26 -0
- package/.opencode/helpers/router.js +66 -0
- package/.opencode/helpers/session.js +127 -0
- package/.opencode/helpers/statusline.cjs +774 -0
- package/.opencode/settings.json +319 -0
- package/opencode.json +35 -78
- package/package.json +2 -6
- package/v3/@claude-flow/cli/README.md +391 -534
- package/v3/@claude-flow/cli/dist/src/commands/benchmark.js +2 -2
- package/v3/@claude-flow/cli/dist/src/commands/claims.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/config.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/daemon.js +3 -3
- package/v3/@claude-flow/cli/dist/src/commands/deployment.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/doctor.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/embeddings.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/hooks.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/init.js +16 -16
- package/v3/@claude-flow/cli/dist/src/commands/neural.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/performance.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/plugins.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/providers.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/security.js +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/start.js +10 -10
- package/v3/@claude-flow/cli/dist/src/commands/status.js +2 -2
- package/v3/@claude-flow/cli/dist/src/commands/transfer-store.js +1 -1
- package/v3/@claude-flow/cli/dist/src/init/executor.js +181 -133
- package/v3/@claude-flow/cli/dist/src/init/helpers-generator.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/init/helpers-generator.js +20 -20
- package/v3/@claude-flow/cli/dist/src/init/index.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/init/index.js +1 -1
- package/v3/@claude-flow/cli/dist/src/init/mcp-generator.d.ts +2 -2
- package/v3/@claude-flow/cli/dist/src/init/mcp-generator.js +15 -15
- package/v3/@claude-flow/cli/dist/src/init/opencode-generator.d.ts +42 -0
- package/v3/@claude-flow/cli/dist/src/init/opencode-generator.js +107 -0
- package/v3/@claude-flow/cli/dist/src/init/settings-generator.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/init/settings-generator.js +18 -18
- package/v3/@claude-flow/cli/dist/src/init/{claudemd-generator.d.ts → skillmd-generator.d.ts} +8 -8
- package/v3/@claude-flow/cli/dist/src/init/{claudemd-generator.js → skillmd-generator.js} +9 -9
- package/v3/@claude-flow/cli/dist/src/init/statusline-generator.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/init/statusline-generator.js +39 -23
- package/v3/@claude-flow/cli/dist/src/init/types.d.ts +14 -10
- package/v3/@claude-flow/cli/dist/src/init/types.js +3 -3
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +1 -1
- package/v3/@claude-flow/cli/dist/src/plugins/store/discovery.js +1 -1
- package/v3/@claude-flow/cli/dist/src/runtime/headless.js +3 -3
- package/v3/@claude-flow/cli/dist/src/services/claim-service.js +1 -1
- package/v3/@claude-flow/cli/dist/src/types.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/types.js +1 -1
- package/v3/@claude-flow/cli/package.json +1 -1
|
@@ -15,7 +15,7 @@ import { generateSettingsJson, generateSettings } from './settings-generator.js'
|
|
|
15
15
|
import { generateMCPJson } from './mcp-generator.js';
|
|
16
16
|
import { generateStatuslineScript } from './statusline-generator.js';
|
|
17
17
|
import { generatePreCommitHook, generatePostCommitHook, generateSessionManager, generateAgentRouter, generateMemoryHelper, generateHookHandler, generateIntelligenceStub, generateAutoMemoryHook, } from './helpers-generator.js';
|
|
18
|
-
import {
|
|
18
|
+
import { generateSkillMd } from './skillmd-generator.js';
|
|
19
19
|
/**
|
|
20
20
|
* Skills to copy based on configuration
|
|
21
21
|
*/
|
|
@@ -109,23 +109,24 @@ const AGENTS_MAP = {
|
|
|
109
109
|
};
|
|
110
110
|
/**
|
|
111
111
|
* Directory structure to create
|
|
112
|
+
* OpenCode uses .opencode/ instead of .opencode/
|
|
112
113
|
*/
|
|
113
114
|
const DIRECTORIES = {
|
|
114
|
-
|
|
115
|
-
'.
|
|
116
|
-
'.
|
|
117
|
-
'.
|
|
118
|
-
'.
|
|
119
|
-
'.
|
|
115
|
+
opencode: [
|
|
116
|
+
'.opencode',
|
|
117
|
+
'.opencode/skills',
|
|
118
|
+
'.opencode/commands',
|
|
119
|
+
'.opencode/agents',
|
|
120
|
+
'.opencode/helpers',
|
|
120
121
|
],
|
|
121
122
|
runtime: [
|
|
122
|
-
'.
|
|
123
|
-
'.
|
|
124
|
-
'.
|
|
125
|
-
'.
|
|
126
|
-
'.
|
|
127
|
-
'.
|
|
128
|
-
'.
|
|
123
|
+
'.opencode-flow',
|
|
124
|
+
'.opencode-flow/data',
|
|
125
|
+
'.opencode-flow/logs',
|
|
126
|
+
'.opencode-flow/sessions',
|
|
127
|
+
'.opencode-flow/hooks',
|
|
128
|
+
'.opencode-flow/agents',
|
|
129
|
+
'.opencode-flow/workflows',
|
|
129
130
|
],
|
|
130
131
|
};
|
|
131
132
|
/**
|
|
@@ -152,6 +153,8 @@ export async function executeInit(options) {
|
|
|
152
153
|
};
|
|
153
154
|
const targetDir = options.targetDir;
|
|
154
155
|
try {
|
|
156
|
+
// Clean up old Claude Code files if they exist
|
|
157
|
+
await cleanupOldClaudeFiles(targetDir, result);
|
|
155
158
|
// Create directory structure
|
|
156
159
|
await createDirectories(targetDir, options, result);
|
|
157
160
|
// Generate and write settings.json
|
|
@@ -190,9 +193,9 @@ export async function executeInit(options) {
|
|
|
190
193
|
if (options.components.statusline) {
|
|
191
194
|
await writeInitialMetrics(targetDir, options, result);
|
|
192
195
|
}
|
|
193
|
-
// Generate
|
|
194
|
-
if (options.components.
|
|
195
|
-
await
|
|
196
|
+
// Generate SKILL.md
|
|
197
|
+
if (options.components.opencodeMd) {
|
|
198
|
+
await writeSkillMd(targetDir, options, result);
|
|
196
199
|
}
|
|
197
200
|
// Count enabled hooks
|
|
198
201
|
result.summary.hooksEnabled = countEnabledHooks(options);
|
|
@@ -234,7 +237,7 @@ function mergeSettingsForUpgrade(existing) {
|
|
|
234
237
|
const gitRootResolver = "var c=require('child_process'),p=require('path'),u=require('url'),r;"
|
|
235
238
|
+ "try{r=c.execSync('git rev-parse --show-toplevel',{encoding:'utf8'}).trim()}"
|
|
236
239
|
+ 'catch(e){r=process.cwd()}';
|
|
237
|
-
const autoMemoryScript = '.
|
|
240
|
+
const autoMemoryScript = '.opencode/helpers/auto-memory-hook.mjs';
|
|
238
241
|
const autoMemoryImportCmd = `node -e "${gitRootResolver}var f=p.join(r,'${autoMemoryScript}');import(u.pathToFileURL(f).href)" import`;
|
|
239
242
|
const autoMemorySyncCmd = `node -e "${gitRootResolver}var f=p.join(r,'${autoMemoryScript}');import(u.pathToFileURL(f).href)" sync`;
|
|
240
243
|
// Add auto-memory import to SessionStart (if not already present)
|
|
@@ -286,14 +289,14 @@ function mergeSettingsForUpgrade(existing) {
|
|
|
286
289
|
if (existingStatusLine) {
|
|
287
290
|
merged.statusLine = {
|
|
288
291
|
type: 'command',
|
|
289
|
-
command: existingStatusLine.command || `node -e "var c=require('child_process'),p=require('path'),r;try{r=c.execSync('git rev-parse --show-toplevel',{encoding:'utf8'}).trim()}catch(e){r=process.cwd()}var s=p.join(r,'.
|
|
292
|
+
command: existingStatusLine.command || `node -e "var c=require('child_process'),p=require('path'),r;try{r=c.execSync('git rev-parse --show-toplevel',{encoding:'utf8'}).trim()}catch(e){r=process.cwd()}var s=p.join(r,'.opencode/helpers/statusline.cjs');process.argv.splice(1,0,s);require(s)"`,
|
|
290
293
|
// Remove invalid fields: refreshMs, enabled (not supported by Claude Code)
|
|
291
294
|
};
|
|
292
295
|
}
|
|
293
296
|
// 4. Merge claudeFlow settings (preserve existing, add agentTeams + memory)
|
|
294
|
-
const existingClaudeFlow = existing.
|
|
297
|
+
const existingClaudeFlow = existing.opencodeFlow || {};
|
|
295
298
|
const existingMemory = existingClaudeFlow.memory || {};
|
|
296
|
-
merged.
|
|
299
|
+
merged.opencodeFlow = {
|
|
297
300
|
...existingClaudeFlow,
|
|
298
301
|
version: existingClaudeFlow.version || '3.0.0',
|
|
299
302
|
enabled: existingClaudeFlow.enabled !== false,
|
|
@@ -340,10 +343,10 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
340
343
|
try {
|
|
341
344
|
// Ensure required directories exist
|
|
342
345
|
const dirs = [
|
|
343
|
-
'.
|
|
344
|
-
'.
|
|
345
|
-
'.
|
|
346
|
-
'.
|
|
346
|
+
'.opencode/helpers',
|
|
347
|
+
'.opencode-flow/metrics',
|
|
348
|
+
'.opencode-flow/security',
|
|
349
|
+
'.opencode-flow/learning',
|
|
347
350
|
];
|
|
348
351
|
for (const dir of dirs) {
|
|
349
352
|
const fullPath = path.join(targetDir, dir);
|
|
@@ -356,14 +359,14 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
356
359
|
if (sourceHelpersForUpgrade) {
|
|
357
360
|
const criticalHelpers = ['auto-memory-hook.mjs', 'hook-handler.cjs', 'intelligence.cjs'];
|
|
358
361
|
for (const helperName of criticalHelpers) {
|
|
359
|
-
const targetPath = path.join(targetDir, '.
|
|
362
|
+
const targetPath = path.join(targetDir, '.opencode', 'helpers', helperName);
|
|
360
363
|
const sourcePath = path.join(sourceHelpersForUpgrade, helperName);
|
|
361
364
|
if (fs.existsSync(sourcePath)) {
|
|
362
365
|
if (fs.existsSync(targetPath)) {
|
|
363
|
-
result.updated.push(`.
|
|
366
|
+
result.updated.push(`.opencode/helpers/${helperName}`);
|
|
364
367
|
}
|
|
365
368
|
else {
|
|
366
|
-
result.created.push(`.
|
|
369
|
+
result.created.push(`.opencode/helpers/${helperName}`);
|
|
367
370
|
}
|
|
368
371
|
fs.copyFileSync(sourcePath, targetPath);
|
|
369
372
|
try {
|
|
@@ -381,12 +384,12 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
381
384
|
'auto-memory-hook.mjs': generateAutoMemoryHook(),
|
|
382
385
|
};
|
|
383
386
|
for (const [helperName, content] of Object.entries(generatedCritical)) {
|
|
384
|
-
const targetPath = path.join(targetDir, '.
|
|
387
|
+
const targetPath = path.join(targetDir, '.opencode', 'helpers', helperName);
|
|
385
388
|
if (fs.existsSync(targetPath)) {
|
|
386
|
-
result.updated.push(`.
|
|
389
|
+
result.updated.push(`.opencode/helpers/${helperName}`);
|
|
387
390
|
}
|
|
388
391
|
else {
|
|
389
|
-
result.created.push(`.
|
|
392
|
+
result.created.push(`.opencode/helpers/${helperName}`);
|
|
390
393
|
}
|
|
391
394
|
fs.writeFileSync(targetPath, content, 'utf-8');
|
|
392
395
|
try {
|
|
@@ -396,7 +399,7 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
396
399
|
}
|
|
397
400
|
}
|
|
398
401
|
// 1. ALWAYS update statusline helper (force overwrite)
|
|
399
|
-
const statuslinePath = path.join(targetDir, '.
|
|
402
|
+
const statuslinePath = path.join(targetDir, '.opencode', 'helpers', 'statusline.cjs');
|
|
400
403
|
// Use default options with statusline config
|
|
401
404
|
const upgradeOptions = {
|
|
402
405
|
...DEFAULT_INIT_OPTIONS,
|
|
@@ -409,15 +412,15 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
409
412
|
};
|
|
410
413
|
const statuslineContent = generateStatuslineScript(upgradeOptions);
|
|
411
414
|
if (fs.existsSync(statuslinePath)) {
|
|
412
|
-
result.updated.push('.
|
|
415
|
+
result.updated.push('.opencode/helpers/statusline.cjs');
|
|
413
416
|
}
|
|
414
417
|
else {
|
|
415
|
-
result.created.push('.
|
|
418
|
+
result.created.push('.opencode/helpers/statusline.cjs');
|
|
416
419
|
}
|
|
417
420
|
fs.writeFileSync(statuslinePath, statuslineContent, 'utf-8');
|
|
418
421
|
// 2. Create MISSING metrics files only (preserve existing data)
|
|
419
|
-
const metricsDir = path.join(targetDir, '.
|
|
420
|
-
const securityDir = path.join(targetDir, '.
|
|
422
|
+
const metricsDir = path.join(targetDir, '.opencode-flow', 'metrics');
|
|
423
|
+
const securityDir = path.join(targetDir, '.opencode-flow', 'security');
|
|
421
424
|
// v3-progress.json
|
|
422
425
|
const progressPath = path.join(metricsDir, 'v3-progress.json');
|
|
423
426
|
if (!fs.existsSync(progressPath)) {
|
|
@@ -431,10 +434,10 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
431
434
|
_note: 'Metrics will update as you use Claude Flow'
|
|
432
435
|
};
|
|
433
436
|
fs.writeFileSync(progressPath, JSON.stringify(progress, null, 2), 'utf-8');
|
|
434
|
-
result.created.push('.
|
|
437
|
+
result.created.push('.opencode-flow/metrics/v3-progress.json');
|
|
435
438
|
}
|
|
436
439
|
else {
|
|
437
|
-
result.preserved.push('.
|
|
440
|
+
result.preserved.push('.opencode-flow/metrics/v3-progress.json');
|
|
438
441
|
}
|
|
439
442
|
// swarm-activity.json
|
|
440
443
|
const activityPath = path.join(metricsDir, 'swarm-activity.json');
|
|
@@ -447,10 +450,10 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
447
450
|
_initialized: true
|
|
448
451
|
};
|
|
449
452
|
fs.writeFileSync(activityPath, JSON.stringify(activity, null, 2), 'utf-8');
|
|
450
|
-
result.created.push('.
|
|
453
|
+
result.created.push('.opencode-flow/metrics/swarm-activity.json');
|
|
451
454
|
}
|
|
452
455
|
else {
|
|
453
|
-
result.preserved.push('.
|
|
456
|
+
result.preserved.push('.opencode-flow/metrics/swarm-activity.json');
|
|
454
457
|
}
|
|
455
458
|
// learning.json
|
|
456
459
|
const learningPath = path.join(metricsDir, 'learning.json');
|
|
@@ -463,10 +466,10 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
463
466
|
_note: 'Intelligence grows as you use Claude Flow'
|
|
464
467
|
};
|
|
465
468
|
fs.writeFileSync(learningPath, JSON.stringify(learning, null, 2), 'utf-8');
|
|
466
|
-
result.created.push('.
|
|
469
|
+
result.created.push('.opencode-flow/metrics/learning.json');
|
|
467
470
|
}
|
|
468
471
|
else {
|
|
469
|
-
result.preserved.push('.
|
|
472
|
+
result.preserved.push('.opencode-flow/metrics/learning.json');
|
|
470
473
|
}
|
|
471
474
|
// audit-status.json
|
|
472
475
|
const auditPath = path.join(securityDir, 'audit-status.json');
|
|
@@ -480,20 +483,20 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
480
483
|
_note: 'Run: npx @claude-flow/cli@latest security scan'
|
|
481
484
|
};
|
|
482
485
|
fs.writeFileSync(auditPath, JSON.stringify(audit, null, 2), 'utf-8');
|
|
483
|
-
result.created.push('.
|
|
486
|
+
result.created.push('.opencode-flow/security/audit-status.json');
|
|
484
487
|
}
|
|
485
488
|
else {
|
|
486
|
-
result.preserved.push('.
|
|
489
|
+
result.preserved.push('.opencode-flow/security/audit-status.json');
|
|
487
490
|
}
|
|
488
491
|
// 3. Merge settings if requested
|
|
489
492
|
if (upgradeSettings) {
|
|
490
|
-
const settingsPath = path.join(targetDir, '.
|
|
493
|
+
const settingsPath = path.join(targetDir, '.opencode', 'settings.json');
|
|
491
494
|
if (fs.existsSync(settingsPath)) {
|
|
492
495
|
try {
|
|
493
496
|
const existingSettings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
494
497
|
const mergedSettings = mergeSettingsForUpgrade(existingSettings);
|
|
495
498
|
fs.writeFileSync(settingsPath, JSON.stringify(mergedSettings, null, 2), 'utf-8');
|
|
496
|
-
result.updated.push('.
|
|
499
|
+
result.updated.push('.opencode/settings.json');
|
|
497
500
|
result.settingsUpdated = [
|
|
498
501
|
'env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS',
|
|
499
502
|
'hooks.SessionStart (auto-memory import)',
|
|
@@ -512,7 +515,7 @@ export async function executeUpgrade(targetDir, upgradeSettings = false) {
|
|
|
512
515
|
// Create new settings.json with defaults
|
|
513
516
|
const defaultSettings = generateSettings(DEFAULT_INIT_OPTIONS);
|
|
514
517
|
fs.writeFileSync(settingsPath, JSON.stringify(defaultSettings, null, 2), 'utf-8');
|
|
515
|
-
result.created.push('.
|
|
518
|
+
result.created.push('.opencode/settings.json');
|
|
516
519
|
result.settingsUpdated = ['Created new settings.json with Agent Teams'];
|
|
517
520
|
}
|
|
518
521
|
}
|
|
@@ -541,9 +544,9 @@ export async function executeUpgradeWithMissing(targetDir, upgradeSettings = fal
|
|
|
541
544
|
result.addedCommands = [];
|
|
542
545
|
try {
|
|
543
546
|
// Ensure target directories exist
|
|
544
|
-
const skillsDir = path.join(targetDir, '.
|
|
545
|
-
const agentsDir = path.join(targetDir, '.
|
|
546
|
-
const commandsDir = path.join(targetDir, '.
|
|
547
|
+
const skillsDir = path.join(targetDir, '.opencode', 'skills');
|
|
548
|
+
const agentsDir = path.join(targetDir, '.opencode', 'agents');
|
|
549
|
+
const commandsDir = path.join(targetDir, '.opencode', 'commands');
|
|
547
550
|
for (const dir of [skillsDir, agentsDir, commandsDir]) {
|
|
548
551
|
if (!fs.existsSync(dir)) {
|
|
549
552
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -578,7 +581,7 @@ export async function executeUpgradeWithMissing(targetDir, upgradeSettings = fal
|
|
|
578
581
|
if (sourceExists && !targetExists) {
|
|
579
582
|
copyDirRecursive(sourcePath, targetPath);
|
|
580
583
|
result.addedSkills.push(skillName);
|
|
581
|
-
result.created.push(`.
|
|
584
|
+
result.created.push(`.opencode/skills/${skillName}`);
|
|
582
585
|
}
|
|
583
586
|
}
|
|
584
587
|
}
|
|
@@ -591,7 +594,7 @@ export async function executeUpgradeWithMissing(targetDir, upgradeSettings = fal
|
|
|
591
594
|
if (fs.existsSync(sourcePath) && !fs.existsSync(targetPath)) {
|
|
592
595
|
copyDirRecursive(sourcePath, targetPath);
|
|
593
596
|
result.addedAgents.push(agentCategory);
|
|
594
|
-
result.created.push(`.
|
|
597
|
+
result.created.push(`.opencode/agents/${agentCategory}`);
|
|
595
598
|
}
|
|
596
599
|
}
|
|
597
600
|
}
|
|
@@ -609,7 +612,7 @@ export async function executeUpgradeWithMissing(targetDir, upgradeSettings = fal
|
|
|
609
612
|
fs.copyFileSync(sourcePath, targetPath);
|
|
610
613
|
}
|
|
611
614
|
result.addedCommands.push(cmdName);
|
|
612
|
-
result.created.push(`.
|
|
615
|
+
result.created.push(`.opencode/commands/${cmdName}`);
|
|
613
616
|
}
|
|
614
617
|
}
|
|
615
618
|
}
|
|
@@ -619,12 +622,57 @@ export async function executeUpgradeWithMissing(targetDir, upgradeSettings = fal
|
|
|
619
622
|
}
|
|
620
623
|
return result;
|
|
621
624
|
}
|
|
625
|
+
/**
|
|
626
|
+
* Clean up old Claude Code files (migration from previous versions)
|
|
627
|
+
*/
|
|
628
|
+
async function cleanupOldClaudeFiles(targetDir, result) {
|
|
629
|
+
const oldPaths = [
|
|
630
|
+
'.claude',
|
|
631
|
+
'.claude/skills',
|
|
632
|
+
'.claude/commands',
|
|
633
|
+
'.claude/agents',
|
|
634
|
+
'.claude/helpers',
|
|
635
|
+
'.claude/settings.json',
|
|
636
|
+
'CLAUDE.md',
|
|
637
|
+
'.mcp.json',
|
|
638
|
+
'.claude-flow',
|
|
639
|
+
'.claude-flow/data',
|
|
640
|
+
'.claude-flow/logs',
|
|
641
|
+
'.claude-flow/sessions',
|
|
642
|
+
'.claude-flow/hooks',
|
|
643
|
+
'.claude-flow/agents',
|
|
644
|
+
'.claude-flow/workflows',
|
|
645
|
+
'.claude-flow/config.yaml',
|
|
646
|
+
'.claude-flow/CAPABILITIES.md',
|
|
647
|
+
'.claude-flow/memory.db',
|
|
648
|
+
'.claude-flow/hnsw.index',
|
|
649
|
+
'.claude-flow/session.json',
|
|
650
|
+
];
|
|
651
|
+
for (const oldPath of oldPaths) {
|
|
652
|
+
const fullPath = path.join(targetDir, oldPath);
|
|
653
|
+
if (fs.existsSync(fullPath)) {
|
|
654
|
+
try {
|
|
655
|
+
const stat = fs.statSync(fullPath);
|
|
656
|
+
if (stat.isDirectory()) {
|
|
657
|
+
fs.rmSync(fullPath, { recursive: true, force: true });
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
fs.unlinkSync(fullPath);
|
|
661
|
+
}
|
|
662
|
+
result.skipped.push(`Cleaned up old: ${oldPath}`);
|
|
663
|
+
}
|
|
664
|
+
catch (error) {
|
|
665
|
+
// Ignore errors during cleanup - files might be in use
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
622
670
|
/**
|
|
623
671
|
* Create directory structure
|
|
624
672
|
*/
|
|
625
673
|
async function createDirectories(targetDir, options, result) {
|
|
626
674
|
const dirs = [
|
|
627
|
-
...DIRECTORIES.
|
|
675
|
+
...DIRECTORIES.opencode,
|
|
628
676
|
...(options.components.runtime ? DIRECTORIES.runtime : []),
|
|
629
677
|
];
|
|
630
678
|
for (const dir of dirs) {
|
|
@@ -639,14 +687,14 @@ async function createDirectories(targetDir, options, result) {
|
|
|
639
687
|
* Write settings.json
|
|
640
688
|
*/
|
|
641
689
|
async function writeSettings(targetDir, options, result) {
|
|
642
|
-
const settingsPath = path.join(targetDir, '.
|
|
690
|
+
const settingsPath = path.join(targetDir, '.opencode', 'settings.json');
|
|
643
691
|
if (fs.existsSync(settingsPath) && !options.force) {
|
|
644
|
-
result.skipped.push('.
|
|
692
|
+
result.skipped.push('.opencode/settings.json');
|
|
645
693
|
return;
|
|
646
694
|
}
|
|
647
695
|
const content = generateSettingsJson(options);
|
|
648
696
|
fs.writeFileSync(settingsPath, content, 'utf-8');
|
|
649
|
-
result.created.files.push('.
|
|
697
|
+
result.created.files.push('.opencode/settings.json');
|
|
650
698
|
}
|
|
651
699
|
/**
|
|
652
700
|
* Write .mcp.json
|
|
@@ -666,7 +714,7 @@ async function writeMCPConfig(targetDir, options, result) {
|
|
|
666
714
|
*/
|
|
667
715
|
async function copySkills(targetDir, options, result) {
|
|
668
716
|
const skillsConfig = options.skills;
|
|
669
|
-
const targetSkillsDir = path.join(targetDir, '.
|
|
717
|
+
const targetSkillsDir = path.join(targetDir, '.opencode', 'skills');
|
|
670
718
|
// Determine which skills to copy
|
|
671
719
|
const skillsToCopy = [];
|
|
672
720
|
if (skillsConfig.all) {
|
|
@@ -700,11 +748,11 @@ async function copySkills(targetDir, options, result) {
|
|
|
700
748
|
if (fs.existsSync(sourcePath)) {
|
|
701
749
|
if (!fs.existsSync(targetPath) || options.force) {
|
|
702
750
|
copyDirRecursive(sourcePath, targetPath);
|
|
703
|
-
result.created.files.push(`.
|
|
751
|
+
result.created.files.push(`.opencode/skills/${skillName}`);
|
|
704
752
|
result.summary.skillsCount++;
|
|
705
753
|
}
|
|
706
754
|
else {
|
|
707
|
-
result.skipped.push(`.
|
|
755
|
+
result.skipped.push(`.opencode/skills/${skillName}`);
|
|
708
756
|
}
|
|
709
757
|
}
|
|
710
758
|
}
|
|
@@ -714,7 +762,7 @@ async function copySkills(targetDir, options, result) {
|
|
|
714
762
|
*/
|
|
715
763
|
async function copyCommands(targetDir, options, result) {
|
|
716
764
|
const commandsConfig = options.commands;
|
|
717
|
-
const targetCommandsDir = path.join(targetDir, '.
|
|
765
|
+
const targetCommandsDir = path.join(targetDir, '.opencode', 'commands');
|
|
718
766
|
// Determine which commands to copy
|
|
719
767
|
const commandsToCopy = [];
|
|
720
768
|
if (commandsConfig.all) {
|
|
@@ -756,11 +804,11 @@ async function copyCommands(targetDir, options, result) {
|
|
|
756
804
|
else {
|
|
757
805
|
fs.copyFileSync(sourcePath, targetPath);
|
|
758
806
|
}
|
|
759
|
-
result.created.files.push(`.
|
|
807
|
+
result.created.files.push(`.opencode/commands/${cmdName}`);
|
|
760
808
|
result.summary.commandsCount++;
|
|
761
809
|
}
|
|
762
810
|
else {
|
|
763
|
-
result.skipped.push(`.
|
|
811
|
+
result.skipped.push(`.opencode/commands/${cmdName}`);
|
|
764
812
|
}
|
|
765
813
|
}
|
|
766
814
|
}
|
|
@@ -770,7 +818,7 @@ async function copyCommands(targetDir, options, result) {
|
|
|
770
818
|
*/
|
|
771
819
|
async function copyAgents(targetDir, options, result) {
|
|
772
820
|
const agentsConfig = options.agents;
|
|
773
|
-
const targetAgentsDir = path.join(targetDir, '.
|
|
821
|
+
const targetAgentsDir = path.join(targetDir, '.opencode', 'agents');
|
|
774
822
|
// Determine which agents to copy
|
|
775
823
|
const agentsToCopy = [];
|
|
776
824
|
if (agentsConfig.all) {
|
|
@@ -816,10 +864,10 @@ async function copyAgents(targetDir, options, result) {
|
|
|
816
864
|
const yamlFiles = countFiles(sourcePath, '.yaml');
|
|
817
865
|
const mdFiles = countFiles(sourcePath, '.md');
|
|
818
866
|
result.summary.agentsCount += yamlFiles + mdFiles;
|
|
819
|
-
result.created.files.push(`.
|
|
867
|
+
result.created.files.push(`.opencode/agents/${agentCategory}`);
|
|
820
868
|
}
|
|
821
869
|
else {
|
|
822
|
-
result.skipped.push(`.
|
|
870
|
+
result.skipped.push(`.opencode/agents/${agentCategory}`);
|
|
823
871
|
}
|
|
824
872
|
}
|
|
825
873
|
}
|
|
@@ -834,21 +882,21 @@ function findSourceHelpersDir(sourceBaseDir) {
|
|
|
834
882
|
const SENTINEL_FILE = 'hook-handler.cjs'; // Must exist in valid source
|
|
835
883
|
// If explicit source base directory is provided, check it first
|
|
836
884
|
if (sourceBaseDir) {
|
|
837
|
-
possiblePaths.push(path.join(sourceBaseDir, '.
|
|
885
|
+
possiblePaths.push(path.join(sourceBaseDir, '.opencode', 'helpers'));
|
|
838
886
|
}
|
|
839
887
|
// Strategy 1: require.resolve to find package root (most reliable for npx)
|
|
840
888
|
try {
|
|
841
889
|
const esmRequire = createRequire(import.meta.url);
|
|
842
890
|
const pkgJsonPath = esmRequire.resolve('@claude-flow/cli/package.json');
|
|
843
891
|
const pkgRoot = path.dirname(pkgJsonPath);
|
|
844
|
-
possiblePaths.push(path.join(pkgRoot, '.
|
|
892
|
+
possiblePaths.push(path.join(pkgRoot, '.opencode', 'helpers'));
|
|
845
893
|
}
|
|
846
894
|
catch {
|
|
847
895
|
// Not installed as a package — skip
|
|
848
896
|
}
|
|
849
897
|
// Strategy 2: __dirname-based (dist/src/init -> package root)
|
|
850
898
|
const packageRoot = path.resolve(__dirname, '..', '..', '..');
|
|
851
|
-
const packageHelpers = path.join(packageRoot, '.
|
|
899
|
+
const packageHelpers = path.join(packageRoot, '.opencode', 'helpers');
|
|
852
900
|
possiblePaths.push(packageHelpers);
|
|
853
901
|
// Strategy 3: Walk up from __dirname looking for package root
|
|
854
902
|
let currentDir = __dirname;
|
|
@@ -856,15 +904,15 @@ function findSourceHelpersDir(sourceBaseDir) {
|
|
|
856
904
|
const parentDir = path.dirname(currentDir);
|
|
857
905
|
if (parentDir === currentDir)
|
|
858
906
|
break; // hit filesystem root
|
|
859
|
-
const helpersPath = path.join(parentDir, '.
|
|
907
|
+
const helpersPath = path.join(parentDir, '.opencode', 'helpers');
|
|
860
908
|
possiblePaths.push(helpersPath);
|
|
861
909
|
currentDir = parentDir;
|
|
862
910
|
}
|
|
863
911
|
// Strategy 4: Check cwd-relative paths (for local dev)
|
|
864
912
|
const cwdBased = [
|
|
865
|
-
path.join(process.cwd(), '.
|
|
866
|
-
path.join(process.cwd(), '..', '.
|
|
867
|
-
path.join(process.cwd(), '..', '..', '.
|
|
913
|
+
path.join(process.cwd(), '.opencode', 'helpers'),
|
|
914
|
+
path.join(process.cwd(), '..', '.opencode', 'helpers'),
|
|
915
|
+
path.join(process.cwd(), '..', '..', '.opencode', 'helpers'),
|
|
868
916
|
];
|
|
869
917
|
possiblePaths.push(...cwdBased);
|
|
870
918
|
// Return first path that exists AND contains the sentinel file
|
|
@@ -879,7 +927,7 @@ function findSourceHelpersDir(sourceBaseDir) {
|
|
|
879
927
|
* Write helper scripts
|
|
880
928
|
*/
|
|
881
929
|
async function writeHelpers(targetDir, options, result) {
|
|
882
|
-
const helpersDir = path.join(targetDir, '.
|
|
930
|
+
const helpersDir = path.join(targetDir, '.opencode', 'helpers');
|
|
883
931
|
// Find source helpers directory (works for npm package and local dev)
|
|
884
932
|
const sourceHelpersDir = findSourceHelpersDir(options.sourceBaseDir);
|
|
885
933
|
// Try to copy existing helpers from source first
|
|
@@ -898,11 +946,11 @@ async function writeHelpers(targetDir, options, result) {
|
|
|
898
946
|
if (file.endsWith('.sh') || file.endsWith('.mjs')) {
|
|
899
947
|
fs.chmodSync(destPath, '755');
|
|
900
948
|
}
|
|
901
|
-
result.created.files.push(`.
|
|
949
|
+
result.created.files.push(`.opencode/helpers/${file}`);
|
|
902
950
|
copiedCount++;
|
|
903
951
|
}
|
|
904
952
|
else {
|
|
905
|
-
result.skipped.push(`.
|
|
953
|
+
result.skipped.push(`.opencode/helpers/${file}`);
|
|
906
954
|
}
|
|
907
955
|
}
|
|
908
956
|
if (copiedCount > 0) {
|
|
@@ -928,26 +976,26 @@ async function writeHelpers(targetDir, options, result) {
|
|
|
928
976
|
if (!name.endsWith('.js')) {
|
|
929
977
|
fs.chmodSync(filePath, '755');
|
|
930
978
|
}
|
|
931
|
-
result.created.files.push(`.
|
|
979
|
+
result.created.files.push(`.opencode/helpers/${name}`);
|
|
932
980
|
}
|
|
933
981
|
else {
|
|
934
|
-
result.skipped.push(`.
|
|
982
|
+
result.skipped.push(`.opencode/helpers/${name}`);
|
|
935
983
|
}
|
|
936
984
|
}
|
|
937
985
|
}
|
|
938
986
|
/**
|
|
939
|
-
* Find source .
|
|
987
|
+
* Find source .opencode directory for statusline files
|
|
940
988
|
*/
|
|
941
989
|
function findSourceClaudeDir(sourceBaseDir) {
|
|
942
990
|
const possiblePaths = [];
|
|
943
991
|
// If explicit source base directory is provided, check it first
|
|
944
992
|
if (sourceBaseDir) {
|
|
945
|
-
possiblePaths.push(path.join(sourceBaseDir, '.
|
|
993
|
+
possiblePaths.push(path.join(sourceBaseDir, '.opencode'));
|
|
946
994
|
}
|
|
947
|
-
// IMPORTANT: Check the package's own .
|
|
995
|
+
// IMPORTANT: Check the package's own .opencode directory
|
|
948
996
|
// Go up 3 levels: dist/src/init -> dist/src -> dist -> root
|
|
949
997
|
const packageRoot = path.resolve(__dirname, '..', '..', '..');
|
|
950
|
-
const packageClaude = path.join(packageRoot, '.
|
|
998
|
+
const packageClaude = path.join(packageRoot, '.opencode');
|
|
951
999
|
if (fs.existsSync(packageClaude)) {
|
|
952
1000
|
possiblePaths.unshift(packageClaude); // Add to beginning (highest priority)
|
|
953
1001
|
}
|
|
@@ -955,7 +1003,7 @@ function findSourceClaudeDir(sourceBaseDir) {
|
|
|
955
1003
|
let currentDir = __dirname;
|
|
956
1004
|
for (let i = 0; i < 10; i++) {
|
|
957
1005
|
const parentDir = path.dirname(currentDir);
|
|
958
|
-
const claudePath = path.join(parentDir, '.
|
|
1006
|
+
const claudePath = path.join(parentDir, '.opencode');
|
|
959
1007
|
if (fs.existsSync(claudePath)) {
|
|
960
1008
|
possiblePaths.push(claudePath);
|
|
961
1009
|
}
|
|
@@ -972,9 +1020,9 @@ function findSourceClaudeDir(sourceBaseDir) {
|
|
|
972
1020
|
* Write statusline configuration
|
|
973
1021
|
*/
|
|
974
1022
|
async function writeStatusline(targetDir, options, result) {
|
|
975
|
-
const claudeDir = path.join(targetDir, '.
|
|
976
|
-
const helpersDir = path.join(targetDir, '.
|
|
977
|
-
// Find source .
|
|
1023
|
+
const claudeDir = path.join(targetDir, '.opencode');
|
|
1024
|
+
const helpersDir = path.join(targetDir, '.opencode', 'helpers');
|
|
1025
|
+
// Find source .opencode directory (works for npm package and local dev)
|
|
978
1026
|
const sourceClaudeDir = findSourceClaudeDir(options.sourceBaseDir);
|
|
979
1027
|
// Try to copy existing advanced statusline files from source
|
|
980
1028
|
const advancedStatuslineFiles = [
|
|
@@ -992,10 +1040,10 @@ async function writeStatusline(targetDir, options, result) {
|
|
|
992
1040
|
if (file.src.endsWith('.sh') || file.src.endsWith('.mjs')) {
|
|
993
1041
|
fs.chmodSync(destPath, '755');
|
|
994
1042
|
}
|
|
995
|
-
result.created.files.push(`.
|
|
1043
|
+
result.created.files.push(`.opencode/${file.dest}`);
|
|
996
1044
|
}
|
|
997
1045
|
else {
|
|
998
|
-
result.skipped.push(`.
|
|
1046
|
+
result.skipped.push(`.opencode/${file.dest}`);
|
|
999
1047
|
}
|
|
1000
1048
|
}
|
|
1001
1049
|
}
|
|
@@ -1006,22 +1054,22 @@ async function writeStatusline(targetDir, options, result) {
|
|
|
1006
1054
|
const statuslinePath = path.join(helpersDir, 'statusline.cjs');
|
|
1007
1055
|
if (!fs.existsSync(statuslinePath) || options.force) {
|
|
1008
1056
|
fs.writeFileSync(statuslinePath, statuslineScript, 'utf-8');
|
|
1009
|
-
result.created.files.push('.
|
|
1057
|
+
result.created.files.push('.opencode/helpers/statusline.cjs');
|
|
1010
1058
|
}
|
|
1011
1059
|
else {
|
|
1012
|
-
result.skipped.push('.
|
|
1060
|
+
result.skipped.push('.opencode/helpers/statusline.cjs');
|
|
1013
1061
|
}
|
|
1014
1062
|
}
|
|
1015
1063
|
/**
|
|
1016
|
-
* Write runtime configuration (.
|
|
1064
|
+
* Write runtime configuration (.opencode-flow/)
|
|
1017
1065
|
*/
|
|
1018
1066
|
async function writeRuntimeConfig(targetDir, options, result) {
|
|
1019
|
-
const configPath = path.join(targetDir, '.
|
|
1067
|
+
const configPath = path.join(targetDir, '.opencode-flow', 'config.yaml');
|
|
1020
1068
|
if (fs.existsSync(configPath) && !options.force) {
|
|
1021
|
-
result.skipped.push('.
|
|
1069
|
+
result.skipped.push('.opencode-flow/config.yaml');
|
|
1022
1070
|
return;
|
|
1023
1071
|
}
|
|
1024
|
-
const config = `#
|
|
1072
|
+
const config = `# OpenCode Orchestrator Runtime Configuration
|
|
1025
1073
|
# Generated: ${new Date().toISOString()}
|
|
1026
1074
|
|
|
1027
1075
|
version: "3.0.0"
|
|
@@ -1035,7 +1083,7 @@ swarm:
|
|
|
1035
1083
|
memory:
|
|
1036
1084
|
backend: ${options.runtime.memoryBackend}
|
|
1037
1085
|
enableHNSW: ${options.runtime.enableHNSW}
|
|
1038
|
-
persistPath: .
|
|
1086
|
+
persistPath: .opencode-flow/data
|
|
1039
1087
|
cacheSize: 100
|
|
1040
1088
|
# ADR-049: Self-Learning Memory
|
|
1041
1089
|
learningBridge:
|
|
@@ -1055,7 +1103,7 @@ memory:
|
|
|
1055
1103
|
|
|
1056
1104
|
neural:
|
|
1057
1105
|
enabled: ${options.runtime.enableNeural}
|
|
1058
|
-
modelPath: .
|
|
1106
|
+
modelPath: .opencode-flow/neural
|
|
1059
1107
|
|
|
1060
1108
|
hooks:
|
|
1061
1109
|
enabled: true
|
|
@@ -1066,9 +1114,9 @@ mcp:
|
|
|
1066
1114
|
port: ${options.mcp.port}
|
|
1067
1115
|
`;
|
|
1068
1116
|
fs.writeFileSync(configPath, config, 'utf-8');
|
|
1069
|
-
result.created.files.push('.
|
|
1117
|
+
result.created.files.push('.opencode-flow/config.yaml');
|
|
1070
1118
|
// Write .gitignore
|
|
1071
|
-
const gitignorePath = path.join(targetDir, '.
|
|
1119
|
+
const gitignorePath = path.join(targetDir, '.opencode-flow', '.gitignore');
|
|
1072
1120
|
const gitignore = `# Claude Flow runtime files
|
|
1073
1121
|
data/
|
|
1074
1122
|
logs/
|
|
@@ -1079,7 +1127,7 @@ neural/
|
|
|
1079
1127
|
`;
|
|
1080
1128
|
if (!fs.existsSync(gitignorePath) || options.force) {
|
|
1081
1129
|
fs.writeFileSync(gitignorePath, gitignore, 'utf-8');
|
|
1082
|
-
result.created.files.push('.
|
|
1130
|
+
result.created.files.push('.opencode-flow/.gitignore');
|
|
1083
1131
|
}
|
|
1084
1132
|
// Write CAPABILITIES.md with full system overview
|
|
1085
1133
|
await writeCapabilitiesDoc(targetDir, options, result);
|
|
@@ -1089,9 +1137,9 @@ neural/
|
|
|
1089
1137
|
* Creates baseline data so statusline shows meaningful state instead of all zeros
|
|
1090
1138
|
*/
|
|
1091
1139
|
async function writeInitialMetrics(targetDir, options, result) {
|
|
1092
|
-
const metricsDir = path.join(targetDir, '.
|
|
1093
|
-
const learningDir = path.join(targetDir, '.
|
|
1094
|
-
const securityDir = path.join(targetDir, '.
|
|
1140
|
+
const metricsDir = path.join(targetDir, '.opencode-flow', 'metrics');
|
|
1141
|
+
const learningDir = path.join(targetDir, '.opencode-flow', 'learning');
|
|
1142
|
+
const securityDir = path.join(targetDir, '.opencode-flow', 'security');
|
|
1095
1143
|
// Ensure directories exist
|
|
1096
1144
|
for (const dir of [metricsDir, learningDir, securityDir]) {
|
|
1097
1145
|
if (!fs.existsSync(dir)) {
|
|
@@ -1128,7 +1176,7 @@ async function writeInitialMetrics(targetDir, options, result) {
|
|
|
1128
1176
|
_note: 'Metrics will update as you use Claude Flow. Run: npx @claude-flow/cli@latest daemon start'
|
|
1129
1177
|
};
|
|
1130
1178
|
fs.writeFileSync(progressPath, JSON.stringify(progress, null, 2), 'utf-8');
|
|
1131
|
-
result.created.files.push('.
|
|
1179
|
+
result.created.files.push('.opencode-flow/metrics/v3-progress.json');
|
|
1132
1180
|
}
|
|
1133
1181
|
// Create initial swarm-activity.json
|
|
1134
1182
|
const activityPath = path.join(metricsDir, 'swarm-activity.json');
|
|
@@ -1152,7 +1200,7 @@ async function writeInitialMetrics(targetDir, options, result) {
|
|
|
1152
1200
|
_initialized: true
|
|
1153
1201
|
};
|
|
1154
1202
|
fs.writeFileSync(activityPath, JSON.stringify(activity, null, 2), 'utf-8');
|
|
1155
|
-
result.created.files.push('.
|
|
1203
|
+
result.created.files.push('.opencode-flow/metrics/swarm-activity.json');
|
|
1156
1204
|
}
|
|
1157
1205
|
// Create initial learning.json
|
|
1158
1206
|
const learningPath = path.join(metricsDir, 'learning.json');
|
|
@@ -1175,7 +1223,7 @@ async function writeInitialMetrics(targetDir, options, result) {
|
|
|
1175
1223
|
_note: 'Intelligence grows as you use Claude Flow'
|
|
1176
1224
|
};
|
|
1177
1225
|
fs.writeFileSync(learningPath, JSON.stringify(learning, null, 2), 'utf-8');
|
|
1178
|
-
result.created.files.push('.
|
|
1226
|
+
result.created.files.push('.opencode-flow/metrics/learning.json');
|
|
1179
1227
|
}
|
|
1180
1228
|
// Create initial audit-status.json
|
|
1181
1229
|
const auditPath = path.join(securityDir, 'audit-status.json');
|
|
@@ -1189,21 +1237,21 @@ async function writeInitialMetrics(targetDir, options, result) {
|
|
|
1189
1237
|
_note: 'Run: npx @claude-flow/cli@latest security scan'
|
|
1190
1238
|
};
|
|
1191
1239
|
fs.writeFileSync(auditPath, JSON.stringify(audit, null, 2), 'utf-8');
|
|
1192
|
-
result.created.files.push('.
|
|
1240
|
+
result.created.files.push('.opencode-flow/security/audit-status.json');
|
|
1193
1241
|
}
|
|
1194
1242
|
}
|
|
1195
1243
|
/**
|
|
1196
1244
|
* Write CAPABILITIES.md - comprehensive overview of all Claude Flow features
|
|
1197
1245
|
*/
|
|
1198
1246
|
async function writeCapabilitiesDoc(targetDir, options, result) {
|
|
1199
|
-
const capabilitiesPath = path.join(targetDir, '.
|
|
1247
|
+
const capabilitiesPath = path.join(targetDir, '.opencode-flow', 'CAPABILITIES.md');
|
|
1200
1248
|
if (fs.existsSync(capabilitiesPath) && !options.force) {
|
|
1201
|
-
result.skipped.push('.
|
|
1249
|
+
result.skipped.push('.opencode-flow/CAPABILITIES.md');
|
|
1202
1250
|
return;
|
|
1203
1251
|
}
|
|
1204
|
-
const capabilities = `#
|
|
1252
|
+
const capabilities = `# OpenCode Orchestrator - Complete Capabilities Reference
|
|
1205
1253
|
> Generated: ${new Date().toISOString()}
|
|
1206
|
-
> Full documentation: https://github.com/
|
|
1254
|
+
> Full documentation: https://github.com/pedrocosta95/opencode-orchestrator
|
|
1207
1255
|
|
|
1208
1256
|
## 📋 Table of Contents
|
|
1209
1257
|
|
|
@@ -1221,7 +1269,7 @@ async function writeCapabilitiesDoc(targetDir, options, result) {
|
|
|
1221
1269
|
|
|
1222
1270
|
## Overview
|
|
1223
1271
|
|
|
1224
|
-
|
|
1272
|
+
OpenCode Orchestrator is a domain-driven design architecture for multi-agent AI coordination with:
|
|
1225
1273
|
|
|
1226
1274
|
- **15-Agent Swarm Coordination** with hierarchical and mesh topologies
|
|
1227
1275
|
- **HNSW Vector Search** - 150x-12,500x faster pattern retrieval
|
|
@@ -1453,9 +1501,9 @@ npx @claude-flow/cli@latest doctor --fix
|
|
|
1453
1501
|
**MemoryGraph** - Builds a knowledge graph from entry references. PageRank identifies influential insights. Communities group related knowledge. Graph-aware ranking blends vector + structural scores.
|
|
1454
1502
|
|
|
1455
1503
|
**AgentMemoryScope** - Maps Claude Code 3-scope directories:
|
|
1456
|
-
- \`project\`: \`<gitRoot>/.
|
|
1457
|
-
- \`local\`: \`<gitRoot>/.
|
|
1458
|
-
- \`user\`: \`~/.
|
|
1504
|
+
- \`project\`: \`<gitRoot>/.opencode/agent-memory/<agent>/\`
|
|
1505
|
+
- \`local\`: \`<gitRoot>/.opencode/agent-memory-local/<agent>/\`
|
|
1506
|
+
- \`user\`: \`~/.opencode/agent-memory/<agent>/\`
|
|
1459
1507
|
|
|
1460
1508
|
High-confidence insights (>0.8) can transfer between agents.
|
|
1461
1509
|
|
|
@@ -1589,7 +1637,7 @@ npx @claude-flow/cli@latest hooks worker dispatch --trigger optimize
|
|
|
1589
1637
|
|
|
1590
1638
|
### File Structure
|
|
1591
1639
|
\`\`\`
|
|
1592
|
-
.
|
|
1640
|
+
.opencode-flow/
|
|
1593
1641
|
├── config.yaml # Runtime configuration
|
|
1594
1642
|
├── CAPABILITIES.md # This file
|
|
1595
1643
|
├── data/ # Memory storage
|
|
@@ -1606,22 +1654,22 @@ npx @claude-flow/cli@latest hooks worker dispatch --trigger optimize
|
|
|
1606
1654
|
**Issues**: https://github.com/ruvnet/claude-flow/issues
|
|
1607
1655
|
`;
|
|
1608
1656
|
fs.writeFileSync(capabilitiesPath, capabilities, 'utf-8');
|
|
1609
|
-
result.created.files.push('.
|
|
1657
|
+
result.created.files.push('.opencode-flow/CAPABILITIES.md');
|
|
1610
1658
|
}
|
|
1611
1659
|
/**
|
|
1612
|
-
* Write
|
|
1660
|
+
* Write SKILL.md with swarm guidance
|
|
1613
1661
|
*/
|
|
1614
|
-
async function
|
|
1615
|
-
const
|
|
1616
|
-
if (fs.existsSync(
|
|
1617
|
-
result.skipped.push('
|
|
1662
|
+
async function writeSkillMd(targetDir, options, result) {
|
|
1663
|
+
const skillMdPath = path.join(targetDir, 'SKILL.md');
|
|
1664
|
+
if (fs.existsSync(skillMdPath) && !options.force) {
|
|
1665
|
+
result.skipped.push('SKILL.md');
|
|
1618
1666
|
return;
|
|
1619
1667
|
}
|
|
1620
1668
|
// Determine template: explicit option > infer from components > 'standard'
|
|
1621
1669
|
const inferredTemplate = (!options.components.commands && !options.components.agents) ? 'minimal' : undefined;
|
|
1622
|
-
const content =
|
|
1623
|
-
fs.writeFileSync(
|
|
1624
|
-
result.created.files.push('
|
|
1670
|
+
const content = generateSkillMd(options, inferredTemplate);
|
|
1671
|
+
fs.writeFileSync(skillMdPath, content, 'utf-8');
|
|
1672
|
+
result.created.files.push('SKILL.md');
|
|
1625
1673
|
}
|
|
1626
1674
|
/**
|
|
1627
1675
|
* Find source directory for skills/commands/agents
|
|
@@ -1631,24 +1679,24 @@ function findSourceDir(type, sourceBaseDir) {
|
|
|
1631
1679
|
const possiblePaths = [];
|
|
1632
1680
|
// If explicit source base directory is provided, use it first
|
|
1633
1681
|
if (sourceBaseDir) {
|
|
1634
|
-
possiblePaths.push(path.join(sourceBaseDir, '.
|
|
1682
|
+
possiblePaths.push(path.join(sourceBaseDir, '.opencode', type));
|
|
1635
1683
|
}
|
|
1636
|
-
// IMPORTANT: Check the package's own .
|
|
1684
|
+
// IMPORTANT: Check the package's own .opencode directory first
|
|
1637
1685
|
// This is the primary path when running as an npm package
|
|
1638
1686
|
// __dirname is typically /path/to/node_modules/@claude-flow/cli/dist/src/init
|
|
1639
1687
|
// We need to go up 3 levels to reach the package root (dist/src/init -> dist/src -> dist -> root)
|
|
1640
1688
|
const packageRoot = path.resolve(__dirname, '..', '..', '..');
|
|
1641
|
-
const packageDotClaude = path.join(packageRoot, '.
|
|
1689
|
+
const packageDotClaude = path.join(packageRoot, '.opencode', type);
|
|
1642
1690
|
if (fs.existsSync(packageDotClaude)) {
|
|
1643
1691
|
possiblePaths.unshift(packageDotClaude); // Add to beginning (highest priority)
|
|
1644
1692
|
}
|
|
1645
1693
|
// From dist/src/init -> go up to project root
|
|
1646
1694
|
const distPath = __dirname;
|
|
1647
|
-
// Try to find the project root by looking for .
|
|
1695
|
+
// Try to find the project root by looking for .opencode directory
|
|
1648
1696
|
let currentDir = distPath;
|
|
1649
1697
|
for (let i = 0; i < 10; i++) {
|
|
1650
1698
|
const parentDir = path.dirname(currentDir);
|
|
1651
|
-
const dotClaudePath = path.join(parentDir, '.
|
|
1699
|
+
const dotClaudePath = path.join(parentDir, '.opencode', type);
|
|
1652
1700
|
if (fs.existsSync(dotClaudePath)) {
|
|
1653
1701
|
possiblePaths.push(dotClaudePath);
|
|
1654
1702
|
}
|
|
@@ -1656,14 +1704,14 @@ function findSourceDir(type, sourceBaseDir) {
|
|
|
1656
1704
|
}
|
|
1657
1705
|
// Also check relative to process.cwd() for development
|
|
1658
1706
|
const cwdBased = [
|
|
1659
|
-
path.join(process.cwd(), '.
|
|
1660
|
-
path.join(process.cwd(), '..', '.
|
|
1661
|
-
path.join(process.cwd(), '..', '..', '.
|
|
1707
|
+
path.join(process.cwd(), '.opencode', type),
|
|
1708
|
+
path.join(process.cwd(), '..', '.opencode', type),
|
|
1709
|
+
path.join(process.cwd(), '..', '..', '.opencode', type),
|
|
1662
1710
|
];
|
|
1663
1711
|
possiblePaths.push(...cwdBased);
|
|
1664
1712
|
// Check v2 directory for agents
|
|
1665
1713
|
if (type === 'agents') {
|
|
1666
|
-
possiblePaths.push(path.join(process.cwd(), 'v2', '.
|
|
1714
|
+
possiblePaths.push(path.join(process.cwd(), 'v2', '.opencode', type), path.join(process.cwd(), '..', 'v2', '.opencode', type));
|
|
1667
1715
|
}
|
|
1668
1716
|
// Plugin directory
|
|
1669
1717
|
possiblePaths.push(path.join(process.cwd(), 'plugin', type), path.join(process.cwd(), '..', 'plugin', type));
|