@ikieaneh/opencode-kit 0.5.3 → 0.5.4
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/package.json +1 -1
- package/rules/rules.json +20 -0
- package/src/postflight.sh +22 -7
- package/src/preflight.sh +61 -45
- package/templates/agents/orchestrator.md +1 -1
- package/templates/opencode-kit.schema.json +6 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikieaneh/opencode-kit",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Standardized OpenCode orchestration framework — contract-based, rules-enforced, zero-touch agent workflow. Install as plugin.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "RizkiRachman",
|
package/rules/rules.json
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
3
3
|
"strict": true,
|
|
4
4
|
"description": "Machine-enforceable rules for OpenCode agents. CRITICAL = BLOCK agent. HIGH = FLAG orchestrator. LOW = advisory.",
|
|
5
5
|
|
|
6
|
+
"required_mcps": {
|
|
7
|
+
"description": "MCPs required for the framework to function. Preflight.sh checks these dynamically.",
|
|
8
|
+
"lean-ctx": {
|
|
9
|
+
"description": "Context persistence — contract storage and retrieval",
|
|
10
|
+
"severity": "required",
|
|
11
|
+
"check_cli": "command -v lean-ctx",
|
|
12
|
+
"check_tool": "lean-ctx ctx_knowledge recall"
|
|
13
|
+
},
|
|
14
|
+
"gitnexus": {
|
|
15
|
+
"description": "Code intelligence — impact analysis before edits",
|
|
16
|
+
"severity": "required",
|
|
17
|
+
"check_cli": "npx --yes gitnexus --version"
|
|
18
|
+
},
|
|
19
|
+
"graphify": {
|
|
20
|
+
"description": "Knowledge graph — codebase exploration",
|
|
21
|
+
"severity": "optional",
|
|
22
|
+
"check_cli": "npx --yes gitnexus analyze --help"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
|
|
6
26
|
"state_machine": {
|
|
7
27
|
"transitions": [
|
|
8
28
|
{ "from": "INIT", "to": "PLAN", "require_score": null },
|
package/src/postflight.sh
CHANGED
|
@@ -11,6 +11,9 @@ CONTRACT_FILE=".opencode/orchestration/contract.json"
|
|
|
11
11
|
STATE_FILE="STATE.md"
|
|
12
12
|
TELEMETRY_DIR=".opencode/telemetry"
|
|
13
13
|
START_TIME_FILE=".opencode/telemetry/.phase_start"
|
|
14
|
+
STATE_BACKUP_DIR=".opencode/state"
|
|
15
|
+
|
|
16
|
+
mkdir -p "$TELEMETRY_DIR" "$STATE_BACKUP_DIR"
|
|
14
17
|
|
|
15
18
|
echo "[opencode-kit] Post-flight: persisting state..."
|
|
16
19
|
|
|
@@ -34,16 +37,28 @@ print(d.get('state','UNKNOWN'))
|
|
|
34
37
|
rm -f "$START_TIME_FILE"
|
|
35
38
|
fi
|
|
36
39
|
|
|
37
|
-
# --- Step 1:
|
|
38
|
-
CURRENT_CONTRACT=$(lean-ctx ctx_knowledge recall --query "$CONTRACT_KEY" 2>/dev/null || cat "$CONTRACT_FILE")
|
|
40
|
+
# --- Step 1: Read contract (try lean-ctx first, fall back to file) ---
|
|
41
|
+
CURRENT_CONTRACT=$(lean-ctx ctx_knowledge recall --query "$CONTRACT_KEY" 2>/dev/null || cat "$CONTRACT_FILE" 2>/dev/null || echo "")
|
|
42
|
+
if [ -z "$CURRENT_CONTRACT" ]; then
|
|
43
|
+
echo " ⚠️ No contract found in lean-ctx or file. Creating new from template..."
|
|
44
|
+
if [ -f "$TEMPLATE_FILE" ]; then
|
|
45
|
+
CURRENT_CONTRACT=$(cat "$TEMPLATE_FILE")
|
|
46
|
+
fi
|
|
47
|
+
fi
|
|
39
48
|
|
|
40
|
-
# --- Step 2:
|
|
41
|
-
|
|
49
|
+
# --- Step 2: Persist (try lean-ctx first, fall back to file) ---
|
|
50
|
+
PERSISTED=false
|
|
51
|
+
if lean-ctx ctx_knowledge remember \
|
|
42
52
|
category architecture \
|
|
43
53
|
key "$CONTRACT_KEY" \
|
|
44
|
-
value "$CURRENT_CONTRACT" 2>/dev/null
|
|
45
|
-
echo " ✅ Contract persisted to lean-ctx"
|
|
46
|
-
|
|
54
|
+
value "$CURRENT_CONTRACT" 2>/dev/null; then
|
|
55
|
+
echo " ✅ Contract persisted to lean-ctx"
|
|
56
|
+
PERSISTED=true
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# File fallback: write to .opencode/state/contract.json
|
|
60
|
+
echo "$CURRENT_CONTRACT" > "$STATE_BACKUP_DIR/contract.json"
|
|
61
|
+
echo " ✅ Contract persisted to file: $STATE_BACKUP_DIR/contract.json"
|
|
47
62
|
|
|
48
63
|
# --- Step 3: Sync STATE.md ---
|
|
49
64
|
mkdir -p "$(dirname "$STATE_FILE")"
|
package/src/preflight.sh
CHANGED
|
@@ -33,55 +33,71 @@ if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
|
|
|
33
33
|
fi
|
|
34
34
|
echo " ✅ Branch: $BRANCH (safe)"
|
|
35
35
|
|
|
36
|
-
# --- Check 3: MCP Availability ---
|
|
36
|
+
# --- Check 3: MCP Availability (from rules.json) ---
|
|
37
37
|
echo ""
|
|
38
|
-
echo " Checking MCP availability..."
|
|
38
|
+
echo " Checking MCP availability from rules.json..."
|
|
39
39
|
|
|
40
40
|
MCP_FAIL=0
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
#
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
42
|
+
if [ -n "$PYTHON_CMD" ] && [ -f "$RULES_FILE" ]; then
|
|
43
|
+
# Parse required_mcps from rules.json
|
|
44
|
+
$PYTHON_CMD -c "
|
|
45
|
+
import json, sys, subprocess, os
|
|
46
|
+
|
|
47
|
+
with open('$RULES_FILE') as f:
|
|
48
|
+
rules = json.load(f)
|
|
49
|
+
|
|
50
|
+
mcps = rules.get('required_mcps', {})
|
|
51
|
+
if not isinstance(mcps, dict) or 'description' in mcps:
|
|
52
|
+
# Skip the meta-description field
|
|
53
|
+
mcps = {k: v for k, v in mcps.items() if k != 'description' and isinstance(v, dict)}
|
|
54
|
+
|
|
55
|
+
if not mcps:
|
|
56
|
+
print(' ℹ️ No required_mcps defined in rules.json — skipping MCP checks')
|
|
57
|
+
sys.exit(0)
|
|
58
|
+
|
|
59
|
+
failures = []
|
|
60
|
+
for name, cfg in mcps.items():
|
|
61
|
+
cli_check = cfg.get('check_cli', '')
|
|
62
|
+
tool_check = cfg.get('check_tool', '')
|
|
63
|
+
severity = cfg.get('severity', 'optional')
|
|
64
|
+
desc = cfg.get('description', name)
|
|
65
|
+
|
|
66
|
+
available = False
|
|
67
|
+
# Try CLI check first
|
|
68
|
+
if cli_check:
|
|
69
|
+
try:
|
|
70
|
+
result = subprocess.run(cli_check, shell=True, capture_output=True, timeout=5)
|
|
71
|
+
if result.returncode == 0:
|
|
72
|
+
available = True
|
|
73
|
+
except:
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
# Try tool check as fallback
|
|
77
|
+
if not available and tool_check:
|
|
78
|
+
try:
|
|
79
|
+
result = subprocess.run(tool_check, shell=True, capture_output=True, timeout=5)
|
|
80
|
+
if result.returncode == 0:
|
|
81
|
+
available = True
|
|
82
|
+
except:
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
if available:
|
|
86
|
+
print(f' ✅ {name}: available — {desc}')
|
|
87
|
+
elif severity == 'required':
|
|
88
|
+
print(f' ❌ {name}: NOT DETECTED — {desc}')
|
|
89
|
+
failures.append(name)
|
|
90
|
+
else:
|
|
91
|
+
print(f' ⚠️ {name}: not detected — {desc} (optional)')
|
|
92
|
+
|
|
93
|
+
if failures:
|
|
94
|
+
print('')
|
|
95
|
+
for name in failures:
|
|
96
|
+
print(f' → Ensure {name} is configured in opencode.json MCP servers')
|
|
97
|
+
sys.exit(1)
|
|
98
|
+
else:
|
|
99
|
+
sys.exit(0)
|
|
100
|
+
" 2>&1 || MCP_FAIL=1
|
|
85
101
|
fi
|
|
86
102
|
|
|
87
103
|
echo ""
|
|
@@ -94,7 +94,7 @@ Delegate to @code-reviewer. After return → Scoring Pipeline → update contrac
|
|
|
94
94
|
3. **Tier 3 (Verdict)**: ≥70 PASS, 50-69 RETRY, <50 BLOCKED
|
|
95
95
|
|
|
96
96
|
### 5. Verify (loop)
|
|
97
|
-
Run quality gates (
|
|
97
|
+
Run quality gates (format, compile, test, verify)
|
|
98
98
|
If CRITICAL findings → BLOCK, fix, re-review. Max 3 iterations.
|
|
99
99
|
|
|
100
100
|
### 6. Ship
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"properties": {
|
|
24
24
|
"skills": {
|
|
25
25
|
"type": "array",
|
|
26
|
-
"description": "
|
|
26
|
+
"description": "Skills to load for this agent (e.g., orchestration, scoring, quality gates)",
|
|
27
27
|
"items": { "type": "string" },
|
|
28
28
|
"default": ["orchestration-template", "scoring-pipeline", "verification-before-completion"]
|
|
29
29
|
},
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"properties": {
|
|
38
38
|
"skills": {
|
|
39
39
|
"type": "array",
|
|
40
|
-
"description": "
|
|
40
|
+
"description": "Skills for analysis, requirements gathering, plan writing",
|
|
41
41
|
"items": { "type": "string" },
|
|
42
42
|
"default": ["brainstorming", "writing-plans", "system-analyst"]
|
|
43
43
|
},
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"properties": {
|
|
52
52
|
"skills": {
|
|
53
53
|
"type": "array",
|
|
54
|
+
"description": "Skills for implementation, execution, testing",
|
|
54
55
|
"items": { "type": "string" },
|
|
55
56
|
"default": ["subagent-driven-development", "executing-plans", "test-driven-development"]
|
|
56
57
|
},
|
|
@@ -64,6 +65,7 @@
|
|
|
64
65
|
"properties": {
|
|
65
66
|
"skills": {
|
|
66
67
|
"type": "array",
|
|
68
|
+
"description": "Skills for code quality, security, performance review",
|
|
67
69
|
"items": { "type": "string" },
|
|
68
70
|
"default": ["qa-expert", "security-expert", "devops-expert"]
|
|
69
71
|
},
|
|
@@ -77,6 +79,7 @@
|
|
|
77
79
|
"properties": {
|
|
78
80
|
"skills": {
|
|
79
81
|
"type": "array",
|
|
82
|
+
"description": "Skills for verification, quality checks, post-analysis",
|
|
80
83
|
"items": { "type": "string" },
|
|
81
84
|
"default": ["verification-before-completion", "qa-expert"]
|
|
82
85
|
},
|
|
@@ -117,6 +120,7 @@
|
|
|
117
120
|
"properties": {
|
|
118
121
|
"skills": {
|
|
119
122
|
"type": "array",
|
|
123
|
+
"description": "Skills for architecture analysis, simplification, debugging",
|
|
120
124
|
"items": { "type": "string" },
|
|
121
125
|
"default": ["simplify", "systematic-debugging", "system-analyst"]
|
|
122
126
|
},
|