Skip to content

A lightweight task manager that lets you take ownership of running processes and schedule dependent tasks to run after them.

License

Notifications You must be signed in to change notification settings

Vertsineu/after

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

After

Never lose a process to SSH disconnection again. Take ownership of any running process and build dynamic task workflows on the fly.

A lightweight task manager that lets you take ownership of running processes and schedule dependent tasks to run after them.

Features

  • Take Ownership of Running Processes: Attach to any running process and manage it through After - prevents SSH disconnection or shell exit from killing your processes. Once taken, the process is truly under After's control.
    • Unlike tmux/screen: You don't need to plan ahead. Even if you forgot to use tmux/screen and started a process directly in your SSH session or terminal, After can still take it over and protect it from disconnection.
  • Dynamic Task Dependencies: Add, modify, or remove task dependencies at any time - even while processes are running. Build complex workflows incrementally without upfront planning.
  • Non-invasive Output Monitoring: Tap into task stdout/stderr using ptrace without disrupting the process. Monitor output in real-time without affecting performance.
  • Dynamic Output Redirection: Redirect task output to files at any time using ptrace-injected system calls, no process restart required.
  • Persistent Background Daemon: Client-server architecture ensures tasks continue running independently of any terminal or SSH session.

Requirements

  • Only supports x86_64 Architecture for now
  • Linux (uses ptrace and Linux-specific system calls)
  • Rust toolchain (for building from source)
  • Proper ptrace_scope configuration (requires sudo - see below)

Enabling ptrace for Non-Child Processes

Important: Before using After, you need to configure your system to allow ptrace on non-child processes. Modern Linux systems restrict ptrace usage via kernel.yama.ptrace_scope.

# Temporarily (until reboot)
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

# Permanently (survives reboot)
echo 'kernel.yama.ptrace_scope = 0' | sudo tee -a /etc/sysctl.d/10-ptrace.conf
sudo sysctl -p /etc/sysctl.d/10-ptrace.conf

Security Note: Setting ptrace_scope to 0 allows any process to ptrace any other process owned by the same user. This is less secure than the default setting (1), which only allows ptracing child processes. Only enable this if you understand the security implications.

Installation

Build from Source

git clone https://github.com/Vertsineu/after.git
cd after
cargo install --path .

Make sure ~/.cargo/bin is in your PATH.

Verify Installation

after --help

Quick Command Reference

Common commands have short aliases for faster typing:

  • after tk = after take
  • after dep = after depend
  • after rm = after remove
  • after ls = after list
  • after red = after redirect

Getting Started

Quick Start

# Start any long-running command
sleep 300 &

# Take it over (use the PID from the background job)
after take $!

# View your task
after ls

# You can now close your terminal - the process keeps running!

Example 1: Prevent SSH Disconnection from Killing Your Process

The Problem: You started a long-running process directly in your SSH session without tmux/screen, and now you're worried about disconnection killing it.

The Solution: After can take over any already-running process, even if it's running in your current shell. Unlike tmux/screen which require you to start processes inside them from the beginning, After works retroactively.

# Oops! You started a long build process directly in SSH without tmux/screen
cargo build --release &
echo $!  # Note the PID, e.g., 12345

# No worries - After can take it over right now
after take 12345

# You can now safely disconnect SSH or close your terminal
# The process will keep running under After's management

# Later, reconnect and check status
after list

# Monitor its output in real-time
after tap 0

# Or save output to a file
after redirect 0 build.log

Why this works: After's daemon runs independently of your shell session. When you take a process, After uses ptrace to manage it, effectively detaching it from your terminal's process group. This prevents signals like SIGHUP (sent on SSH disconnection) from killing your process.

Example 2: Dynamically Add Dependencies to Running Processes

After lets you add dependencies at any time, even while the process is already running. You don't need to plan everything upfront!

# Take ownership of a compilation that's already running
after take 12345

# Compilation is still running - you can add dependencies now!
# Run tests only if compilation succeeds
after depend 0 --if-success -- cargo test

# Changed your mind? Add another dependency while it's still compiling
after depend 0 --if-failure -- ./cleanup.sh

# Add more tasks dynamically - chain off the test task
after depend 1 -- notify-send "Build complete"

# View all tasks and their dependency relationships
after list

# Remove a task if you change your mind (if not yet running)
after rm 2

Key insight: Dependencies are dynamic, not static. You can build complex workflows incrementally as your process runs, adjusting based on changing requirements or new ideas.

Example 3: Interactive Process Selection

# Let After show you all processes you can take
after take

# Use arrow keys or j/k to select, press Enter to confirm
# After will immediately show the task list with your new task

Example 4: Complete CI/CD Workflow

# Take a running deployment process
after take 56789

# Chain post-deployment tasks
after depend 0 --if-success -- ./run-smoke-tests.sh
after depend 1 --if-success -- ./notify-team.sh "Deployment successful"
after depend 0 --if-failure -- ./rollback.sh
after depend 3 --if-failure -- ./notify-team.sh "Deployment failed"

# Monitor the entire workflow
after list

Usage

Taking Ownership of a Process

Take control of an existing process by PID:

after take <pid>

Or interactively select from running processes:

after take                    # Select from shell-spawned processes
after take --all              # Select from all user processes
after take --no-ignore-shell  # Include shell processes in selection

Adding Dependent Tasks

Schedule a task to run after another task completes:

# Run after task completes (regardless of success/failure)
after depend <task_id> -- <command> [args...]

# Run only if task succeeds
after depend <task_id> --if-success -- <command> [args...]

# Run only if task fails
after depend <task_id> --if-failure -- <command> [args...]

Example:

# Take ownership of a build process
after take 12345

# Schedule tests to run after build succeeds
after depend 0 --if-success -- cargo test

# Schedule cleanup on failure
after depend 0 --if-failure -- ./cleanup.sh

Monitoring Task Output

Tap into a task's output streams in real-time:

after tap <task_id>              # Show both stdout and stderr
after tap <task_id> --no-stdout  # Show only stderr
after tap <task_id> --no-stderr  # Show only stdout

Redirecting Output

Redirect task output to a file:

after redirect <task_id> <path>              # Redirect both streams
after redirect <task_id> <path> --no-stdout  # Redirect only stderr
after redirect <task_id> <path> --no-stderr  # Redirect only stdout

Listing Tasks

View all managed tasks:

after list

Removing Tasks

Remove a task from management:

after remove <task_id>         # Remove if not running or has no dependents
after remove <task_id> --force # Force removal

How It Works

After uses Linux ptrace to non-invasively attach to running processes. It can:

  • Intercept and record system calls (particularly write syscalls for output monitoring)
  • Inject system calls to redirect file descriptors
  • Monitor process lifecycle and exit status

The daemon process persists in the background, managing all tasks and their dependencies. Each client command connects to the daemon via Unix socket to perform operations.

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

A lightweight task manager that lets you take ownership of running processes and schedule dependent tasks to run after them.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published