refactor(skills): make skills portable across users/locations via workspace-relative paths + env var overrides
Changes:
- skills/lib.sh:
- HOME_DIR default changed from $HOME to <workspace_root> (workspace self-sufficient)
- Added CLAUDE_PROJECT_DIR / LOCAL_BIN env var pattern (default $HOME, overridable)
- skills/tmux-agent-orchestrate-monitor/scripts/reconcile.sh:
- STATE_DIR moved from $HOME/.cache/... to <workspace>/.cache/tmux-agent-orchestrate-monitor
- skills/tmux-agent-orchestrate-create/scripts/create_session.sh:
- WRAPPER uses $LOCAL_BIN env var (default $HOME/.local/bin)
- 6 SKILL.md: examples and explanations updated to mention env var override capability
User/portability contract:
- Workspace-internal data: .hermes/ + .cache/ (moves with workspace)
- User/system data: $HOME/* (overridable via CLAUDE_PROJECT_DIR, LOCAL_BIN)
- All env vars follow: ${VAR:-default} pattern with documented defaults
Verified on isolated server -L agy-homeport-test (kill-server after):
- syntax check PASS
- E2E: defaults resolve to workspace-relative paths
- E2E: env var override correctly changes paths
- 0 leftover direct $HOME references in code
- Global skill non-interference verified
- Main isolated server -L multi-agent-canary untouched
This commit is contained in:
+10
-4
@@ -18,6 +18,11 @@ SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
WORKSPACE_ROOT="$(cd "$SKILL_DIR/.." && pwd)"
|
||||
AGENT_SESSIONS_YAML="${AGENT_SESSIONS_YAML:-$WORKSPACE_ROOT/.hermes/agent-sessions.yaml}"
|
||||
|
||||
# Workspace-relative defaults with environment overrides (Phase Z)
|
||||
HOME_DIR="${HOME_DIR:-$WORKSPACE_ROOT}"
|
||||
CLAUDE_PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$HOME/.claude/projects}"
|
||||
LOCAL_BIN="${LOCAL_BIN:-$HOME/.local/bin}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tmux Server Isolation support
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -159,7 +164,7 @@ derive_session_name() {
|
||||
# ---------------------------------------------------------------------------
|
||||
env_python() {
|
||||
local yaml_path="$1"; shift
|
||||
local -a envs=("YAML_PATH=$yaml_path" "HOME_DIR=$HOME")
|
||||
local -a envs=("YAML_PATH=$yaml_path" "HOME_DIR=$HOME_DIR" "CLAUDE_PROJECT_DIR=$CLAUDE_PROJECT_DIR" "LOCAL_BIN=$LOCAL_BIN")
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
*=*) envs+=("$1"); shift ;;
|
||||
@@ -186,7 +191,7 @@ env_python() {
|
||||
# ---------------------------------------------------------------------------
|
||||
atomic_dump_yaml() {
|
||||
local yaml_path="$1"; shift
|
||||
local -a envs=("YAML_PATH=$yaml_path" "HOME_DIR=$HOME")
|
||||
local -a envs=("YAML_PATH=$yaml_path" "HOME_DIR=$HOME_DIR" "CLAUDE_PROJECT_DIR=$CLAUDE_PROJECT_DIR" "LOCAL_BIN=$LOCAL_BIN")
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
*=*) envs+=("$1"); shift ;;
|
||||
@@ -283,6 +288,7 @@ ws = os.environ['WS_ABS']
|
||||
agent = os.environ['AGENT']
|
||||
home = os.environ['HOME_DIR']
|
||||
yaml_path = os.environ['YAML_PATH']
|
||||
claude_project_dir = os.environ.get('CLAUDE_PROJECT_DIR', f"{home}/.claude/projects")
|
||||
|
||||
d = {}
|
||||
if os.path.exists(yaml_path):
|
||||
@@ -292,7 +298,7 @@ if os.path.exists(yaml_path):
|
||||
|
||||
def jsonl_exists(uuid):
|
||||
key = ws.replace('/', '-').replace('_', '-')
|
||||
return os.path.exists(f"{home}/.claude/projects/{key}/{uuid}.jsonl")
|
||||
return os.path.exists(f"{claude_project_dir}/{key}/{uuid}.jsonl")
|
||||
|
||||
|
||||
def db_exists(uuid):
|
||||
@@ -323,7 +329,7 @@ for s in d.get('tmux_sessions', []):
|
||||
# 2) disk scan scoped to THIS workspace
|
||||
if agent == 'claude':
|
||||
key = ws.replace('/', '-').replace('_', '-')
|
||||
proj = f"{home}/.claude/projects/{key}"
|
||||
proj = f"{claude_project_dir}/{key}"
|
||||
if os.path.isdir(proj):
|
||||
for j in sorted(glob.glob(f"{proj}/*.jsonl"), key=os.path.getmtime, reverse=True):
|
||||
sid = None
|
||||
|
||||
Reference in New Issue
Block a user