@ikieaneh/opencode-kit 0.5.6 → 0.5.8

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
@@ -224,6 +224,25 @@ INIT → PLAN → PLAN_SCORED → EXECUTE → EXECUTE_SCORED → REVIEW → REVI
224
224
 
225
225
  Each phase transition requires a score ≥70 to proceed.
226
226
 
227
+ ### CLI Commands
228
+
229
+ Once installed, run these from the project root:
230
+
231
+ | Command | Purpose |
232
+ |---------|---------|
233
+ | `bash .opencode/src/status.sh` | Dashboard — contract state, telemetry, rules |
234
+ | `bash .opencode/src/doctor.sh` | Diagnostics — MCPs, contract, git, persistence |
235
+ | `bash .opencode/src/analytics.sh` | Telemetry aggregation — phase times, cost estimates |
236
+ | `bash .opencode/src/diff.sh` [branch1] [branch2] | Compare contract state between branches |
237
+ | `bash .opencode/src/adr.sh` | Record a new Architecture Decision Record |
238
+ | `bash .opencode/src/telemetry.sh` | View telemetry details |
239
+ | `bash .opencode/src/new-skill.sh` <name> | Scaffold a new skill SKILL.md |
240
+ | `bash .opencode/rules/validation.sh` | Validate rules compliance |
241
+ | `npx opencode-kit --version` | Print version |
242
+ | `npx opencode-kit --help` | Print help |
243
+
244
+
245
+
227
246
  <p align="right">(<a href="#readme-top">back to top</a>)</p>
228
247
 
229
248
  <!-- STRUCTURE -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikieaneh/opencode-kit",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
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/adr.sh CHANGED
@@ -5,6 +5,7 @@
5
5
  set -euo pipefail
6
6
 
7
7
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ # shellcheck source=./platform.sh
8
9
  . "$SCRIPT_DIR/platform.sh"
9
10
 
10
11
  CONTRACT_FILE=".opencode/orchestration/contract.json"
@@ -87,6 +88,7 @@ fi
87
88
 
88
89
  # --- Build ADR entry ---
89
90
  # --- Build ADR entry via heredoc to avoid nested quote issues ---
91
+ # shellcheck disable=SC2001
90
92
  $PYTHON_CMD -c "
91
93
  import json, sys, os
92
94
 
package/src/analytics.sh CHANGED
@@ -4,6 +4,7 @@
4
4
  set -euo pipefail
5
5
 
6
6
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ # shellcheck source=./platform.sh
7
8
  . "$SCRIPT_DIR/platform.sh"
8
9
 
9
10
  TELEMETRY_DIR=".opencode/telemetry"
package/src/diff.sh ADDED
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env bash
2
+ # opencode-kit diff — compare contract state between branches
3
+ # Usage: bash src/diff.sh [branch1] [branch2]
4
+ # Default: compares current branch vs main
5
+ set -euo pipefail
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ # shellcheck source=./platform.sh
9
+ . "$SCRIPT_DIR/platform.sh"
10
+
11
+ CONTRACT_FILE=".opencode/orchestration/contract.json"
12
+ BRANCH_A="${1:-main}"
13
+ BRANCH_B="${2:-HEAD}"
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
+ echo -e "${CYAN}📋 opencode-kit diff: $BRANCH_A ↔ $BRANCH_B${NC}"
22
+ echo ""
23
+
24
+ # Extract contract from a git ref
25
+ get_contract_state() {
26
+ local branch="$1"
27
+ local content
28
+ content=$(git show "$branch:$CONTRACT_FILE" 2>/dev/null || echo "")
29
+ if [ -z "$content" ]; then
30
+ echo ""
31
+ return 1
32
+ fi
33
+ echo "$content"
34
+ }
35
+
36
+ CONTRACT_A=$(get_contract_state "$BRANCH_A")
37
+ CONTRACT_B=$(get_contract_state "$BRANCH_B")
38
+
39
+ if [ -z "$CONTRACT_A" ] && [ -z "$CONTRACT_B" ]; then
40
+ echo -e "${YELLOW}No contract found in either branch.${NC}"
41
+ exit 0
42
+ fi
43
+
44
+ # Show state diff
45
+ if [ -n "$PYTHON_CMD" ]; then
46
+ $PYTHON_CMD -c "
47
+ import json, sys
48
+
49
+ def get_state(c):
50
+ try:
51
+ d = json.loads(c)
52
+ return {
53
+ 'state': d.get('state', '?'),
54
+ 'goal': (d.get('requirements', {}) or {}).get('goal', '?'),
55
+ 'score': (d.get('score', {}) or {}).get('combined', '?'),
56
+ 'phases': (d.get('metrics', {}) or {}).get('phases_completed', []),
57
+ 'adrs': len((d.get('decisions', {}) or {}).get('adr_log', [])),
58
+ 'version': d.get('contract_version', '?')
59
+ }
60
+ except:
61
+ return None
62
+
63
+ a = get_state('''$CONTRACT_A''') if '''$CONTRACT_A''' else None
64
+ b = get_state('''$CONTRACT_B''') if '''$CONTRACT_B''' else None
65
+
66
+ if a and b:
67
+ print(f' Field $BRANCH_A $BRANCH_B')
68
+ print(f' {"─"*50}')
69
+ for field in ['state', 'goal', 'score', 'version']:
70
+ va = str(a.get(field, '?'))[:20]
71
+ vb = str(b.get(field, '?'))[:20]
72
+ marker = ' ←→' if va != vb else ' '
73
+ print(f' {field:20s} {va:20s} {marker} {vb:20s}')
74
+ print(f' phases {len(a.get(\"phases\",[])):3d} completed {len(b.get(\"phases\",[])):3d} completed')
75
+ print(f' ADRs {a.get(\"adrs\",0):3d} recorded {b.get(\"adrs\",0):3d} recorded')
76
+ elif a and not b:
77
+ print(f' Contract exists in $BRANCH_A but NOT in $BRANCH_B')
78
+ print(f' State: {a.get(\"state\",\"?\")}')
79
+ elif b and not a:
80
+ print(f' Contract exists in $BRANCH_B but NOT in $BRANCH_A')
81
+ print(f' State: {b.get(\"state\",\"?\")}')
82
+ " 2>/dev/null || echo -e "${YELLOW}Could not parse contract JSON${NC}"
83
+ fi
84
+
85
+ # Raw git diff
86
+ echo ""
87
+ echo -e "${CYAN}Raw diff:${NC}"
88
+ if git diff "$BRANCH_A" "$BRANCH_B" -- "$CONTRACT_FILE" 2>/dev/null | head -40; then
89
+ if ! git diff --exit-code "$BRANCH_A" "$BRANCH_B" -- "$CONTRACT_FILE" &>/dev/null; then
90
+ :
91
+ fi
92
+ fi
93
+ echo ""
94
+ echo -e "Run: ${GREEN}bash .opencode/src/diff.sh${NC} (default: main vs HEAD)"
95
+ echo -e " ${GREEN}bash .opencode/src/diff.sh staging feature-x${NC} (custom branches)"
package/src/doctor.sh CHANGED
@@ -5,6 +5,7 @@
5
5
  set -euo pipefail
6
6
 
7
7
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ # shellcheck source=./platform.sh
8
9
  . "$SCRIPT_DIR/platform.sh"
9
10
  . "$SCRIPT_DIR/global-config.sh"
10
11
 
@@ -4,6 +4,7 @@
4
4
  set -euo pipefail
5
5
 
6
6
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ # shellcheck source=./platform.sh
7
8
  . "$SCRIPT_DIR/platform.sh"
8
9
 
9
10
  PLUGIN_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
package/src/init.sh CHANGED
@@ -6,6 +6,7 @@
6
6
  set -euo pipefail
7
7
 
8
8
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
9
+ # shellcheck source=./platform.sh
9
10
  . "$SCRIPT_DIR/platform.sh"
10
11
  . "$SCRIPT_DIR/global-config.sh"
11
12
  KIT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
@@ -88,7 +89,7 @@ if [ -d ".opencode" ]; then
88
89
  fi
89
90
 
90
91
  # --- Scaffold directories ---
91
- mkdir -p .opencode/orchestration .opencode/rules .opencode/agents .opencode/src
92
+ mkdir -p .opencode/orchestration .opencode/rules .opencode/agents .opencode/src .opencode/templates
92
93
 
93
94
  # --- Copy templates ---
94
95
  echo ""
@@ -154,6 +155,10 @@ if [ "$PLUGIN_MODE" = false ]; then
154
155
  chmod +x .opencode/src/analytics.sh
155
156
  echo " ✅ analytics.sh (executable)"
156
157
 
158
+ cp "$KIT_DIR/src/diff.sh" .opencode/src/diff.sh
159
+ chmod +x .opencode/src/diff.sh
160
+ echo " ✅ diff.sh (executable)"
161
+
157
162
  # --- Copy agent templates (pre-flight gates) ---
158
163
  for agent in orchestrator planner task-manager code-reviewer learner fixer; do
159
164
  if [ -f "$KIT_DIR/templates/agents/$agent.md" ]; then
package/src/postflight.sh CHANGED
@@ -4,6 +4,7 @@
4
4
  set -euo pipefail
5
5
 
6
6
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ # shellcheck source=./platform.sh
7
8
  . "$SCRIPT_DIR/platform.sh"
8
9
 
9
10
  CONTRACT_KEY="orchestration-contract"
@@ -12,6 +13,7 @@ STATE_FILE="STATE.md"
12
13
  TELEMETRY_DIR=".opencode/telemetry"
13
14
  START_TIME_FILE=".opencode/telemetry/.phase_start"
14
15
  STATE_BACKUP_DIR=".opencode/state"
16
+ TEMPLATE_FILE=".opencode/templates/contract.json"
15
17
 
16
18
  mkdir -p "$TELEMETRY_DIR" "$STATE_BACKUP_DIR"
17
19
 
@@ -46,6 +48,46 @@ if [ -z "$CURRENT_CONTRACT" ]; then
46
48
  fi
47
49
  fi
48
50
 
51
+ # --- Step 1b: Contract migration (auto-upgrade old schema) ---
52
+ if [ -n "$CURRENT_CONTRACT" ] && [ -f "$TEMPLATE_FILE" ] && [ -n "$PYTHON_CMD" ]; then
53
+ MIGRATED=$($PYTHON_CMD -c "
54
+ import json
55
+
56
+ try:
57
+ contract = json.loads('''$CURRENT_CONTRACT''')
58
+ with open('$TEMPLATE_FILE') as f:
59
+ template = json.load(f)
60
+
61
+ # Check version
62
+ old_ver = contract.get('contract_version', '0.0.0')
63
+ new_ver = template.get('contract_version', '0.5.2')
64
+
65
+ if old_ver == new_ver and all(k in contract for k in ['state','requirements','governance','score']):
66
+ print('NO_MIGRATION')
67
+ else:
68
+ # Merge missing top-level fields from template
69
+ for key in template:
70
+ if key not in contract:
71
+ contract[key] = template[key]
72
+ # Merge governance.extension_skills if missing
73
+ if 'extension_skills' not in contract.get('governance', {}):
74
+ if 'governance' not in contract:
75
+ contract['governance'] = {}
76
+ contract['governance']['extension_skills'] = []
77
+ # Update version
78
+ contract['contract_version'] = new_ver
79
+ print(json.dumps(contract))
80
+ except Exception as e:
81
+ print('MIGRATE_ERROR:'+str(e))
82
+ " 2>/dev/null || echo "MIGRATE_ERROR")
83
+
84
+ if [ -n "$MIGRATED" ] && [ "$MIGRATED" != "NO_MIGRATION" ] && [ "$MIGRATED" != "MIGRATE_ERROR" ]; then
85
+ CURRENT_CONTRACT="$MIGRATED"
86
+ echo "$MIGRATED" > "$CONTRACT_FILE"
87
+ echo " 🔄 Contract migrated to v$(echo "$MIGRATED" | $PYTHON_CMD -c "import sys,json; print(json.load(sys.stdin).get('contract_version','?'))" 2>/dev/null)"
88
+ fi
89
+ fi
90
+
49
91
  # --- Step 2: Persist (try lean-ctx first, fall back to file) ---
50
92
  PERSISTED=false
51
93
  if lean-ctx ctx_knowledge remember \
package/src/preflight.sh CHANGED
@@ -4,6 +4,7 @@
4
4
  set -euo pipefail
5
5
 
6
6
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ # shellcheck source=./platform.sh
7
8
  . "$SCRIPT_DIR/platform.sh"
8
9
 
9
10
  CONTRACT_KEY="orchestration-contract"
package/src/status.sh CHANGED
@@ -4,6 +4,7 @@
4
4
  set -euo pipefail
5
5
 
6
6
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ # shellcheck source=./platform.sh
7
8
  . "$SCRIPT_DIR/platform.sh"
8
9
 
9
10
  CONTRACT_FILE=".opencode/orchestration/contract.json"
package/src/telemetry.sh CHANGED
@@ -4,6 +4,7 @@
4
4
  set -euo pipefail
5
5
 
6
6
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ # shellcheck source=./platform.sh
7
8
  . "$SCRIPT_DIR/platform.sh"
8
9
 
9
10
  TELEMETRY_DIR=".opencode/telemetry"
package/src/update.sh CHANGED
@@ -5,6 +5,7 @@
5
5
  set -euo pipefail
6
6
 
7
7
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ # shellcheck source=./platform.sh
8
9
  . "$SCRIPT_DIR/platform.sh"
9
10
 
10
11
  RED='\033[0;31m'