Set Session
Binds the current Claude Code session to a Linear ticket for cross-session correlation.
Behavior
- Accept a ticket ID argument (e.g.,
/onex:set_session PROJ-1234) - Write
task_id: PROJ-1234to.onex_state/active_session.yaml(authoritative binding per Doctrine D1) - Set
ONEX_TASK_ID=PROJ-1234in the process environment as a derived runtime convenience - Emit a
session.status_changedevent withtask_idandstatus: bound - Confirm: "Session bound to PROJ-1234. All events will carry this task_id."
Implementation
Use the TaskBinding service from omniclaude.services.task_binding:
from omniclaude.services.task_binding import TaskBinding
binding = TaskBinding()
# Check for --clear flag
if args == "--clear":
binding.clear()
# Emit session.status_changed with status: unbound
print("Session unbound. Events will no longer carry a task_id.")
else:
# Check for existing binding
existing = binding.detect_existing()
if existing and existing != task_id:
print(f"Replacing existing binding to {existing}.")
binding.bind(task_id)
# Emit session.status_changed with status: bound
print(f"Session bound to {task_id}. All events will carry this task_id.")
Unbinding
/onex:set_session --clear removes the binding:
- Remove
.onex_state/active_session.yaml - Unset
ONEX_TASK_IDfrom the process environment - Emit
session.status_changedwithstatus: unbound
Resume Detection
On session start, if .onex_state/active_session.yaml exists in the working directory,
suggest: "Previous session was bound to PROJ-1234. Resume? (/onex:set_session PROJ-1234)"
Do NOT auto-inject -- user must explicitly opt in.
Note: This skill executes directly (not via general-purpose) because it is a synchronous, user-invoked operation with no need for agent routing.