agi-farm 1.9.0 → 3.3.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 +49 -2
- package/dist/index.d.ts +13 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -59
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +67 -38
- package/package.json +12 -25
- package/scripts/agi-farm.js +48 -32
- package/scripts/lib/blueprints.js +421 -0
- package/scripts/paperclip.js +68 -0
- package/scripts/setup.js +616 -360
- package/scripts/sync-lobsterboard-upstream.js +7 -1
- package/server/paperclip-bridge.js +390 -0
- package/server/paperclip-sync.js +132 -0
- package/skills/agi-farm/tools/create_company.js +94 -0
- package/skills/agi-farm/tools/create_project.js +88 -0
- package/skills/agi-farm/tools/create_task.js +106 -0
- package/skills/agi-farm/tools/hire_specialist.js +138 -0
- package/skills/agi-farm/tools/lib/resolve-company.js +90 -0
- package/skills/agi-farm/tools/list_projects.js +63 -0
- package/skills/agi-farm/tools/manage_board.js +110 -0
- package/skills/agi-farm/tools/update_task.js +126 -0
- package/templates/SOUL.md.main +84 -0
- package/dashboard-dist/assets/Agents-hD22o0iq.js +0 -1
- package/dashboard-dist/assets/Alerts-T-KcEJKx.js +0 -1
- package/dashboard-dist/assets/Approvals-BHXY6xD5.js +0 -1
- package/dashboard-dist/assets/AuditLog-Cc1GUGYz.js +0 -1
- package/dashboard-dist/assets/Budget-DRJWqsop.js +0 -1
- package/dashboard-dist/assets/Comms-DT2o5TCi.js +0 -1
- package/dashboard-dist/assets/Crons-EoAAeNe7.js +0 -1
- package/dashboard-dist/assets/Decisions-B3i1Rijg.js +0 -3
- package/dashboard-dist/assets/Failures-CaEvQ0t1.js +0 -2
- package/dashboard-dist/assets/HITL-F6AxJIK6.js +0 -1
- package/dashboard-dist/assets/Jobs-Ch4D8P85.js +0 -1
- package/dashboard-dist/assets/Knowledge-C92uZhl9.js +0 -1
- package/dashboard-dist/assets/Memory-DFU5CtTT.js +0 -2
- package/dashboard-dist/assets/OKRs-Dt0HzTQQ.js +0 -1
- package/dashboard-dist/assets/Overview-Cp6HOIJF.js +0 -2
- package/dashboard-dist/assets/Policies-CbemgLkX.js +0 -1
- package/dashboard-dist/assets/Processes-btq7Pyex.js +0 -1
- package/dashboard-dist/assets/Projects-DGmgA8FX.js +0 -1
- package/dashboard-dist/assets/Security-BVLBAnlu.js +0 -1
- package/dashboard-dist/assets/Settings-D9R5JTPF.js +0 -1
- package/dashboard-dist/assets/Tasks-lXCgffoh.js +0 -1
- package/dashboard-dist/assets/Usage-Cvfmkgit.js +0 -1
- package/dashboard-dist/assets/Velocity-DzCZH_YB.js +0 -1
- package/dashboard-dist/assets/charts-CjCN_e1M.js +0 -36
- package/dashboard-dist/assets/index-B3IWXYRY.js +0 -2
- package/dashboard-dist/assets/index-Cti3NWck.css +0 -1
- package/dashboard-dist/assets/vendor-gUVFsxOc.js +0 -9
- package/dashboard-dist/index.html +0 -16
- package/dashboard-dist/vite.svg +0 -1
- package/scripts/dashboard.js +0 -49
- package/server/dashboard.js +0 -2098
- package/server/services/audit.js +0 -17
- package/server/services/intake.js +0 -156
- package/server/services/metering.js +0 -64
- package/server/services/projects.js +0 -220
- package/server/services/timeline.js +0 -71
- package/server/updater.js +0 -154
package/package.json
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agi-farm",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Multi-agent AI team builder for OpenClaw — bootstrap complete teams with auto-dispatcher,
|
|
3
|
+
"version": "3.3.0",
|
|
4
|
+
"description": "Multi-agent AI team builder for OpenClaw — bootstrap complete teams with Paperclip dashboard, auto-dispatcher, and infrastructure",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"agi-farm": "scripts/
|
|
9
|
-
"agi-farm-teardown": "scripts/teardown.js",
|
|
10
|
-
"agi-farm-status": "scripts/status.js",
|
|
11
|
-
"agi-farm-dashboard": "scripts/dashboard.js",
|
|
12
|
-
"agi-farm-dispatch": "scripts/dispatch.js",
|
|
13
|
-
"agi-farm-export": "scripts/export.js",
|
|
14
|
-
"agi-farm-rebuild": "scripts/rebuild.js",
|
|
15
|
-
"agi-farm-launchagent": "scripts/install-launchagent.js"
|
|
8
|
+
"agi-farm": "scripts/agi-farm.js"
|
|
16
9
|
},
|
|
17
10
|
"license": "MIT",
|
|
18
11
|
"author": "oabdelmaksoud",
|
|
@@ -26,7 +19,7 @@
|
|
|
26
19
|
},
|
|
27
20
|
"files": [
|
|
28
21
|
"dist",
|
|
29
|
-
"
|
|
22
|
+
"paperclip",
|
|
30
23
|
"openclaw.plugin.json",
|
|
31
24
|
"server",
|
|
32
25
|
"scripts",
|
|
@@ -54,10 +47,8 @@
|
|
|
54
47
|
}
|
|
55
48
|
},
|
|
56
49
|
"scripts": {
|
|
57
|
-
"build:dashboard": "cd dashboard-react && npm run build",
|
|
58
|
-
"build:all": "npm run build && npm run build:dashboard && rm -rf dashboard-dist && cp -r dashboard-react/dist dashboard-dist",
|
|
59
|
-
"prepublishOnly": "npm run build:all",
|
|
60
50
|
"postinstall": "node scripts/validate-config.js",
|
|
51
|
+
"setup:paperclip": "cd paperclip && pnpm install",
|
|
61
52
|
"prebuild": "rm -rf dist tsconfig.tsbuildinfo",
|
|
62
53
|
"build": "tsc",
|
|
63
54
|
"dev": "tsc --watch",
|
|
@@ -65,11 +56,10 @@
|
|
|
65
56
|
"test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js",
|
|
66
57
|
"test:install": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --runInBand tests/install-*.test.js",
|
|
67
58
|
"test:install:real-openclaw": "bash scripts/test-install-smoke.sh",
|
|
68
|
-
"start-dashboard": "node
|
|
59
|
+
"start-dashboard": "node scripts/paperclip.js",
|
|
69
60
|
"validate": "node scripts/validate-config.js",
|
|
70
61
|
"lint": "eslint src --ext .ts,.js",
|
|
71
|
-
"
|
|
72
|
-
"sync:lobsterboard:check": "node scripts/sync-lobsterboard-upstream.js --dry-run"
|
|
62
|
+
"setup": "node scripts/setup.js"
|
|
73
63
|
},
|
|
74
64
|
"keywords": [
|
|
75
65
|
"openclaw",
|
|
@@ -81,28 +71,25 @@
|
|
|
81
71
|
"agentic-workflow",
|
|
82
72
|
"team-management",
|
|
83
73
|
"auto-dispatcher",
|
|
74
|
+
"paperclip",
|
|
84
75
|
"dashboard",
|
|
85
76
|
"cli-wizard",
|
|
86
77
|
"agi",
|
|
87
|
-
"collaborative-ai"
|
|
88
|
-
"crewai",
|
|
89
|
-
"langgraph",
|
|
90
|
-
"autogen"
|
|
78
|
+
"collaborative-ai"
|
|
91
79
|
],
|
|
92
80
|
"dependencies": {
|
|
93
81
|
"chalk": "^5.4.1",
|
|
94
|
-
"chokidar": "^4.0.1",
|
|
95
82
|
"commander": "^13.1.0",
|
|
96
83
|
"ejs": "^3.1.10",
|
|
97
|
-
"express": "^
|
|
84
|
+
"express": "^5.2.1",
|
|
98
85
|
"inquirer": "^12.4.1",
|
|
99
86
|
"open": "^10.1.0",
|
|
100
|
-
"ora": "^8.1.1"
|
|
87
|
+
"ora": "^8.1.1",
|
|
88
|
+
"tsx": "^4.19.0"
|
|
101
89
|
},
|
|
102
90
|
"devDependencies": {
|
|
103
91
|
"@eslint/js": "^9.21.0",
|
|
104
92
|
"@types/ejs": "^3.1.5",
|
|
105
|
-
"@types/express": "^5.0.0",
|
|
106
93
|
"@types/inquirer": "^9.0.8",
|
|
107
94
|
"@types/jest": "^29.5.14",
|
|
108
95
|
"@types/node": "^22.13.4",
|
package/scripts/agi-farm.js
CHANGED
|
@@ -1,52 +1,68 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* AGI Farm CLI
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* AGI Farm Professional CLI (v2.0)
|
|
4
|
+
*
|
|
5
|
+
* Main entry point for all AGI Farm automation commands.
|
|
6
|
+
* Built with Commander for a professional terminal experience.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { Command } from 'commander';
|
|
9
10
|
import { spawnSync } from 'child_process';
|
|
10
11
|
import path from 'path';
|
|
11
|
-
import fs from 'fs';
|
|
12
12
|
import { fileURLToPath } from 'url';
|
|
13
|
+
import fs from 'fs';
|
|
13
14
|
|
|
14
15
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
16
|
const __dirname = path.dirname(__filename);
|
|
17
|
+
const packageJson = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../package.json'), 'utf8'));
|
|
16
18
|
|
|
17
|
-
const
|
|
19
|
+
const program = new Command();
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
program
|
|
22
|
+
.name('agi-farm')
|
|
23
|
+
.description('Comprehensive toolset for AGI Farm team management')
|
|
24
|
+
.version(packageJson.version);
|
|
22
25
|
|
|
23
|
-
//
|
|
24
|
-
if (!command || !VALID_COMMANDS.includes(command)) {
|
|
25
|
-
// If the user meant a subcommand but typed it wrong, we could show help, but the historical behavior was to just run setup.
|
|
26
|
-
// For safety, let's keep the historical behavior of running the wizard if they just type `agi-farm`.
|
|
27
|
-
// However, if they typed `agi-farm status`, `command` will be 'status'.
|
|
26
|
+
// ── Subcommands ──────────────────────────────────────────────────────────────
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
command = 'setup';
|
|
32
|
-
} else {
|
|
33
|
-
// Valid command recognized, remove it from the args array representing the flags
|
|
34
|
-
args.shift();
|
|
35
|
-
}
|
|
28
|
+
function routeSubcommand(commandName, description, scriptOverride = null) {
|
|
29
|
+
const scriptPath = path.join(__dirname, `${scriptOverride || commandName}.js`);
|
|
36
30
|
|
|
37
|
-
|
|
31
|
+
if (!fs.existsSync(scriptPath)) {
|
|
32
|
+
console.error(`\x1b[31mError: Subcommand script not found: ${scriptPath}\x1b[0m`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
program
|
|
37
|
+
.command(`${commandName} [args...]`)
|
|
38
|
+
.description(description)
|
|
39
|
+
.allowUnknownOption()
|
|
40
|
+
.action(() => {
|
|
41
|
+
// We slice(3) to pass through all args after 'node agi-farm.js commandName'
|
|
42
|
+
const result = spawnSync(process.execPath, [scriptPath, ...process.argv.slice(3)], { stdio: 'inherit' });
|
|
43
|
+
process.exit(result.status ?? 0);
|
|
44
|
+
});
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
//
|
|
45
|
-
|
|
47
|
+
// Register all core commands
|
|
48
|
+
routeSubcommand('setup', 'Launch the Advanced Setup Wizard to build a new AGI team');
|
|
49
|
+
routeSubcommand('teardown', 'Safely stop and remove an existing AGI team and workspace');
|
|
50
|
+
routeSubcommand('status', 'Check real-time status, agent health, and project progress');
|
|
51
|
+
routeSubcommand('dashboard', 'Start the Paperclip dashboard (Web UI)', 'paperclip');
|
|
52
|
+
routeSubcommand('dispatch', 'Process the task queue and orchestrate agent assignments');
|
|
53
|
+
routeSubcommand('export', 'Bundle the workspace and team configuration for GitHub export');
|
|
54
|
+
routeSubcommand('rebuild', 'Regenerate SOUL.md files and re-sync components from templates');
|
|
55
|
+
routeSubcommand('launchagent', 'Install/Reset the macOS LaunchAgent for background persistence', 'install-launchagent');
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
console.error(`\x1b[31mFailed to start subcommand '${command}': ${result.error.message}\x1b[0m`);
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
57
|
+
// ── Default Behavior ────────────────────────────────────────────────────────
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
// If no arguments provided, show help
|
|
60
|
+
if (!process.argv.slice(2).length) {
|
|
61
|
+
program.outputHelp();
|
|
62
|
+
console.log('\n\x1b[36mTip: Run "agi-farm setup" to get started.\x1b[0m\n');
|
|
63
|
+
} else {
|
|
64
|
+
// If the first arg is not a command, we could assume 'setup' for backward compat,
|
|
65
|
+
// but professional CLIs usually require the command name.
|
|
66
|
+
// We'll require it for clarity.
|
|
67
|
+
program.parse(process.argv);
|
|
68
|
+
}
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AGI Farm Team Blueprints (v2.0)
|
|
3
|
+
* 15 specialized blueprints across 5 industry verticals
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const TEAM_BLUEPRINTS = {
|
|
7
|
+
// ── Software Engineering ───────────────────────────────────────────────────
|
|
8
|
+
'startup-mvp': {
|
|
9
|
+
name: 'Startup MVP',
|
|
10
|
+
emoji: '🚀',
|
|
11
|
+
industry: 'Software Engineering',
|
|
12
|
+
description: 'Rapid prototype development, proof-of-concept, MVP launches',
|
|
13
|
+
timeline: '1-2 weeks',
|
|
14
|
+
agents: [
|
|
15
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
16
|
+
{ id: 'forge', template: 'SOUL.md.forge', name: 'Forge', emoji: '⚒️', role: 'Backend Developer', workspace: 'forge' },
|
|
17
|
+
{ id: 'pixel', template: 'SOUL.md.pixel', name: 'Pixel', emoji: '🐛', role: 'Frontend Developer', workspace: 'pixel' },
|
|
18
|
+
{ id: 'vigil', template: 'SOUL.md.vigil', name: 'Vigil', emoji: '🛡️', role: 'QA Specialist', workspace: 'vigil' },
|
|
19
|
+
{ id: 'growth-hacker', template: 'agency-agents/marketing/growth-hacker.md', name: 'Growth Hacker', emoji: '📈', role: 'Growth & Experiments', workspace: 'growth-hacker' }
|
|
20
|
+
],
|
|
21
|
+
okrs: [
|
|
22
|
+
{ objective: 'Launch functional MVP', keyResults: ['Complete 5 core features', 'Zero critical bugs in production'] },
|
|
23
|
+
{ objective: 'Establish growth foundation', keyResults: ['Set up 3 growth experiments', 'Integrate analytics tracking'] }
|
|
24
|
+
],
|
|
25
|
+
crons: ['security-scan', 'velocity-report'],
|
|
26
|
+
featureFlags: { jobs: true, skills: true, memory: true, policy: true, approvals: true, metering: true },
|
|
27
|
+
hitlPolicy: { threshold: 0.7 },
|
|
28
|
+
starterProject: {
|
|
29
|
+
name: 'MVP Launch',
|
|
30
|
+
description: 'Initial build and launch of the minimum viable product',
|
|
31
|
+
tasks: [
|
|
32
|
+
{ id: 'mvp-1', title: 'Architect core backend', assigned_to: 'forge' },
|
|
33
|
+
{ id: 'mvp-2', title: 'Implement hero section UI', assigned_to: 'pixel' }
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
'fullstack-product': {
|
|
38
|
+
name: 'Full-Stack Product',
|
|
39
|
+
emoji: '🌐',
|
|
40
|
+
industry: 'Software Engineering',
|
|
41
|
+
description: 'Professional product development with full lifecycle support',
|
|
42
|
+
timeline: '4-8 weeks',
|
|
43
|
+
agents: [
|
|
44
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
45
|
+
{ id: 'vista', template: 'SOUL.md.vista', name: 'Vista', emoji: '🔭', role: 'Product Manager', workspace: 'vista' },
|
|
46
|
+
{ id: 'forge', template: 'SOUL.md.forge', name: 'Forge', emoji: '⚒️', role: 'Backend/API Developer', workspace: 'forge' },
|
|
47
|
+
{ id: 'pixel', template: 'SOUL.md.pixel', name: 'Pixel', emoji: '🐛', role: 'Frontend/UI Developer', workspace: 'pixel' },
|
|
48
|
+
{ id: 'vigil', template: 'SOUL.md.vigil', name: 'Vigil', emoji: '🛡️', role: 'QA Engineer', workspace: 'vigil' },
|
|
49
|
+
{ id: 'devops', template: 'agency-agents/engineering/devops-automator.md', name: 'DevOps', emoji: '♾️', role: 'Infrastructure/CI/CD', workspace: 'devops' }
|
|
50
|
+
],
|
|
51
|
+
okrs: [
|
|
52
|
+
{ objective: 'Build robust product architecture', keyResults: ['Design scalable database schema', 'Document all API contracts'] },
|
|
53
|
+
{ objective: 'High-quality implementation', keyResults: ['Maintain >80% test coverage', 'Pass all integration tests'] }
|
|
54
|
+
],
|
|
55
|
+
crons: ['security-scan', 'velocity-report', 'budget-check'],
|
|
56
|
+
featureFlags: { jobs: true, skills: true, memory: true, policy: true, approvals: true, metering: true },
|
|
57
|
+
hitlPolicy: { threshold: 0.75 },
|
|
58
|
+
starterProject: {
|
|
59
|
+
name: 'Project Foundation',
|
|
60
|
+
description: 'Setting up the base architecture and core features',
|
|
61
|
+
tasks: [
|
|
62
|
+
{ id: 'base-1', title: 'Define product requirements', assigned_to: 'vista' },
|
|
63
|
+
{ id: 'base-2', title: 'Configure CI/CD pipeline', assigned_to: 'devops' }
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
'mobile-first': {
|
|
68
|
+
name: 'Mobile-First App',
|
|
69
|
+
emoji: '📱',
|
|
70
|
+
industry: 'Software Engineering',
|
|
71
|
+
description: 'iOS/Android focus with cross-platform excellence',
|
|
72
|
+
timeline: '3-6 weeks',
|
|
73
|
+
agents: [
|
|
74
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
75
|
+
{ id: 'mobile-builder', template: 'agency-agents/engineering/mobile-app-builder.md', name: 'Mobile Build', emoji: '📲', role: 'Cross-Platform Dev', workspace: 'mobile' },
|
|
76
|
+
{ id: 'ui-designer', template: 'agency-agents/design/ui-designer.md', name: 'Designer', emoji: '🎨', role: 'Mobile UI/UX', workspace: 'designer' },
|
|
77
|
+
{ id: 'forge', template: 'SOUL.md.forge', name: 'Forge', emoji: '⚒️', role: 'Mobile API/Backend', workspace: 'forge' },
|
|
78
|
+
{ id: 'performance', template: 'agency-agents/testing/performance-benchmarker.md', name: 'Perf Check', emoji: '⚡', role: 'Quality & Speed', workspace: 'perf' }
|
|
79
|
+
],
|
|
80
|
+
okrs: [
|
|
81
|
+
{ objective: 'App Store Readiness', keyResults: ['Pass all mobile performance benchmarks', 'Complete all UI/UX mobile screens'] }
|
|
82
|
+
],
|
|
83
|
+
crons: ['security-scan', 'velocity-report'],
|
|
84
|
+
featureFlags: { jobs: true, skills: true, memory: true, policy: true, approvals: true, metering: true },
|
|
85
|
+
hitlPolicy: { threshold: 0.7 },
|
|
86
|
+
starterProject: {
|
|
87
|
+
name: 'Mobile MVP',
|
|
88
|
+
description: 'First version of the mobile application',
|
|
89
|
+
tasks: [
|
|
90
|
+
{ id: 'mob-1', title: 'Design mobile navigation flow', assigned_to: 'ui-designer' },
|
|
91
|
+
{ id: 'mob-2', title: 'Setup mobile build environment', assigned_to: 'mobile-builder' }
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
'ai-ml-system': {
|
|
96
|
+
name: 'AI/ML System',
|
|
97
|
+
emoji: '🧠',
|
|
98
|
+
industry: 'Software Engineering',
|
|
99
|
+
description: 'Data science, model training, and AI feature engineering',
|
|
100
|
+
timeline: '4-12 weeks',
|
|
101
|
+
agents: [
|
|
102
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
103
|
+
{ id: 'ai-engineer', template: 'agency-agents/engineering/ai-engineer.md', name: 'ML Engineer', emoji: '🧪', role: 'Model & Training', workspace: 'ml-eng' },
|
|
104
|
+
{ id: 'researcher', template: 'SOUL.md.sage', name: 'Sage', emoji: '🔮', role: 'Data Researcher', workspace: 'research' },
|
|
105
|
+
{ id: 'nova', template: 'SOUL.md.nova', name: 'Nova', emoji: '🧪', role: 'R&D/Experimentation', workspace: 'rd' },
|
|
106
|
+
{ id: 'forge', template: 'SOUL.md.forge', name: 'Forge', emoji: '⚒️', role: 'AI API/Integrations', workspace: 'forge' }
|
|
107
|
+
],
|
|
108
|
+
okrs: [
|
|
109
|
+
{ objective: 'Model Performance', keyResults: ['Achieve >90% prediction accuracy', 'Optimize inference latency <100ms'] }
|
|
110
|
+
],
|
|
111
|
+
crons: ['security-scan', 'velocity-report'],
|
|
112
|
+
hitlPolicy: { threshold: 0.6 },
|
|
113
|
+
starterProject: {
|
|
114
|
+
name: 'Model v1 Training',
|
|
115
|
+
description: 'Researching data and training the first model',
|
|
116
|
+
tasks: [
|
|
117
|
+
{ id: 'ai-1', title: 'Prepare training dataset', assigned_to: 'ai-engineer' },
|
|
118
|
+
{ id: 'ai-2', title: 'Benchmark baseline models', assigned_to: 'nova' }
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
// ── Marketing & Growth ─────────────────────────────────────────────────────
|
|
124
|
+
'marketing-campaign': {
|
|
125
|
+
name: 'Marketing Campaign',
|
|
126
|
+
emoji: '📈',
|
|
127
|
+
industry: 'Marketing & Growth',
|
|
128
|
+
description: 'Product launches, campaigns, content marketing, community growth',
|
|
129
|
+
timeline: '2-4 weeks',
|
|
130
|
+
agents: [
|
|
131
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
132
|
+
{ id: 'content-creator', template: 'agency-agents/marketing/content-creator.md', name: 'Content', emoji: '✍️', role: 'Copy/Content', workspace: 'content' },
|
|
133
|
+
{ id: 'twitter', template: 'agency-agents/marketing/twitter-engager.md', name: 'Twitter', emoji: '🐦', role: 'Social Media', workspace: 'twitter' },
|
|
134
|
+
{ id: 'reddit', template: 'agency-agents/marketing/reddit-community-builder.md', name: 'Reddit', emoji: '👥', role: 'Community', workspace: 'reddit' },
|
|
135
|
+
{ id: 'analytics', template: 'agency-agents/support/analytics-reporter.md', name: 'Analytics', emoji: '📊', role: 'Metrics Specialist', workspace: 'analytics' }
|
|
136
|
+
],
|
|
137
|
+
okrs: [
|
|
138
|
+
{ objective: 'Campaign Reach', keyResults: ['Generate 50k social impressions', 'Publish 5 high-quality articles'] }
|
|
139
|
+
],
|
|
140
|
+
crons: ['velocity-report'],
|
|
141
|
+
hitlPolicy: { threshold: 0.8 },
|
|
142
|
+
starterProject: {
|
|
143
|
+
name: 'Launch Campaign',
|
|
144
|
+
description: 'Coordinated launch across multiple social channels',
|
|
145
|
+
tasks: [
|
|
146
|
+
{ id: 'mkt-1', title: 'Draft hero blog post', assigned_to: 'content-creator' },
|
|
147
|
+
{ id: 'mkt-2', title: 'Setup Reddit engagement strategy', assigned_to: 'reddit' }
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
'brand-launch': {
|
|
152
|
+
name: 'Brand Launch',
|
|
153
|
+
emoji: '🏷️',
|
|
154
|
+
industry: 'Marketing & Growth',
|
|
155
|
+
description: 'New brand identity, PR, and market positioning',
|
|
156
|
+
timeline: '4-8 weeks',
|
|
157
|
+
agents: [
|
|
158
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
159
|
+
{ id: 'brand-guardian', template: 'agency-agents/design/brand-guardian.md', name: 'Guardian', emoji: '🛡️', role: 'Identy & Tone', workspace: 'brand' },
|
|
160
|
+
{ id: 'storyteller', template: 'agency-agents/design/visual-storyteller.md', name: 'Storyteller', emoji: '📖', role: 'Visual Narrative', workspace: 'story' },
|
|
161
|
+
{ id: 'content', template: 'agency-agents/marketing/content-creator.md', name: 'Content', emoji: '✍️', role: 'Copywriting', workspace: 'content' },
|
|
162
|
+
{ id: 'pr', template: 'agency-agents/marketing/social-media-strategist.md', name: 'PR/Social', emoji: '📣', role: 'Strategy', workspace: 'strategy' }
|
|
163
|
+
],
|
|
164
|
+
okrs: [
|
|
165
|
+
{ objective: 'Brand Identity Lock', keyResults: ['Complete brand book/style guide', 'Define unified brand voice/tone'] }
|
|
166
|
+
],
|
|
167
|
+
crons: ['velocity-report'],
|
|
168
|
+
hitlPolicy: { threshold: 0.8 },
|
|
169
|
+
starterProject: {
|
|
170
|
+
name: 'Identity Workshop',
|
|
171
|
+
description: 'Defining core brand values and visual language',
|
|
172
|
+
tasks: [
|
|
173
|
+
{ id: 'brand-1', title: 'Create mood board and palette', assigned_to: 'storyteller' },
|
|
174
|
+
{ id: 'brand-2', title: 'Write brand positioning statement', assigned_to: 'brand-guardian' }
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
'performance-marketing': {
|
|
179
|
+
name: 'Performance Marketing',
|
|
180
|
+
emoji: '💰',
|
|
181
|
+
industry: 'Marketing & Growth',
|
|
182
|
+
description: 'Paid acquisition, landing page optimization, and high ROI growth',
|
|
183
|
+
timeline: 'Ongoing',
|
|
184
|
+
agents: [
|
|
185
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
186
|
+
{ id: 'hacker', template: 'agency-agents/marketing/growth-hacker.md', name: 'Growth', emoji: '📈', role: 'ROI Experiments', workspace: 'hacker' },
|
|
187
|
+
{ id: 'analytics', template: 'agency-agents/support/analytics-reporter.md', name: 'Metrics', emoji: '📊', role: 'Tracking/Ads', workspace: 'analytics' },
|
|
188
|
+
{ id: 'content', template: 'agency-agents/marketing/content-creator.md', name: 'Ads/Copy', emoji: '✍️', role: 'Ad Copywriter', workspace: 'content' },
|
|
189
|
+
{ id: 'experiment', template: 'agency-agents/project-management/experiment-tracker.md', name: 'A/B Tracker', emoji: '🧪', role: 'Optimization', workspace: 'ab' }
|
|
190
|
+
],
|
|
191
|
+
okrs: [
|
|
192
|
+
{ objective: 'Conversion Efficiency', keyResults: ['Reduce CPA by 20%', 'Increase LP conversion rate to 5%'] }
|
|
193
|
+
],
|
|
194
|
+
crons: ['velocity-report', 'budget-check'],
|
|
195
|
+
hitlPolicy: { threshold: 0.75 },
|
|
196
|
+
starterProject: {
|
|
197
|
+
name: 'Ad Funnel Setup',
|
|
198
|
+
description: 'Building and testing the initial paid acquisition funnel',
|
|
199
|
+
tasks: [
|
|
200
|
+
{ id: 'perf-1', title: 'Draft initial ad set copy', assigned_to: 'content' },
|
|
201
|
+
{ id: 'perf-2', title: 'Configure tracking conversion pixels', assigned_to: 'analytics' }
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
// ── Enterprise & Regulated ──────────────────────────────────────────────────
|
|
207
|
+
'enterprise-feature': {
|
|
208
|
+
name: 'Enterprise Feature',
|
|
209
|
+
emoji: '🏢',
|
|
210
|
+
industry: 'Enterprise & Regulated',
|
|
211
|
+
description: 'Complex feature development, enterprise systems, high-stakes projects',
|
|
212
|
+
timeline: '4-8 weeks',
|
|
213
|
+
agents: [
|
|
214
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
215
|
+
{ id: 'vista', template: 'SOUL.md.vista', name: 'Vista', emoji: '🔭', role: 'Product Manager', workspace: 'vista' },
|
|
216
|
+
{ id: 'sage', template: 'SOUL.md.sage', name: 'Sage', emoji: '🔮', role: 'Senior Developer', workspace: 'sage' },
|
|
217
|
+
{ id: 'vigil', template: 'SOUL.md.vigil', name: 'Vigil', emoji: '🛡️', role: 'QA Specialist', workspace: 'vigil' },
|
|
218
|
+
{ id: 'experiment', template: 'agency-agents/project-management/experiment-tracker.md', name: 'Experiments', emoji: '🧪', role: 'A/B Testing', workspace: 'experiments' },
|
|
219
|
+
{ id: 'reality', template: 'agency-agents/testing/reality-checker.md', name: 'Reality Check', emoji: '🛡️', role: 'Certification', workspace: 'cert' }
|
|
220
|
+
],
|
|
221
|
+
okrs: [
|
|
222
|
+
{ objective: 'Enterprise Delivery', keyResults: ['Complete feature with 0 high-risk security flaws', 'Pass 100% of enterprise acceptance tests'] }
|
|
223
|
+
],
|
|
224
|
+
crons: ['security-scan', 'velocity-report', 'budget-check'],
|
|
225
|
+
hitlPolicy: { threshold: 0.6 },
|
|
226
|
+
starterProject: {
|
|
227
|
+
name: 'Feature Specification',
|
|
228
|
+
description: 'Analysing requirements for an enterprise feature',
|
|
229
|
+
tasks: [
|
|
230
|
+
{ id: 'ent-1', title: 'Document enterprise requirements', assigned_to: 'vista' },
|
|
231
|
+
{ id: 'ent-2', title: 'Draft technical architecture', assigned_to: 'sage' }
|
|
232
|
+
]
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
'security-critical': {
|
|
236
|
+
name: 'Security-Critical',
|
|
237
|
+
emoji: '🔐',
|
|
238
|
+
industry: 'Enterprise & Regulated',
|
|
239
|
+
description: 'High-security applications, financial systems, and zero-trust',
|
|
240
|
+
timeline: 'Ongoing',
|
|
241
|
+
agents: [
|
|
242
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
243
|
+
{ id: 'security', template: 'agency-agents/support/legal-compliance-checker.md', name: 'Auditor', emoji: '🕵️', role: 'Security Compliance', workspace: 'auditor' },
|
|
244
|
+
{ id: 'sage', template: 'SOUL.md.sage', name: 'Sage', emoji: '🔮', role: 'Secure Architect', workspace: 'sage' },
|
|
245
|
+
{ id: 'vigil', template: 'SOUL.md.vigil', name: 'Vigil', emoji: '🛡️', role: 'Penetration Tester', workspace: 'vigil' },
|
|
246
|
+
{ id: 'reality', template: 'agency-agents/testing/reality-checker.md', name: 'Reality Check', emoji: '🛡️', role: 'Hardness Certification', workspace: 'cert' }
|
|
247
|
+
],
|
|
248
|
+
okrs: [
|
|
249
|
+
{ objective: 'Zero Critical Vulns', keyResults: ['Maintain Grade A Security posture', 'Zero unmitigated critical vulnerabilities'] }
|
|
250
|
+
],
|
|
251
|
+
crons: ['security-scan', 'velocity-report'],
|
|
252
|
+
hitlPolicy: { threshold: 0.5 },
|
|
253
|
+
starterProject: {
|
|
254
|
+
name: 'Security Audit',
|
|
255
|
+
description: 'Comprehensive security sweep of the system',
|
|
256
|
+
tasks: [
|
|
257
|
+
{ id: 'sec-1', title: 'Audit auth flows for injection points', assigned_to: 'vigil' },
|
|
258
|
+
{ id: 'sec-2', title: 'Review encryption documentation', assigned_to: 'security' }
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
'compliance-audit': {
|
|
263
|
+
name: 'Compliance & Audit',
|
|
264
|
+
emoji: '⚖️',
|
|
265
|
+
industry: 'Enterprise & Regulated',
|
|
266
|
+
description: 'Regulatory compliance focused (SOC2, GDPR, HIPAA)',
|
|
267
|
+
timeline: 'Recurring',
|
|
268
|
+
agents: [
|
|
269
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
270
|
+
{ id: 'legal', template: 'agency-agents/support/legal-compliance-checker.md', name: 'Compliance', emoji: '📜', role: 'Legal Tech', workspace: 'legal' },
|
|
271
|
+
{ id: 'analytics', template: 'agency-agents/support/analytics-reporter.md', name: 'Reporter', emoji: '📈', role: 'Audit Analytics', workspace: 'analytics' },
|
|
272
|
+
{ id: 'vigil', template: 'SOUL.md.vigil', name: 'Vigil', emoji: '🛡️', role: 'Compliance QA', workspace: 'vigil' },
|
|
273
|
+
{ id: 'vista', template: 'SOUL.md.vista', name: 'Vista', emoji: '🔭', role: 'Policy Manager', workspace: 'vista' },
|
|
274
|
+
{ id: 'exec', template: 'agency-agents/support/executive-summary-generator.md', name: 'Executive', emoji: '📝', role: 'Audit reporting', workspace: 'exec' }
|
|
275
|
+
],
|
|
276
|
+
okrs: [
|
|
277
|
+
{ objective: 'Compliance Readiness', keyResults: ['Collect 100% of necessary audit evidence', 'Resolve all major compliance findings'] }
|
|
278
|
+
],
|
|
279
|
+
crons: ['velocity-report'],
|
|
280
|
+
hitlPolicy: { threshold: 0.6 },
|
|
281
|
+
starterProject: {
|
|
282
|
+
name: 'Audit Prep',
|
|
283
|
+
description: 'Gathering evidence for upcoming regulatory audit',
|
|
284
|
+
tasks: [
|
|
285
|
+
{ id: 'aud-1', title: 'Map system architecture to SOC2 criteria', assigned_to: 'legal' },
|
|
286
|
+
{ id: 'aud-2', title: 'Generate security history snapshot', assigned_to: 'analytics' }
|
|
287
|
+
]
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
|
|
291
|
+
// ── Research & Development ──────────────────────────────────────────────────
|
|
292
|
+
'quality-first': {
|
|
293
|
+
name: 'Quality-First',
|
|
294
|
+
emoji: '🔬',
|
|
295
|
+
industry: 'Research & Development',
|
|
296
|
+
description: 'Zero-defect requirements, high-reliability software',
|
|
297
|
+
timeline: 'Quality-driven',
|
|
298
|
+
agents: [
|
|
299
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
300
|
+
{ id: 'vigil', template: 'SOUL.md.vigil', name: 'Vigil', emoji: '🛡️', role: 'QA (Evidence Collector)', workspace: 'vigil' },
|
|
301
|
+
{ id: 'reality', template: 'agency-agents/testing/reality-checker.md', name: 'Reality Check', emoji: '🛡️', role: 'Hardness Cert', workspace: 'cert' },
|
|
302
|
+
{ id: 'perf', template: 'agency-agents/testing/performance-benchmarker.md', name: 'Perf Check', emoji: '⚡', role: 'Benchmark QA', workspace: 'perf' }
|
|
303
|
+
],
|
|
304
|
+
okrs: [
|
|
305
|
+
{ objective: 'Flawless Quality', keyResults: ['Zero production issues for 30 days', 'Test coverage >95% everywhere'] }
|
|
306
|
+
],
|
|
307
|
+
crons: ['security-scan', 'velocity-report'],
|
|
308
|
+
hitlPolicy: { threshold: 0.55 },
|
|
309
|
+
starterProject: {
|
|
310
|
+
name: 'Quality Sweep',
|
|
311
|
+
description: 'Bringing existing systems up to quality standards',
|
|
312
|
+
tasks: [
|
|
313
|
+
{ id: 'qa-1', title: 'Run comprehensive TDD sweep', assigned_to: 'vigil' },
|
|
314
|
+
{ id: 'qa-2', title: 'Establish performance baselines', assigned_to: 'perf' }
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
'research-discovery': {
|
|
319
|
+
name: 'Research & Discovery',
|
|
320
|
+
emoji: '🔭',
|
|
321
|
+
industry: 'Research & Development',
|
|
322
|
+
description: 'Trend analysis, knowledge curation, and intellectual discovery',
|
|
323
|
+
timeline: '4-12 weeks',
|
|
324
|
+
agents: [
|
|
325
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
326
|
+
{ id: 'trend', template: 'agency-agents/product/trend-researcher.md', name: 'Trend', emoji: '📈', role: 'Market Intelligence', workspace: 'trend' },
|
|
327
|
+
{ id: 'nova', template: 'SOUL.md.nova', name: 'Nova', emoji: '🧪', role: 'R&D Head', workspace: 'rd' },
|
|
328
|
+
{ id: 'cipher', template: 'SOUL.md.cipher', name: 'Cipher', emoji: '🔊', role: 'Knowledge Curator', workspace: 'cipher' },
|
|
329
|
+
{ id: 'analytics', template: 'agency-agents/support/analytics-reporter.md', name: 'Analyst', emoji: '📊', role: 'Data Analysis', workspace: 'analytics' },
|
|
330
|
+
{ id: 'content', template: 'agency-agents/marketing/content-creator.md', name: 'Content', emoji: '✍️', role: 'Knowledge Sharing', workspace: 'content' }
|
|
331
|
+
],
|
|
332
|
+
okrs: [
|
|
333
|
+
{ objective: 'Systemic Knowledge Expansion', keyResults: ['Produce 10 high-value internal research whitepapers', 'Surface 5 major industry shifts/trends'] }
|
|
334
|
+
],
|
|
335
|
+
crons: ['velocity-report'],
|
|
336
|
+
hitlPolicy: { threshold: 0.7 },
|
|
337
|
+
starterProject: {
|
|
338
|
+
name: 'Industry Landscape Research',
|
|
339
|
+
description: 'Mapping the currently known space and identifying unknowns',
|
|
340
|
+
tasks: [
|
|
341
|
+
{ id: 'res-1', title: 'Index competitive landscape data', assigned_to: 'cipher' },
|
|
342
|
+
{ id: 'res-2', title: 'Formulate 3 testable hypotheses', assigned_to: 'nova' }
|
|
343
|
+
]
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
// ── Creative & Content ─────────────────────────────────────────────────────
|
|
348
|
+
'content-studio': {
|
|
349
|
+
name: 'Content Studio',
|
|
350
|
+
emoji: '🎬',
|
|
351
|
+
industry: 'Creative & Content',
|
|
352
|
+
description: 'High-volume high-quality content production factory',
|
|
353
|
+
timeline: 'Weekly',
|
|
354
|
+
agents: [
|
|
355
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
356
|
+
{ id: 'content', template: 'agency-agents/marketing/content-creator.md', name: 'Creator', emoji: '✍️', role: 'Chief Copywriter', workspace: 'content' },
|
|
357
|
+
{ id: 'insta', template: 'agency-agents/marketing/instagram-curator.md', name: 'Insta', emoji: '📸', role: 'Visual Social', workspace: 'insta' },
|
|
358
|
+
{ id: 'tiktok', template: 'agency-agents/marketing/tiktok-strategist.md', name: 'TikTok', emoji: '🎵', role: 'Viral Strategy', workspace: 'tiktok' },
|
|
359
|
+
{ id: 'whimsy', template: 'agency-agents/design/whimsy-injector.md', name: 'Whimsy', emoji: '✨', role: 'Delight Specialist', workspace: 'whimsy' },
|
|
360
|
+
{ id: 'analytics', template: 'agency-agents/support/analytics-reporter.md', name: 'Metrics', emoji: '📊', role: 'Performance QA', workspace: 'analytics' }
|
|
361
|
+
],
|
|
362
|
+
okrs: [
|
|
363
|
+
{ objective: 'Content Factory Throughput', keyResults: ['Publish 20 multi-channel asset sets weekly', 'Increase net engagement rate by 15%'] }
|
|
364
|
+
],
|
|
365
|
+
crons: ['velocity-report'],
|
|
366
|
+
hitlPolicy: { threshold: 0.8 },
|
|
367
|
+
starterProject: {
|
|
368
|
+
name: 'Content Production Loop',
|
|
369
|
+
description: 'Setup and execution of the weekly content production workflow',
|
|
370
|
+
tasks: [
|
|
371
|
+
{ id: 'studio-1', title: 'Draft next week\'s topic ideas', assigned_to: 'content' },
|
|
372
|
+
{ id: 'studio-2', title: 'Create base visual template', assigned_to: 'whimsy' }
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
'design-sprint': {
|
|
377
|
+
name: 'Product Design Sprint',
|
|
378
|
+
emoji: '🖍️',
|
|
379
|
+
industry: 'Creative & Content',
|
|
380
|
+
description: 'User-centered design discovery and UI prototyping',
|
|
381
|
+
timeline: '1-4 weeks',
|
|
382
|
+
agents: [
|
|
383
|
+
{ id: 'main', template: 'SOUL.md.main', name: 'Cooper', emoji: '🦅', role: 'Orchestrator', workspace: '.' },
|
|
384
|
+
{ id: 'ux-research', template: 'agency-agents/design/ux-researcher.md', name: 'Research', emoji: '🔍', role: 'User Insights', workspace: 'ux-res' },
|
|
385
|
+
{ id: 'ui-designer', template: 'agency-agents/design/ui-designer.md', name: 'Designer', emoji: '🎨', role: 'UI Implementation', workspace: 'design' },
|
|
386
|
+
{ id: 'ux-arch', template: 'agency-agents/design/ux-architect.md', name: 'UX Arch', emoji: '🏗️', role: 'Technical UX', workspace: 'ux-arch' },
|
|
387
|
+
{ id: 'pixel', template: 'SOUL.md.pixel', name: 'Pixel', emoji: '🐛', role: 'Web/Poc Builder', workspace: 'pixel' },
|
|
388
|
+
{ id: 'evidence', template: 'agency-agents/testing/evidence-collector.md', name: 'Evidence', emoji: '📸', role: 'Visual QA', workspace: 'evidence' }
|
|
389
|
+
],
|
|
390
|
+
okrs: [
|
|
391
|
+
{ objective: 'Handoff Ready Design', keyResults: ['Complete high-fidelity prototype', 'Achieve >80% task success rate in user tests'] }
|
|
392
|
+
],
|
|
393
|
+
crons: ['velocity-report'],
|
|
394
|
+
hitlPolicy: { threshold: 0.7 },
|
|
395
|
+
starterProject: {
|
|
396
|
+
name: 'Discovery Sprint',
|
|
397
|
+
description: 'Rapid research and wireframing for the new concept',
|
|
398
|
+
tasks: [
|
|
399
|
+
{ id: 'ds-1', title: 'Analyze user pain points', assigned_to: 'ux-research' },
|
|
400
|
+
{ id: 'ds-2', title: 'Create initial wireframe flow', assigned_to: 'ux-arch' }
|
|
401
|
+
]
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
export function getBlueprintById(id) {
|
|
407
|
+
return TEAM_BLUEPRINTS[id] || null;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export function getBlueprintGroups() {
|
|
411
|
+
const industries = [...new Set(Object.values(TEAM_BLUEPRINTS).map(b => b.industry))];
|
|
412
|
+
const groups = {};
|
|
413
|
+
|
|
414
|
+
industries.forEach(ind => {
|
|
415
|
+
groups[ind] = Object.entries(TEAM_BLUEPRINTS)
|
|
416
|
+
.filter(([_, b]) => b.industry === ind)
|
|
417
|
+
.map(([id, b]) => ({ id, ...b }));
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
return groups;
|
|
421
|
+
}
|