Compare commits

..

6 Commits

Author SHA1 Message Date
shokollm
6e9472b5e2 fix(kugetsu): detect session via DB query instead of opencode session list
opencode session list doesn't show sessions in ~/.kugetsu-worktrees/ directories.
This caused detection to fail even though sessions were being created.

Now we query the database directly for sessions matching the worktree path.
Also fixed database path in fix_session_permissions (was ~/.opencode/, should be ~/.local/share/opencode/).
2026-04-02 11:45:35 +00:00
shokollm
775f73348a fix(kugetsu): update forked session permissions after detection
Previously we only fixed base session permissions before forking.
But permissions are NOT inherited from parent to child.

Now we update the newly created session's permissions immediately
after detection, ensuring the forked session can access external
directories like ~/.kugetsu/worktrees/.
2026-04-02 11:15:27 +00:00
2e9081f4f5 Merge pull request 'fix(kugetsu): call fix_session_permissions before forking' (#109) from fix/prefork-permissions into main 2026-04-02 13:10:54 +02:00
shokollm
f7ac2f35fe fix(kugetsu): call fix_session_permissions before forking
- Call fix_session_permissions in cmd_start before forking to ensure
  base session has correct permissions for external_directory access
- Add debug logging to show forked session's directory and permissions
  after creation to help diagnose permission inheritance issues
2026-04-02 11:08:30 +00:00
97d7511e56 Merge pull request 'fix(kugetsu): session detection ordering bug and debugging' (#108) from fix/session-detection-v2 into main 2026-04-02 12:26:57 +02:00
shokollm
cd12a0cda8 fix(kugetsu): fix session detection ordering and add DB debugging
1. Move session detection BEFORE checking if fork process is still running.
   Previous code broke out of loop if forked process exited, skipping detection.

2. Add database query debugging when detection fails to help diagnose
   why opencode session list might miss newly created sessions.
2026-04-02 09:57:27 +00:00

View File

@@ -876,7 +876,7 @@ cmd_doctor() {
}
fix_session_permissions() {
local opencode_db="${OPENCODE_DB:-$HOME/.opencode/opencode.db}"
local opencode_db="${OPENCODE_DB:-$HOME/.local/share/opencode/opencode.db}"
if [ ! -f "$opencode_db" ]; then
echo "[ERROR] opencode database not found: $opencode_db"
@@ -1226,12 +1226,6 @@ cmd_start() {
local session_file="$(issue_ref_to_filename "$issue_ref").json"
# Get list of sessions before fork to compare against after
declare -a before_sessions=()
while IFS= read -r sess; do
before_sessions+=("$sess")
done < <(opencode session list 2>/dev/null | grep -oP '^ses_\w+')
echo "Forking session for '$issue_ref'..."
# Session-counting: count actual dev sessions, reject if at limit
@@ -1244,6 +1238,9 @@ cmd_start() {
fi
local fork_log="$SESSIONS_DIR/$session_file.fork.log"
local opencode_db="${OPENCODE_DB:-$HOME/.local/share/opencode/opencode.db}"
fix_session_permissions
if [ "$DEBUG_MODE" = true ]; then
(cd "$worktree_path" && opencode run "$message" --fork --session "$base_session_id" 2>&1) | tee "$fork_log" &
@@ -1256,37 +1253,27 @@ cmd_start() {
local max_attempts=10
local attempt=1
local new_session_id=""
local fork_log_output=""
while [ $attempt -le $max_attempts ]; do
sleep 1
new_session_id=$(python3 -c "
import sqlite3
conn = sqlite3.connect('$opencode_db')
cursor = conn.cursor()
cursor.execute(\"SELECT id FROM session WHERE directory = '$worktree_path' ORDER BY time_created DESC LIMIT 1\")
result = cursor.fetchone()
if result:
print(result[0])
" 2>/dev/null || echo "")
if [ -n "$new_session_id" ] && [ "$new_session_id" != "$base_session_id" ] && [ "$new_session_id" != "$pm_agent_session_id" ]; then
break
fi
if ! kill -0 $fork_pid 2>/dev/null; then
if [ -s "$fork_log" ]; then
echo "Fork command exited. Log output:" >&2
tail -20 "$fork_log" >&2
fi
break
fi
while IFS= read -r sess; do
[ "$sess" = "$base_session_id" ] && continue
[ "$sess" = "$pm_agent_session_id" ] && continue
local existed_before=false
for before_sess in "${before_sessions[@]}"; do
if [ "$sess" = "$before_sess" ]; then
existed_before=true
break
fi
done
if [ "$existed_before" = false ]; then
new_session_id="$sess"
break
fi
done < <(opencode session list 2>/dev/null | grep -oP '^ses_\w+')
if [ -n "$new_session_id" ]; then
fork_log_output=$(tail -20 "$fork_log" 2>/dev/null || echo "(log empty or unavailable)")
break
fi
@@ -1295,14 +1282,39 @@ cmd_start() {
if [ -z "$new_session_id" ]; then
echo "Error: Could not find newly created session after ${max_attempts}s" >&2
if [ -f "$fork_log" ] && [ -s "$fork_log" ]; then
echo "Fork log:" >&2
tail -30 "$fork_log" >&2
if [ -n "$fork_log_output" ]; then
echo "Fork log output:" >&2
echo "$fork_log_output" >&2
fi
remove_worktree_for_issue "$issue_ref"
exit 1
fi
echo "Updating permissions for new session: $new_session_id"
python3 -c "
import sqlite3
conn = sqlite3.connect('$opencode_db')
cursor = conn.cursor()
PERMISSION_JSON = '[{\"permission\":\"question\",\"pattern\":\"*\",\"action\":\"deny\"},{\"permission\":\"plan_enter\",\"pattern\":\"*\",\"action\":\"deny\"},{\"permission\":\"plan_exit\",\"pattern\":\"*\",\"action\":\"deny\"},{\"permission\":\"external_directory\",\"pattern\":\"*\",\"action\":\"allow\"}]'
cursor.execute('UPDATE session SET permission = ? WHERE id = ?', (PERMISSION_JSON, '$new_session_id'))
conn.commit()
print('[OK] Session permissions updated')
"
if [ "$DEBUG_MODE" = true ]; then
echo "[DEBUG] Forked session permissions check:"
python3 -c "
import sqlite3
conn = sqlite3.connect('$opencode_db')
cursor = conn.cursor()
cursor.execute(\"SELECT id, directory, permission FROM session WHERE id = '$new_session_id'\")
for row in cursor.fetchall():
print(' ID:', row[0])
print(' Directory:', row[1])
print(' Permission:', row[2])
" 2>/dev/null || echo " (failed to query DB)"
fi
printf '{"type": "forked", "issue_ref": "%s", "opencode_session_id": "%s", "worktree_path": "%s", "created_at": "%s", "state": "idle"}\n' \
"$issue_ref" "$new_session_id" "$worktree_path" "$(date -Iseconds)" > "$SESSIONS_DIR/$session_file"