@ikieaneh/opencode-kit 0.5.4 → 0.5.5
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/plugins/opencode-kit.js +12 -0
- package/package.json +1 -1
- package/src/doctor.sh +123 -0
- package/src/init.sh +4 -0
- package/templates/contract.json +2 -1
|
@@ -171,8 +171,20 @@ export const OpencodeKitPlugin = async ({ client, directory }) => {
|
|
|
171
171
|
config.skills = config.skills || {};
|
|
172
172
|
config.skills.paths = config.skills.paths || [];
|
|
173
173
|
|
|
174
|
+
// Detect if other plugins might conflict with opencode-kit's system prompt
|
|
175
|
+
if (config.plugins && Array.isArray(config.plugins)) {
|
|
176
|
+
const kitIndex = config.plugins.findIndex(p =>
|
|
177
|
+
typeof p === 'string' && p.includes('opencode-kit')
|
|
178
|
+
);
|
|
179
|
+
if (kitIndex > 0) {
|
|
180
|
+
const firstPlugin = config.plugins[0];
|
|
181
|
+
log('warn', `Plugin ordering conflict: opencode-kit should be FIRST, but found '${firstPlugin}' at position 0 and opencode-kit at position ${kitIndex}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
174
185
|
// Register user project skills FIRST (higher priority)
|
|
175
186
|
const userSkillsDir = path.join(projectDir, '.opencode/skills');
|
|
187
|
+
const userSkillsDir = path.join(projectDir, '.opencode/skills');
|
|
176
188
|
if (fs.existsSync(userSkillsDir) && !config.skills.paths.includes(userSkillsDir)) {
|
|
177
189
|
config.skills.paths.push(userSkillsDir);
|
|
178
190
|
log('info', `Registered user skills: ${userSkillsDir}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikieaneh/opencode-kit",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
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/src/doctor.sh
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# opencode-kit doctor — diagnostic command
|
|
3
|
+
# Checks: MCPs, contract, rules, permissions, git branch, agent configs
|
|
4
|
+
# Usage: bash src/doctor.sh [--json] [--fix]
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
. "$SCRIPT_DIR/platform.sh"
|
|
9
|
+
. "$SCRIPT_DIR/global-config.sh"
|
|
10
|
+
|
|
11
|
+
RULES_FILE=".opencode/rules/rules.json"
|
|
12
|
+
CONTRACT_FILE=".opencode/orchestration/contract.json"
|
|
13
|
+
OPENCODE_JSON="opencode.json"
|
|
14
|
+
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
GREEN='\033[0;32m'
|
|
17
|
+
YELLOW='\033[1;33m'
|
|
18
|
+
CYAN='\033[0;36m'
|
|
19
|
+
NC='\033[0m'
|
|
20
|
+
|
|
21
|
+
ISSUES=0
|
|
22
|
+
mode="${1:-}"
|
|
23
|
+
|
|
24
|
+
echo -e "${CYAN}🔍 opencode-kit doctor${NC}"
|
|
25
|
+
echo ""
|
|
26
|
+
|
|
27
|
+
# === 1. Contract check ===
|
|
28
|
+
echo -e "${CYAN}[CONTRACT]${NC} Checking orchestration contract..."
|
|
29
|
+
if [ ! -f "$CONTRACT_FILE" ]; then
|
|
30
|
+
echo -e " ${RED}❌ contract.json not found — run 'opencode-kit init'${NC}"
|
|
31
|
+
ISSUES=$((ISSUES + 1))
|
|
32
|
+
else
|
|
33
|
+
if [ -n "$PYTHON_CMD" ]; then
|
|
34
|
+
STATE=$($PYTHON_CMD -c "import json; d=json.load(open('$CONTRACT_FILE')); print(d.get('state','?'))" 2>/dev/null || echo "parse_error")
|
|
35
|
+
if [ "$STATE" = "parse_error" ]; then
|
|
36
|
+
echo -e " ${RED}❌ contract.json is malformed JSON${NC}"
|
|
37
|
+
ISSUES=$((ISSUES + 1))
|
|
38
|
+
else
|
|
39
|
+
echo -e " ✅ State: $STATE"
|
|
40
|
+
fi
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# === 2. Rules check ===
|
|
45
|
+
echo -e "${CYAN}[RULES]${NC} Checking rules.json..."
|
|
46
|
+
if [ ! -f "$RULES_FILE" ]; then
|
|
47
|
+
echo -e " ${RED}❌ rules.json not found${NC}"
|
|
48
|
+
ISSUES=$((ISSUES + 1))
|
|
49
|
+
else
|
|
50
|
+
if [ -n "$PYTHON_CMD" ]; then
|
|
51
|
+
RULE_COUNT=$($PYTHON_CMD -c "import json; d=json.load(open('$RULES_FILE')); print(len(d.get('rules',[])))" 2>/dev/null || echo "0")
|
|
52
|
+
echo -e " ✅ $RULE_COUNT rules loaded"
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# === 3. MCP checks ===
|
|
57
|
+
echo -e "${CYAN}[MCP]${NC} Checking required MCPs..."
|
|
58
|
+
if [ -f "$RULES_FILE" ] && [ -n "$PYTHON_CMD" ]; then
|
|
59
|
+
$PYTHON_CMD -c "
|
|
60
|
+
import json, subprocess, sys
|
|
61
|
+
with open('$RULES_FILE') as f:
|
|
62
|
+
rules = json.load(f)
|
|
63
|
+
mcps = rules.get('required_mcps', {})
|
|
64
|
+
mcps.pop('description', None)
|
|
65
|
+
for name, cfg in mcps.items():
|
|
66
|
+
cli = cfg.get('check_cli', '')
|
|
67
|
+
severity = cfg.get('severity', 'optional')
|
|
68
|
+
result = subprocess.run(cli, shell=True, capture_output=True, timeout=5)
|
|
69
|
+
ok = result.returncode == 0
|
|
70
|
+
if ok:
|
|
71
|
+
print(f' ✅ {name}: available')
|
|
72
|
+
elif severity == 'required':
|
|
73
|
+
print(f' ❌ {name}: MISSING (required)')
|
|
74
|
+
sys.exit(1)
|
|
75
|
+
else:
|
|
76
|
+
print(f' ⚠️ {name}: not detected (optional)')
|
|
77
|
+
" 2>/dev/null || ISSUES=$((ISSUES + 1))
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# === 4. Git branch ===
|
|
81
|
+
echo -e "${CYAN}[GIT]${NC} Checking branch..."
|
|
82
|
+
BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
|
|
83
|
+
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
|
|
84
|
+
echo -e " ${YELLOW}⚠️ On '$BRANCH' — create a feature branch for development${NC}"
|
|
85
|
+
else
|
|
86
|
+
echo -e " ✅ Branch: $BRANCH"
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# === 5. Lean-ctx persistence ===
|
|
90
|
+
echo -e "${CYAN}[PERSIST]${NC} Checking persistence..."
|
|
91
|
+
if command -v lean-ctx &>/dev/null; then
|
|
92
|
+
echo -e " ✅ lean-ctx CLI available"
|
|
93
|
+
LEAN_OK=$(lean-ctx ctx_knowledge recall --query "orchestration-contract" &>/dev/null && echo "yes" || echo "no")
|
|
94
|
+
if [ "$LEAN_OK" = "yes" ]; then
|
|
95
|
+
echo -e " ✅ Contract found in lean-ctx"
|
|
96
|
+
else
|
|
97
|
+
echo -e " ⚠️ Contract not in lean-ctx (file fallback active)"
|
|
98
|
+
fi
|
|
99
|
+
else
|
|
100
|
+
echo -e " ⚠️ lean-ctx not detected (file fallback active)"
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# === 6. Plugin in opencode.json ===
|
|
104
|
+
echo -e "${CYAN}[PLUGIN]${NC} Checking plugin configuration..."
|
|
105
|
+
if [ -f "$OPENCODE_JSON" ]; then
|
|
106
|
+
if grep -q "@ikieaneh/opencode-kit" "$OPENCODE_JSON" 2>/dev/null; then
|
|
107
|
+
echo -e " ✅ Plugin registered in opencode.json"
|
|
108
|
+
else
|
|
109
|
+
echo -e " ${YELLOW}⚠️ Plugin not found in opencode.json — add to your plugin array${NC}"
|
|
110
|
+
fi
|
|
111
|
+
else
|
|
112
|
+
echo -e " ${YELLOW}⚠️ No opencode.json found${NC}"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# === Summary ===
|
|
116
|
+
echo ""
|
|
117
|
+
if [ "$ISSUES" -eq 0 ]; then
|
|
118
|
+
echo -e "${GREEN}✅ All checks passed. System healthy.${NC}"
|
|
119
|
+
exit 0
|
|
120
|
+
else
|
|
121
|
+
echo -e "${RED}❌ $ISSUES issue(s) found. Review warnings above.${NC}"
|
|
122
|
+
exit 1
|
|
123
|
+
fi
|
package/src/init.sh
CHANGED
|
@@ -138,6 +138,10 @@ if [ "$PLUGIN_MODE" = false ]; then
|
|
|
138
138
|
chmod +x .opencode/src/telemetry.sh
|
|
139
139
|
echo " ✅ telemetry.sh (executable)"
|
|
140
140
|
|
|
141
|
+
cp "$KIT_DIR/src/doctor.sh" .opencode/src/doctor.sh
|
|
142
|
+
chmod +x .opencode/src/doctor.sh
|
|
143
|
+
echo " ✅ doctor.sh (executable)"
|
|
144
|
+
|
|
141
145
|
# --- Copy agent templates (pre-flight gates) ---
|
|
142
146
|
for agent in orchestrator planner task-manager code-reviewer learner fixer; do
|
|
143
147
|
if [ -f "$KIT_DIR/templates/agents/$agent.md" ]; then
|