feat: add destroy command and session_id validation
- Add destroy subcommand for deleting sessions - Add destroy --all for fresh start with confirmation - Add -y flag to skip confirmation prompts - Add validate_session_id() to reject empty session_ids - Remove misleading force resume error message - Update SKILL.md to v1.1 with destroy documentation
This commit is contained in:
@@ -5,7 +5,7 @@ license: MIT
|
|||||||
compatibility: Requires opencode CLI, bash, and filesystem access for session state.
|
compatibility: Requires opencode CLI, bash, and filesystem access for session state.
|
||||||
metadata:
|
metadata:
|
||||||
author: shoko
|
author: shoko
|
||||||
version: "1.0"
|
version: "1.1"
|
||||||
---
|
---
|
||||||
|
|
||||||
# kugetsu - OpenCode Session Manager
|
# kugetsu - OpenCode Session Manager
|
||||||
@@ -85,6 +85,23 @@ kugetsu stop mytask
|
|||||||
- Sends SIGTERM to process
|
- Sends SIGTERM to process
|
||||||
- Sets state to `idle`
|
- Sets state to `idle`
|
||||||
|
|
||||||
|
### kugetsu destroy `<session_id>` [-y]
|
||||||
|
Delete a session:
|
||||||
|
```bash
|
||||||
|
kugetsu destroy mytask # Prompts for confirmation (default: N)
|
||||||
|
kugetsu destroy mytask -y # Skips confirmation
|
||||||
|
```
|
||||||
|
- Errors if session is `used` (use `stop` first)
|
||||||
|
- Errors if session not found
|
||||||
|
|
||||||
|
### kugetsu destroy --all [-y]
|
||||||
|
Delete all sessions:
|
||||||
|
```bash
|
||||||
|
kugetsu destroy --all # Prompts for confirmation (default: N)
|
||||||
|
kugetsu destroy --all -y # Skips confirmation
|
||||||
|
```
|
||||||
|
- Useful for fresh start
|
||||||
|
|
||||||
### kugetsu help
|
### kugetsu help
|
||||||
Show usage help.
|
Show usage help.
|
||||||
|
|
||||||
@@ -94,6 +111,9 @@ Show usage help.
|
|||||||
start ──────────────► used ──────► idle (stop/SIGTERM)
|
start ──────────────► used ──────► idle (stop/SIGTERM)
|
||||||
│
|
│
|
||||||
└──────► left (kill/SIGINT/crash)
|
└──────► left (kill/SIGINT/crash)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
destroy (delete)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example Workflow
|
## Example Workflow
|
||||||
@@ -112,6 +132,9 @@ kugetsu resume issue42
|
|||||||
|
|
||||||
# Later, when done
|
# Later, when done
|
||||||
kugetsu stop issue42
|
kugetsu stop issue42
|
||||||
|
|
||||||
|
# When you want a fresh start
|
||||||
|
kugetsu destroy --all
|
||||||
```
|
```
|
||||||
|
|
||||||
## Without kugetsu
|
## Without kugetsu
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ usage() {
|
|||||||
kugetsu - OpenCode Session Manager
|
kugetsu - OpenCode Session Manager
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
kugetsu start <session_id> <message> Start a new session
|
kugetsu start <session_id> <message> Start a new session
|
||||||
kugetsu list [--all] List sessions (default: left only)
|
kugetsu list [--all] List sessions (default: left only)
|
||||||
kugetsu resume <session_id> [message] Resume a session
|
kugetsu resume <session_id> [message] Resume a session
|
||||||
kugetsu stop <session_id> Stop a session gracefully
|
kugetsu stop <session_id> Stop a session gracefully
|
||||||
kugetsu help Show this help
|
kugetsu destroy <session_id> [-y] Delete a session (prompts confirmation)
|
||||||
|
kugetsu destroy --all [-y] Delete all sessions (prompts confirmation)
|
||||||
|
kugetsu help Show this help
|
||||||
|
|
||||||
States:
|
States:
|
||||||
used - Session is active (process running)
|
used - Session is active (process running)
|
||||||
@@ -29,6 +31,10 @@ Examples:
|
|||||||
kugetsu resume mytask
|
kugetsu resume mytask
|
||||||
kugetsu resume mytask "continue working"
|
kugetsu resume mytask "continue working"
|
||||||
kugetsu stop mytask
|
kugetsu stop mytask
|
||||||
|
kugetsu destroy mytask
|
||||||
|
kugetsu destroy mytask -y
|
||||||
|
kugetsu destroy --all
|
||||||
|
kugetsu destroy --all -y
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +42,14 @@ ensure_dirs() {
|
|||||||
mkdir -p "$SESSIONS_DIR" "$BIN_DIR"
|
mkdir -p "$SESSIONS_DIR" "$BIN_DIR"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate_session_id() {
|
||||||
|
local session_id="$1"
|
||||||
|
if [ -z "$session_id" ]; then
|
||||||
|
echo "Error: session_id cannot be empty" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
get_session_dir() {
|
get_session_dir() {
|
||||||
local session_id="$1"
|
local session_id="$1"
|
||||||
echo "$SESSIONS_DIR/$session_id"
|
echo "$SESSIONS_DIR/$session_id"
|
||||||
@@ -93,6 +107,7 @@ cmd_start() {
|
|||||||
|
|
||||||
local session_id="$1"
|
local session_id="$1"
|
||||||
local message="$2"
|
local message="$2"
|
||||||
|
validate_session_id "$session_id"
|
||||||
local session_dir=$(get_session_dir "$session_id")
|
local session_dir=$(get_session_dir "$session_id")
|
||||||
|
|
||||||
ensure_dirs
|
ensure_dirs
|
||||||
@@ -176,6 +191,7 @@ cmd_resume() {
|
|||||||
|
|
||||||
local session_id="$1"
|
local session_id="$1"
|
||||||
local message=""
|
local message=""
|
||||||
|
validate_session_id "$session_id"
|
||||||
|
|
||||||
if [ $# -ge 2 ]; then
|
if [ $# -ge 2 ]; then
|
||||||
message="$2"
|
message="$2"
|
||||||
@@ -199,7 +215,6 @@ cmd_resume() {
|
|||||||
fi
|
fi
|
||||||
if [ -n "$pid" ] && is_process_running "$pid"; then
|
if [ -n "$pid" ] && is_process_running "$pid"; then
|
||||||
echo "Error: process $pid is still running for this session" >&2
|
echo "Error: process $pid is still running for this session" >&2
|
||||||
echo "Use 'kugetsu stop $session_id' first, or 'kugetsu resume $session_id' to force resume anyway" >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
set_state "$session_dir" "left"
|
set_state "$session_dir" "left"
|
||||||
@@ -255,6 +270,7 @@ cmd_stop() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local session_id="$1"
|
local session_id="$1"
|
||||||
|
validate_session_id "$session_id"
|
||||||
local session_dir=$(get_session_dir "$session_id")
|
local session_dir=$(get_session_dir "$session_id")
|
||||||
|
|
||||||
if [ ! -d "$session_dir" ]; then
|
if [ ! -d "$session_dir" ]; then
|
||||||
@@ -296,6 +312,95 @@ cmd_stop() {
|
|||||||
echo "Session '$session_id' stopped"
|
echo "Session '$session_id' stopped"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd_destroy() {
|
||||||
|
local session_id=""
|
||||||
|
local destroy_all=false
|
||||||
|
local force=false
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--all)
|
||||||
|
destroy_all=true
|
||||||
|
;;
|
||||||
|
-y|--yes)
|
||||||
|
force=true
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo "Error: unknown option '$1'" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [ -n "$session_id" ]; then
|
||||||
|
echo "Error: too many arguments" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
session_id="$1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$destroy_all" = true ]; then
|
||||||
|
if [ -n "$session_id" ]; then
|
||||||
|
echo "Error: cannot specify session_id with --all" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$force" = true ]; then
|
||||||
|
rm -rf "$SESSIONS_DIR"/*
|
||||||
|
echo "All sessions deleted"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Delete ALL sessions? [y/N] "
|
||||||
|
local reply
|
||||||
|
read reply
|
||||||
|
if [ "$reply" = "y" ] || [ "$reply" = "Y" ]; then
|
||||||
|
rm -rf "$SESSIONS_DIR"/*
|
||||||
|
echo "All sessions deleted"
|
||||||
|
else
|
||||||
|
echo "Aborted"
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$session_id" ]; then
|
||||||
|
echo "Error: destroy requires <session_id> or --all" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
validate_session_id "$session_id"
|
||||||
|
local session_dir=$(get_session_dir "$session_id")
|
||||||
|
|
||||||
|
if [ ! -d "$session_dir" ]; then
|
||||||
|
echo "Error: session '$session_id' not found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local state=$(get_state "$session_dir")
|
||||||
|
if [ "$state" = "used" ]; then
|
||||||
|
echo "Error: session '$session_id' is in use (state=used)" >&2
|
||||||
|
echo "Use 'kugetsu stop $session_id' first" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$force" = true ]; then
|
||||||
|
rm -rf "$session_dir"
|
||||||
|
echo "Session '$session_id' deleted"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Delete session '$session_id'? [y/N] "
|
||||||
|
local reply
|
||||||
|
read reply
|
||||||
|
if [ "$reply" = "y" ] || [ "$reply" = "Y" ]; then
|
||||||
|
rm -rf "$session_dir"
|
||||||
|
echo "Session '$session_id' deleted"
|
||||||
|
else
|
||||||
|
echo "Aborted"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
if [ $# -eq 0 ]; then
|
if [ $# -eq 0 ]; then
|
||||||
usage
|
usage
|
||||||
@@ -321,6 +426,9 @@ main() {
|
|||||||
stop)
|
stop)
|
||||||
cmd_stop "$@"
|
cmd_stop "$@"
|
||||||
;;
|
;;
|
||||||
|
destroy)
|
||||||
|
cmd_destroy "$@"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Error: unknown command '$command'" >&2
|
echo "Error: unknown command '$command'" >&2
|
||||||
usage
|
usage
|
||||||
|
|||||||
Reference in New Issue
Block a user