Skip to content

Commit 704e41f

Browse files
authored
Fix trailing commas in openclaw.plugin.json and add JSON manifest CI tests (#774)
Fixes #771 — two trailing commas in openclaw.plugin.json caused OpenClaw's strict JSON parser to reject the plugin manifest during installation. Also adds JSON validation tests for both the openclaw plugin manifest and the claude-code hooks.json so CI catches invalid JSON before release.
1 parent f30ca3d commit 704e41f

3 files changed

Lines changed: 38 additions & 2 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"""Validate that JSON manifests are strict-valid JSON (no trailing commas, etc.)."""
2+
3+
import json
4+
from pathlib import Path
5+
6+
INTEGRATION_ROOT = Path(__file__).resolve().parent.parent
7+
8+
9+
def test_hooks_json_is_valid():
10+
path = INTEGRATION_ROOT / "hooks" / "hooks.json"
11+
raw = path.read_text()
12+
parsed = json.loads(raw)
13+
assert "hooks" in parsed
14+
assert isinstance(parsed["hooks"], dict)

hindsight-integrations/openclaw/openclaw.plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@
215215
"type": "number",
216216
"description": "Interval in ms to batch retain/recall log summaries. 0 = log every event individually. Default: 300000 (5 min).",
217217
"default": 300000
218-
},
218+
}
219219
},
220220
"additionalProperties": false
221221
},
@@ -349,6 +349,6 @@
349349
"logSummaryIntervalMs": {
350350
"label": "Log Summary Interval (ms)",
351351
"placeholder": "300000"
352-
},
352+
}
353353
}
354354
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { describe, it, expect } from 'vitest';
2+
import { readFileSync } from 'fs';
3+
import { resolve, dirname } from 'path';
4+
import { fileURLToPath } from 'url';
5+
6+
const __dirname = dirname(fileURLToPath(import.meta.url));
7+
const manifestPath = resolve(__dirname, '..', 'openclaw.plugin.json');
8+
9+
describe('openclaw.plugin.json', () => {
10+
it('is valid JSON', () => {
11+
const raw = readFileSync(manifestPath, 'utf-8');
12+
expect(() => JSON.parse(raw)).not.toThrow();
13+
});
14+
15+
it('has required top-level fields', () => {
16+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
17+
expect(manifest.id).toBe('hindsight-openclaw');
18+
expect(manifest.name).toBeTypeOf('string');
19+
expect(manifest.configSchema).toBeDefined();
20+
expect(manifest.configSchema.properties).toBeDefined();
21+
});
22+
});

0 commit comments

Comments
 (0)