Skip to content

Conversation

@noperator
Copy link
Contributor

Adds --json flag to shpool list to expose session data including when sessions were last connected/disconnected, making it easier to identify recently-used sessions.

Closes #292

Supersedes #293, which added optional columns to the tabular output. Per maintainer feedback, pivoted to a single --json flag that outputs all session data as JSON, allowing users to filter/format with jq.

New --json CLI flag:

$ shpool  list --help
lists all the running shell sessions

Usage: shpool list [OPTIONS]

Options:
  -j, --json  Output as JSON
  -h, --help  Print help

Behavior:

  • Default output unchanged. Without the flag, shpool list behaves exactly as before.
  • JSON output includes all fields: name, started_at_unix_ms, connected_at_unix_ms, disconnected_at_unix_ms, status
  • Timestamps are null until the relevant event occurs.

Testing:

# start daemon
./target/debug/shpool -s /tmp/shpool-dev.sock daemon

# open this session, then detach
./target/debug/shpool -s /tmp/shpool-dev.sock attach test1

# default list output unchanged
./target/debug/shpool -s /tmp/shpool-dev.sock list
NAME	STARTED_AT	STATUS
test1	2026-01-23T20:16:12.467+00:00	disconnected

# JSON contains extra session data
./target/debug/shpool -s /tmp/shpool-dev.sock list --json
{
  "sessions": [
    {
      "name": "test1",
      "started_at_unix_ms": 1769199372467,
      "connected_at_unix_ms": 1769199372467,
      "disconnected_at_unix_ms": 1769199373669,
      "status": "Disconnected"
    }
  ]
}

# open another session so we can compare and sort by time
./target/debug/shpool -s /tmp/shpool-dev.sock attach test2

# use jq for custom/complex session sorting (in this case, by recent activity)
./target/debug/shpool -s /tmp/shpool-dev.sock list --json |
    jq '.sessions | sort_by([
        ({ "Disconnected": 0, "Attached": 1 }[.status]),
        (if .status == "Attached" then .connected_at_unix_ms else .disconnected_at_unix_ms end)
    ])'
[
  {
    "name": "test1",
    "started_at_unix_ms": 1769199372467,
    "connected_at_unix_ms": 1769199372467,
    "disconnected_at_unix_ms": 1769199373669,
    "status": "Disconnected"
  },
  {
    "name": "test2",
    "started_at_unix_ms": 1769199432284,
    "connected_at_unix_ms": 1769199432284,
    "disconnected_at_unix_ms": null,
    "status": "Attached"
  }
]

Track when sessions were last connected and disconnected. Add --json
flag to output all session data as JSON for scripting.

Example:
  shpool list --json | jq '.sessions | sort_by([
    ({"Disconnected": 0, "Attached": 1}[.status]),
    (if .status == "Attached" then .connected_at_unix_ms else .disconnected_at_unix_ms end)
  ])'

Default tabular output unchanged.
Copy link
Contributor

@ethanpailes ethanpailes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! just a few bits of feedback and then we should be ready to merge.

I'll also create a bug as a reminder to drop the STARTED_AT column from the normal list output before 1.0. I rather doubt people care about that most of the time, and now that there is a better way to deal with the data we should probably clean that up the next time we do a compatibility break.

- Rename connected_at -> last_connected_at, disconnected_at -> last_disconnected_at
- Combine timestamps into SessionLifecycleTimestamps behind single Mutex
- Update help text to "Output as JSON, includes extra fields"
@noperator
Copy link
Contributor Author

Made requested changes:

  • Rename connected_at -> last_connected_at, disconnected_at -> last_disconnected_at
  • Combine timestamps into SessionLifecycleTimestamps behind single Mutex
  • Update help text to "Output as JSON, includes extra fields"
Repeated tests with new changes
# start daemon
./target/debug/shpool -s /tmp/shpool-dev.sock daemon

# open this session, then detach
./target/debug/shpool -s /tmp/shpool-dev.sock attach test1

# default list output unchanged
./target/debug/shpool -s /tmp/shpool-dev.sock list
NAME	STARTED_AT	STATUS
test1	2026-01-23T21:59:51.955+00:00	disconnected

# JSON contains extra session data
./target/debug/shpool -s /tmp/shpool-dev.sock list --json
{
  "sessions": [
    {
      "name": "test1",
      "started_at_unix_ms": 1769205591955,
      "last_connected_at_unix_ms": 1769205591955,
      "last_disconnected_at_unix_ms": 1769205597359,
      "status": "Disconnected"
    }
  ]
}

# open another session so we can compare and sort by time
./target/debug/shpool -s /tmp/shpool-dev.sock attach test2

# use jq for custom/complex session sorting (in this case, by recent activity)
./target/debug/shpool -s /tmp/shpool-dev.sock list --json |
    jq '.sessions | sort_by([
        ({ "Disconnected": 0, "Attached": 1 }[.status]),
        (if .status == "Attached" then .last_connected_at_unix_ms else .last_disconnected_at_unix_ms end)
    ])'
[
  {
    "name": "test1",
    "started_at_unix_ms": 1769205591955,
    "last_connected_at_unix_ms": 1769205591955,
    "last_disconnected_at_unix_ms": 1769205597359,
    "status": "Disconnected"
  },
  {
    "name": "test2",
    "started_at_unix_ms": 1769205633087,
    "last_connected_at_unix_ms": 1769205633087,
    "last_disconnected_at_unix_ms": null,
    "status": "Attached"
  }
]

@ethanpailes
Copy link
Contributor

Sorry to ask for more changes on a second round, but I just realized the change itself has no new tests. Do you mind adding a new test to sanity check in shpool/tests/list.rs. It doesn't have to be fancy, just lauching a sub-process and grepping the output for one of the new fields and maybe using serde_json to verify that the output is valid json is enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show more session details in list subcommand

2 participants