agi-farm 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -686,6 +686,45 @@ The embedded `skills/agi-farm/SKILL.md` provides documentation reference for age
686
686
 
687
687
  ---
688
688
 
689
+ ## 🔄 OpenClaw Compatibility
690
+
691
+ AGI Farm ensures compatibility with OpenClaw through **automated testing** and **proactive monitoring**:
692
+
693
+ ### Automated Compatibility Testing
694
+ - **Weekly testing** against multiple OpenClaw versions (latest, previous, oldest-supported, beta)
695
+ - **Performance benchmarks** to detect regressions (load time, validation time thresholds)
696
+ - **API deprecation scanning** with automated replacement suggestions
697
+ - **Automated PR creation** for compatibility fixes when breaking changes detected
698
+
699
+ ### Supported Versions
700
+ - **Minimum**: OpenClaw 1.0.0+
701
+ - **Tested**: Latest stable + previous stable + beta (when available)
702
+ - **Status**: All compatibility tests run weekly via GitHub Actions
703
+
704
+ ### For Users
705
+ Check compatibility before upgrading OpenClaw:
706
+ ```bash
707
+ # Check current OpenClaw version
708
+ openclaw --version
709
+
710
+ # Run validation
711
+ npm run validate
712
+
713
+ # View compatibility matrix
714
+ cat OPENCLAW_COMPATIBILITY.md
715
+ ```
716
+
717
+ ### For Maintainers
718
+ The enhanced compatibility system includes:
719
+ - Multi-version testing matrix (4 versions tested)
720
+ - Performance regression detection (<5s load time, <3s validation)
721
+ - Automated issue creation when incompatibility detected
722
+ - Optional automated PR generation with suggested fixes
723
+
724
+ **See:** [OPENCLAW_COMPATIBILITY.md](OPENCLAW_COMPATIBILITY.md) for complete compatibility guide.
725
+
726
+ ---
727
+
689
728
  ## 🤝 Contributing
690
729
 
691
730
  Contributions are welcome! Please feel free to submit a Pull Request.
@@ -2,10 +2,15 @@
2
2
  "id": "agi-farm",
3
3
  "kind": "team-orchestration",
4
4
  "name": "AGI Farm — Multi-Agent Team Builder",
5
- "version": "1.5.0",
5
+ "version": "1.5.2",
6
6
  "description": "Bootstrap complete multi-agent AI teams with auto-dispatcher, live dashboard, and infrastructure. Includes interactive wizard, SOUL.md generation, comms setup, cron registration, and React + SSE ops room.",
7
7
  "author": "oabdelmaksoud",
8
8
  "homepage": "https://github.com/oabdelmaksoud/AGI-FARM-PLUGIN",
9
+ "openclawVersion": ">=1.0.0",
10
+ "engines": {
11
+ "openclaw": ">=1.0.0",
12
+ "node": ">=20.0.0"
13
+ },
9
14
  "configSchema": {
10
15
  "type": "object",
11
16
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agi-farm",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "Multi-agent AI team builder for OpenClaw — bootstrap complete teams with auto-dispatcher, dashboard, and infrastructure",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -43,6 +43,14 @@
43
43
  "engines": {
44
44
  "node": ">=20.0.0"
45
45
  },
46
+ "peerDependencies": {
47
+ "openclaw": ">=1.0.0"
48
+ },
49
+ "peerDependenciesMeta": {
50
+ "openclaw": {
51
+ "optional": true
52
+ }
53
+ },
46
54
  "scripts": {
47
55
  "build:dashboard": "cd dashboard-react && npm run build",
48
56
  "build:all": "npm run build && npm run build:dashboard && rm -rf dashboard-dist && cp -r dashboard-react/dist dashboard-dist",
@@ -24,7 +24,7 @@ if (isCI) {
24
24
  console.log(chalk.cyan('ℹ Running in CI environment'));
25
25
  }
26
26
 
27
- // ── 1. Check OpenClaw Installation ────────────────────────────────────────────
27
+ // ── 1. Check OpenClaw Installation & Version ──────────────────────────────────
28
28
  const openclawDir = path.join(os.homedir(), '.openclaw');
29
29
  if (!fs.existsSync(openclawDir)) {
30
30
  // In CI, OpenClaw won't be installed — treat as warning, not error
@@ -35,6 +35,43 @@ if (!fs.existsSync(openclawDir)) {
35
35
  }
36
36
  } else {
37
37
  console.log(chalk.green('✓ OpenClaw directory found'));
38
+
39
+ // Check OpenClaw version
40
+ try {
41
+ const openclawVersion = execSync('openclaw --version', { encoding: 'utf-8', stdio: 'pipe' }).trim();
42
+ console.log(chalk.green(`✓ OpenClaw version: ${openclawVersion}`));
43
+
44
+ // Extract version number (e.g., "openclaw/1.2.3" → "1.2.3")
45
+ const versionMatch = openclawVersion.match(/(\d+\.\d+\.\d+)/);
46
+ if (versionMatch) {
47
+ const version = versionMatch[1];
48
+ const [major, minor, patch] = version.split('.').map(Number);
49
+
50
+ // Define minimum compatible OpenClaw version
51
+ const MIN_OPENCLAW_VERSION = '1.0.0';
52
+ const [minMajor, minMinor, minPatch] = MIN_OPENCLAW_VERSION.split('.').map(Number);
53
+
54
+ // Check if version meets minimum requirement
55
+ if (major < minMajor || (major === minMajor && minor < minMinor) || (major === minMajor && minor === minMinor && patch < minPatch)) {
56
+ warnings.push(`OpenClaw ${version} is older than recommended ${MIN_OPENCLAW_VERSION}`);
57
+ warnings.push('Consider upgrading: npm install -g openclaw@latest');
58
+ }
59
+
60
+ // Check for known incompatible versions
61
+ const INCOMPATIBLE_VERSIONS = [
62
+ // Add known incompatible versions here if discovered
63
+ // e.g., '2.0.0-beta.1'
64
+ ];
65
+
66
+ if (INCOMPATIBLE_VERSIONS.includes(version)) {
67
+ errors.push(`OpenClaw ${version} has known incompatibilities with AGI Farm`);
68
+ errors.push('Please upgrade or downgrade OpenClaw');
69
+ }
70
+ }
71
+ } catch (err) {
72
+ warnings.push('Could not determine OpenClaw version');
73
+ warnings.push('Ensure openclaw CLI is in PATH');
74
+ }
38
75
  }
39
76
 
40
77
  // ── 2. Check Node.js Version ──────────────────────────────────────────────────
@@ -378,7 +378,7 @@ function toggleCronEnabled(id) {
378
378
  const updateChecker = new UpdateChecker();
379
379
 
380
380
  function buildWorkspaceSnapshot(cache, services) {
381
- const tasks = asArray(readJson(path.join(WORKSPACE, 'TASKS.json')));
381
+ let tasks = asArray(readJson(path.join(WORKSPACE, 'TASKS.json')));
382
382
  const agentStatus = asObject(readJson(path.join(WORKSPACE, 'AGENT_STATUS.json')));
383
383
  const agentPerf = asObject(readJson(path.join(WORKSPACE, 'AGENT_PERFORMANCE.json')));
384
384
  const budget = asObject(readJson(path.join(WORKSPACE, 'BUDGET.json')));
@@ -445,13 +445,61 @@ function buildWorkspaceSnapshot(cache, services) {
445
445
  const jobs = flags.jobs ? services.jobs.list({}).slice(0, 100) : [];
446
446
  const approvals = flags.approvals ? services.policy.listApprovals() : [];
447
447
  const usage = flags.metering ? services.metering.getUsage() : { records: [], perAgent: {}, perModel: {}, totals: {} };
448
- const projects = enrichProjects(projectsRaw, tasks, agentPerf);
448
+
449
+ // Auto-derive tasks from jobs that have rootTaskId
450
+ const taskIds = new Set(tasks.map(t => t.id));
451
+ const derivedTasks = [];
452
+ for (const job of jobs) {
453
+ if (job.rootTaskId && !taskIds.has(job.rootTaskId)) {
454
+ derivedTasks.push({
455
+ id: job.rootTaskId,
456
+ title: job.title || `Task from job ${job.id.slice(0, 8)}`,
457
+ description: job.intent || '',
458
+ status: job.status === 'complete' ? 'complete' : (job.status === 'running' ? 'in-progress' : 'pending'),
459
+ assigned_to: job.assignedAgent || job.requestedBy || 'system',
460
+ project_id: job.projectId || null,
461
+ created_at: job.createdAt,
462
+ updated_at: job.updatedAt,
463
+ depends_on: [],
464
+ });
465
+ taskIds.add(job.rootTaskId);
466
+ }
467
+ }
468
+ // Merge explicit tasks + auto-derived from jobs
469
+ const allTasks = [...tasks, ...derivedTasks];
470
+
471
+ // Auto-derive projects from jobs that have projectId
472
+ const jobProjects = {};
473
+ for (const job of jobs) {
474
+ if (job.projectId && !jobProjects[job.projectId]) {
475
+ jobProjects[job.projectId] = {
476
+ id: job.projectId,
477
+ name: job.title || job.projectId,
478
+ description: job.intent || '',
479
+ status: job.status === 'complete' ? 'complete' : 'active',
480
+ owner: job.requestedBy || 'system',
481
+ created_at: job.createdAt,
482
+ updated_at: job.updatedAt,
483
+ task_ids: job.rootTaskId ? [job.rootTaskId] : [],
484
+ job_ids: [job.id],
485
+ };
486
+ } else if (job.projectId && jobProjects[job.projectId]) {
487
+ jobProjects[job.projectId].job_ids.push(job.id);
488
+ if (job.rootTaskId && !jobProjects[job.projectId].task_ids.includes(job.rootTaskId)) {
489
+ jobProjects[job.projectId].task_ids.push(job.rootTaskId);
490
+ }
491
+ }
492
+ }
493
+
494
+ // Merge: explicit projects from PROJECTS.json + auto-derived from jobs
495
+ const allProjectsRaw = [...projectsRaw, ...Object.values(jobProjects)];
496
+ const projects = enrichProjects(allProjectsRaw, tasks, agentPerf);
449
497
  const projectEvents = services.timeline ? services.timeline.list(null, { limit: 120 }) : [];
450
498
 
451
499
  return {
452
500
  timestamp: new Date().toISOString(),
453
501
  workspace: WORKSPACE,
454
- tasks,
502
+ tasks: allTasks,
455
503
  task_counts: taskCounts,
456
504
  hitl_tasks: hitlTasks,
457
505
  sla_at_risk: slaAtRisk,