Split the monolithic kugetsu script into modular components: Modules created: - kugetsu-config.sh - Config/env loading and global variables - kugetsu-index.sh - Index.json read/write via JSON - kugetsu-worktree.sh - Git worktree operations - kugetsu-log.sh - Structured logging and notifications - kugetsu-session.sh - Session create/fork/destroy logic - kugetsu-queue-daemon.sh - Queue daemon subprocess Main script (kugetsu) is now a thin dispatcher that sources all modules. Acceptance Criteria: - All existing commands work exactly as before - Main script sources modules - Each module is independently testable Fixes #116
136 lines
4.4 KiB
Bash
Executable File
136 lines
4.4 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
read_index() {
|
|
if [ -f "$INDEX_FILE" ]; then
|
|
cat "$INDEX_FILE"
|
|
else
|
|
echo '{"base": null, "pm_agent": null, "issues": {}}'
|
|
fi
|
|
}
|
|
|
|
write_index() {
|
|
local base="$1"
|
|
local pm_agent="$2"
|
|
local issues_json="$3"
|
|
local temp_file="$INDEX_FILE.tmp.$$"
|
|
printf '{"base": %s, "pm_agent": %s, "issues": %s}\n' "$base" "$pm_agent" "$issues_json" > "$temp_file"
|
|
mv "$temp_file" "$INDEX_FILE"
|
|
}
|
|
|
|
get_base_session_id() {
|
|
local index=$(read_index)
|
|
echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('base') or '')"
|
|
}
|
|
|
|
get_pm_agent_session_id() {
|
|
local index=$(read_index)
|
|
echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('pm_agent') or '')"
|
|
}
|
|
|
|
get_session_for_issue() {
|
|
local issue_ref="$1"
|
|
local index=$(read_index)
|
|
echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('issues', {}).get('$issue_ref') or 'null')"
|
|
}
|
|
|
|
set_base_in_index() {
|
|
local session_id="$1"
|
|
local index=$(read_index)
|
|
local pm_agent=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('pm_agent') or 'null')")
|
|
local issues=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(json.dumps(d.get('issues', {})))")
|
|
|
|
if [ "$session_id" = "null" ]; then
|
|
write_index "null" "$pm_agent" "$issues"
|
|
else
|
|
write_index "\"$session_id\"" "$pm_agent" "$issues"
|
|
fi
|
|
}
|
|
|
|
set_pm_agent_in_index() {
|
|
local session_id="$1"
|
|
local index=$(read_index)
|
|
local base=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('base') or 'null')")
|
|
local issues=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(json.dumps(d.get('issues', {})))")
|
|
|
|
if [ "$session_id" = "null" ]; then
|
|
write_index "$base" "null" "$issues"
|
|
else
|
|
write_index "$base" "\"$session_id\"" "$issues"
|
|
fi
|
|
}
|
|
|
|
add_issue_to_index() {
|
|
local issue_ref="$1"
|
|
local session_file="$2"
|
|
|
|
local index=$(read_index)
|
|
local base=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('base') or 'null')")
|
|
local pm_agent=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('pm_agent') or 'null')")
|
|
|
|
local issues=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(json.dumps(d.get('issues', {})))")
|
|
|
|
issues=$(python3 -c "import sys, json; d=json.load(sys.stdin); d['$issue_ref']='$session_file'; print(json.dumps(d))" <<< "$issues")
|
|
|
|
write_index "$base" "$pm_agent" "$issues"
|
|
}
|
|
|
|
remove_issue_from_index() {
|
|
local issue_ref="$1"
|
|
|
|
local index=$(read_index)
|
|
local base=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('base') or 'null')")
|
|
local pm_agent=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('pm_agent') or 'null')")
|
|
|
|
local issues=$(echo "$index" | python3 -c "import sys, json; d=json.load(sys.stdin); print(json.dumps(d.get('issues', {})))")
|
|
|
|
issues=$(python3 -c "import sys, json; d=json.load(sys.stdin); d.pop('$issue_ref', None); print(json.dumps(d))" <<< "$issues")
|
|
|
|
write_index "$base" "$pm_agent" "$issues"
|
|
}
|
|
|
|
validate_issue_ref() {
|
|
local issue_ref="$1"
|
|
|
|
if [[ ! "$issue_ref" =~ ^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+#[0-9]+$ ]]; then
|
|
echo "Error: Invalid issue ref format: '$issue_ref'" >&2
|
|
echo "Expected format: instance/user/repo#number" >&2
|
|
echo "Example: github.com/shoko/kugetsu#14" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
update_session_pr_url() {
|
|
local issue_ref="$1"
|
|
local pr_url="$2"
|
|
|
|
local session_file=$(get_session_for_issue "$issue_ref")
|
|
if [ -z "$session_file" ] || [ "$session_file" = "null" ]; then
|
|
echo "Error: No session found for '$issue_ref'" >&2
|
|
return 1
|
|
fi
|
|
|
|
local session_path="$SESSIONS_DIR/$session_file"
|
|
if [ ! -f "$session_path" ]; then
|
|
echo "Error: Session file not found: $session_path" >&2
|
|
return 1
|
|
fi
|
|
|
|
python3 << PYEOF
|
|
import json
|
|
|
|
session_path = "$session_path"
|
|
pr_url = "$pr_url"
|
|
|
|
with open(session_path, 'r') as f:
|
|
session = json.load(f)
|
|
|
|
session['pr_url'] = pr_url
|
|
|
|
with open(session_path, 'w') as f:
|
|
json.dump(session, f, indent=2)
|
|
|
|
print(f"Updated PR URL for $issue_ref: $pr_url")
|
|
PYEOF
|
|
}
|