feat(opencode): wire 29-point CLI lifecycle scripts, drift-C reconciler, and skill docs

This commit is contained in:
2026-08-29 14:59:01 +09:00
parent 7341186ef9
commit 94af7f6b8a
14 changed files with 303 additions and 35 deletions
@@ -49,7 +49,7 @@ ideal resume path:
`agent-sessions.yaml` and on-disk discovery are used to resolve the UUID in this order:
1. **`herdr_sessions[]` row's per-row own id** (`claude_session_id_own` / `agy_conversation_id_own` / `hermes_conversation_id_own` / `grok_session_id_own`) — explicitly saved by `multi-agent-mux-stop` right before teardown (tier-1, race-free).
1. **`herdr_sessions[]` row's per-row own id** (`claude_session_id_own` / `agy_conversation_id_own` / `hermes_conversation_id_own` / `grok_session_id_own` / `opencode_session_id_own`) — explicitly saved by `multi-agent-mux-stop` right before teardown (tier-1, race-free).
2. **Workspace-scoped on-disk scan** (adapter `discover()`)
If both are empty → the workspace has no conversation yet. Fall back to `multi-agent-mux-create`.
@@ -58,7 +58,7 @@ If both are empty → the workspace has no conversation yet. Fall back to `multi
```bash
WORKSPACE=/path/to/project
AGENT=claude # claude | agy | hermes | grok — pass it explicitly
AGENT=claude # claude | agy | hermes | grok | opencode — pass it explicitly
SESSION_NAME=<workspace>-creator-<agent> # same convention as multi-agent-mux-create
# Resolve the isolated herdr server name & load common utils
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# resolve_session_id.sh — multi-agent-mux-resume 의 부속 스크립트
# Usage:
# bash resolve_session_id.sh --workspace <path> --agent <claude|agy|hermes|grok>
# bash resolve_session_id.sh --workspace <path> --agent <claude|agy|hermes|grok|opencode>
# 출력: stdout 으로 UUID 한 줄 (없으면 빈 줄 + exit 0)
#
# P0-C: 전역 agent_identities 를 즉시 반환하지 않는다. lib.sh::find_workspace_uuid
@@ -13,7 +13,7 @@ source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib.sh"
usage() {
cat <<EOF
Usage: $0 --workspace <path> --agent <claude|agy|hermes|grok> [--session <name>]
Usage: $0 --workspace <path> --agent <claude|agy|hermes|grok|opencode> [--session <name>]
Outputs the resolved UUID on stdout (empty if not found).
--session prefers that registry row's recorded id; falls back to workspace-wide discovery if it does not verify.
EOF
@@ -36,8 +36,8 @@ done
[ -n "$WORKSPACE" ] || { echo "ERROR: --workspace required" >&2; exit 2; }
[ -n "$AGENT" ] || { echo "ERROR: --agent required" >&2; exit 2; }
case "$AGENT" in
claude|agy|hermes|grok) ;;
*) echo "ERROR: --agent must be claude, agy, hermes, or grok" >&2; exit 2 ;;
claude|agy|hermes|grok|opencode) ;;
*) echo "ERROR: --agent must be claude, agy, hermes, grok, or opencode" >&2; exit 2 ;;
esac
find_workspace_uuid "$WORKSPACE" "$AGENT" "$SESSION_NAME"
@@ -9,7 +9,7 @@ source "$LIB_SH"
usage() {
cat <<EOF
Usage: $0 --workspace <path> --agent <claude|agy|hermes|grok> --session <name> [options]
Usage: $0 --workspace <path> --agent <claude|agy|hermes|grok|opencode> --session <name> [options]
Options:
--herdr-session NAME specify isolated herdr session name (alias: --herdr-server)
@@ -42,7 +42,7 @@ done
[ -n "$WORKSPACE" ] || { echo "ERROR: --workspace required" >&2; exit 2; }
[ -n "$AGENT" ] || { echo "ERROR: --agent required" >&2; exit 2; }
case "$AGENT" in
claude|agy|hermes|grok) ;;
claude|agy|hermes|grok|opencode) ;;
*) echo "ERROR: unsupported agent: $AGENT" >&2; exit 2 ;;
esac
[ -n "$SESSION_NAME" ] || { echo "ERROR: --session required" >&2; exit 2; }
@@ -103,6 +103,7 @@ if [ -z "$CMD_FULL" ]; then
agy) CMD_FULL="${RESOLVED_BIN} --dangerously-skip-permissions --conversation $UUID" ;;
hermes) CMD_FULL="${RESOLVED_BIN} --resume $UUID --no-restore-cwd --yolo --accept-hooks" ;;
grok) CMD_FULL="${RESOLVED_BIN} --resume $UUID --permission-mode bypassPermissions" ;;
opencode) CMD_FULL="${RESOLVED_BIN} --session $UUID --auto --agent build" ;;
*) echo "ERROR: unsupported agent: $AGENT" >&2; exit 2 ;;
esac
fi
@@ -125,6 +126,12 @@ if [ "${DRY_RUN:-0}" = "1" ]; then
exit 0
fi
if [ "$AGENT" = "opencode" ]; then
if [ -z "${OPENCODE_PERMISSION:-}" ]; then
export OPENCODE_PERMISSION='{"*":"allow"}'
fi
fi
# 4. Spawn new agent session (delegates to herdr translation shim)
_herdr new-session -d -s "$SESSION_NAME" -c "$WORKSPACE" "$CMD_FULL"
if [ "$AGENT" = "claude" ]; then
@@ -4,14 +4,14 @@
# resume UUID 를 per-row own id (claude_session_id_own / agy_conversation_id_own)
# 에 박는다 — agent_identities 전역은 더 이상 primary 아님 (cache 로 강등, P0-C/단계 e).
#
# Usage: bash update_yaml_resumed.sh --session <name> --uuid <id> [--agent claude|agy|hermes|grok]
# Usage: bash update_yaml_resumed.sh --session <name> --uuid <id> [--agent claude|agy|hermes|grok|opencode]
set -euo pipefail
source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib.sh"
usage() {
cat <<EOF
Usage: $0 --session <name> --uuid <id> [--agent claude|agy|hermes|grok] [--herdr-session <name>]
Usage: $0 --session <name> --uuid <id> [--agent claude|agy|hermes|grok|opencode] [--herdr-session <name>]
EOF
}
@@ -190,6 +190,20 @@ elif agent == 'hermes':
cp = os.environ.get('CHILD_PID', '0')
if cp.isdigit() and int(cp) > 0:
target['child_pid'] = int(cp)
elif agent == 'grok':
target['pane']['cmd'] = 'grok'
target['pane']['cmd_full'] = f'grok --resume {uuid}'
target['grok_session_id_own'] = uuid
cp = os.environ.get('CHILD_PID', '0')
if cp.isdigit() and int(cp) > 0:
target['child_pid'] = int(cp)
elif agent == 'opencode':
target['pane']['cmd'] = 'opencode'
target['pane']['cmd_full'] = f'opencode --session {uuid} --auto --agent build'
target['opencode_session_id_own'] = uuid
cp = os.environ.get('CHILD_PID', '0')
if cp.isdigit() and int(cp) > 0:
target['child_pid'] = int(cp)
snap = d.setdefault('snapshot', {})
snap['taken_at'] = now