Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions docs/case-studies/issue-67/ANALYSIS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Case Study: Issue #67 - Display Session Name and Container Name When Different from Session UUID

## Overview

**Issue:** When using isolation backends (screen, docker, tmux), the output shows a session UUID but not the actual container/screen/tmux session name that users need to reconnect to the session, especially in detached mode.

**Priority:** Bug / Enhancement / Documentation

## Problem Description

When running commands with isolation (screen, docker, tmux), the tool generates two different identifiers:
1. **Session UUID** - A unique identifier for tracking executions (e.g., `f1efebcd-5426-437b-92db-b94acaaf421c`)
2. **Session/Container Name** - The actual name used by the isolation backend (e.g., `docker-1767841051864-c0qs07`)

Currently, only the session UUID is displayed in output blocks, but users need the actual session/container name to:
- Reconnect to detached sessions (`screen -r <name>`, `tmux attach -t <name>`)
- View container logs (`docker logs <name>`)
- Attach to containers (`docker attach <name>`)
- Kill sessions (`screen -S <name> -X quit`, `docker rm -f <name>`)

## Root Cause Analysis

### Timeline of Code Flow

1. **Session UUID Generation** (`cli.js:234`):
```javascript
const sessionId = wrapperOptions.sessionId || generateUUID();
```
This generates the tracking UUID, e.g., `f1efebcd-5426-437b-92db-b94acaaf421c`

2. **Session Name Generation** (`cli.js:410-412`):
```javascript
const sessionName = options.session ||
`${environment || 'start'}-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
```
This generates the backend session name, e.g., `docker-1767841051864-c0qs07`

3. **Extra Lines for Isolation** (`cli.js:470-485`):
Currently only adds:
- `[Isolation] Environment: docker, Mode: attached`
- `[Isolation] Session: <name>` (only if explicitly provided via --session)
- `[Isolation] Image: ubuntu:latest`
- `[Isolation] Endpoint: user@host` (for SSH)
- `[Isolation] User: <user>` (for user isolation)

4. **Output Block Generation** (`output-blocks.js:181-205`):
- Parses extraLines for isolation metadata
- Generates spine lines with container/screen/tmux names
- But the actual session name is **not passed** when auto-generated

### The Gap

The issue is in `cli.js` - when no explicit `--session` is provided, the auto-generated session name is not added to `extraLines`, so `output-blocks.js` cannot display it.

Currently:
```javascript
if (options.session) {
extraLines.push(`[Isolation] Session: ${options.session}`);
}
```

This only adds the session line when user explicitly provides `--session`, but NOT when it's auto-generated.

## Proposed Solution

### Option 1: Always Add Session Name to extraLines (Recommended)

In `cli.js`, after generating `sessionName`, always add it to extraLines regardless of whether it was explicitly provided:

```javascript
// Always add the actual session/container name used
extraLines.push(`[Isolation] Session: ${sessionName}`);
```

This ensures that `output-blocks.js` can always display the correct session/container/screen name.

### Option 2: Use Session UUID for Session Names

Alternative approach: Try to use the session UUID as the session name when possible. However, this has limitations:
- UUIDs are long (36 characters) which may exceed name limits
- Some backends have character restrictions (docker container names must match `[a-zA-Z0-9][a-zA-Z0-9_.-]*`)
- UUIDs contain dashes which may cause issues in some contexts

### Recommendation

**Implement Option 1** - Always pass the actual session name to extraLines. This is:
- Minimal code change
- Backward compatible
- Provides users with the information they need
- Allows them to reconnect to detached sessions

## Implementation Steps

### JavaScript Implementation (completed)

1. Modified `js/src/bin/cli.js` to always add `[Isolation] Session: ${sessionName}` to extraLines
2. Added tests in `js/test/cli.test.js` to verify the session name is displayed for screen, tmux, and docker
3. Created changeset `js/.changeset/issue-67-display-session-name.md`

### Rust Implementation (completed)

1. Modified `rust/src/bin/main.rs` to always add the session name to extraLines when using isolation
2. Added tests in `rust/src/lib/output_blocks.rs` to verify the session name is displayed for screen, tmux, and docker
3. Created changelog fragment `rust/changelog.d/67.md`

## Impact

- **Users** will see the actual session/container name in output, enabling them to:
- Reconnect to detached screen sessions
- Attach to tmux sessions
- View Docker container logs
- Remove containers
- **Backward Compatibility**: No breaking changes - just additional information displayed

## References

- Issue: https://github.com/link-foundation/start/issues/67
- Related Files:
- JavaScript:
- `js/src/bin/cli.js` - Main CLI logic
- `js/src/lib/output-blocks.js` - Output formatting
- `js/src/lib/isolation.js` - Isolation backend runners
- `js/src/lib/args-parser.js` - Argument parsing
- `js/test/cli.test.js` - Tests for issue #67 fix
- Rust:
- `rust/src/bin/main.rs` - Main CLI logic
- `rust/src/lib/output_blocks.rs` - Output formatting (with tests)
- `rust/src/lib/isolation.rs` - Isolation backend runners
- `rust/src/lib/args_parser.rs` - Argument parsing

## User-Provided Log Examples

From the issue description:
```
$ --isolated screen -- echo 'hi'
│ session a39a17a3-1064-480d-b508-80b8bdd3a93f
│ start 2026-01-08 02:57:28.115
│ isolation screen
│ mode attached
$ echo hi
```

The screen session name (e.g., `screen-1767841048115-nch2wk`) is NOT shown, only the UUID.

With the fix, users would see:
```
│ session a39a17a3-1064-480d-b508-80b8bdd3a93f
│ start 2026-01-08 02:57:28.115
│ isolation screen
│ mode attached
│ screen screen-1767841048115-nch2wk
$ echo hi
```

This allows users to reconnect with `screen -r screen-1767841048115-nch2wk`.
1 change: 1 addition & 0 deletions docs/case-studies/issue-67/issue-comments.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
1 change: 1 addition & 0 deletions docs/case-studies/issue-67/issue-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"url":"https://api.github.com/repos/link-foundation/start/issues/67","repository_url":"https://api.github.com/repos/link-foundation/start","labels_url":"https://api.github.com/repos/link-foundation/start/issues/67/labels{/name}","comments_url":"https://api.github.com/repos/link-foundation/start/issues/67/comments","events_url":"https://api.github.com/repos/link-foundation/start/issues/67/events","html_url":"https://github.com/link-foundation/start/issues/67","id":3791066046,"node_id":"I_kwDOP85RQM7h9xO-","number":67,"title":"Make sure to also output session name and container name if they are not the same as main session uuid","user":{"login":"konard","id":1431904,"node_id":"MDQ6VXNlcjE0MzE5MDQ=","avatar_url":"https://avatars.githubusercontent.com/u/1431904?v=4","gravatar_id":"","url":"https://api.github.com/users/konard","html_url":"https://github.com/konard","followers_url":"https://api.github.com/users/konard/followers","following_url":"https://api.github.com/users/konard/following{/other_user}","gists_url":"https://api.github.com/users/konard/gists{/gist_id}","starred_url":"https://api.github.com/users/konard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/konard/subscriptions","organizations_url":"https://api.github.com/users/konard/orgs","repos_url":"https://api.github.com/users/konard/repos","events_url":"https://api.github.com/users/konard/events{/privacy}","received_events_url":"https://api.github.com/users/konard/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[{"id":9408517827,"node_id":"LA_kwDOP85RQM8AAAACMMqWww","url":"https://api.github.com/repos/link-foundation/start/labels/bug","name":"bug","color":"d73a4a","default":true,"description":"Something isn't working"},{"id":9408517830,"node_id":"LA_kwDOP85RQM8AAAACMMqWxg","url":"https://api.github.com/repos/link-foundation/start/labels/documentation","name":"documentation","color":"0075ca","default":true,"description":"Improvements or additions to documentation"},{"id":9408517834,"node_id":"LA_kwDOP85RQM8AAAACMMqWyg","url":"https://api.github.com/repos/link-foundation/start/labels/enhancement","name":"enhancement","color":"a2eeef","default":true,"description":"New feature or request"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2026-01-08T03:17:41Z","updated_at":"2026-01-08T03:17:41Z","closed_at":null,"author_association":"MEMBER","type":{"id":22969355,"node_id":"IT_kwDOCoAzvc4BXnwL","name":"Task","description":"A specific piece of work","color":"yellow","created_at":"2024-07-20T19:06:39Z","updated_at":"2024-07-20T19:06:39Z","is_enabled":true},"active_lock_reason":null,"sub_issues_summary":{"total":0,"completed":0,"percent_completed":0},"issue_dependencies_summary":{"blocked_by":0,"total_blocked_by":0,"blocking":0,"total_blocking":0},"body":"```\nkonard@MacBook-Pro-Konstantin ~ % bun install -g start-command \nbun add v1.2.20 (6ad208bc)\n\ninstalled start-command@0.19.0 with binaries:\n - $\n\n[302.00ms] done\nkonard@MacBook-Pro-Konstantin ~ % $ echo 'hi' \n│ session 3098d3ae-07b2-418c-aede-c001b82ec31c\n│ start 2026-01-08 02:57:23.530\n│\n$ echo hi\n\nhi\n\n✓\n│ finish 2026-01-08 02:57:23.798\n│ duration 0.268s\n│ exit 0\n│\n│ log /var/folders/cl/831lqjgd58v5mb_m74cfdfcw0000gn/T/start-command-1767841043530-kyf19v.log\n│ session 3098d3ae-07b2-418c-aede-c001b82ec31c\nkonard@MacBook-Pro-Konstantin ~ % $ --isolated screen -- echo 'hi'\n│ session a39a17a3-1064-480d-b508-80b8bdd3a93f\n│ start 2026-01-08 02:57:28.115\n│\n│ isolation screen\n│ mode attached\n│\n$ echo hi\n\nhi\n\n✓\n│ finish 2026-01-08 02:57:28.423\n│ duration 0.415s\n│ exit 0\n│\n│ isolation screen\n│ mode attached\n│\n│ log /var/folders/cl/831lqjgd58v5mb_m74cfdfcw0000gn/T/start-command-screen-1767841048115-nch2wk.log\n│ session a39a17a3-1064-480d-b508-80b8bdd3a93f\nkonard@MacBook-Pro-Konstantin ~ % $ --isolated docker -- echo 'hi'\n│ session f1efebcd-5426-437b-92db-b94acaaf421c\n│ start 2026-01-08 02:57:31.864\n│\n│ isolation docker\n│ mode attached\n│ image alpine:latest\n│\n$ echo hi\n\nhi\n\n✓\n│ finish 2026-01-08 02:57:32.241\n│ duration 0.489s\n│ exit 0\n│\n│ isolation docker\n│ mode attached\n│ image alpine:latest\n│\n│ log /var/folders/cl/831lqjgd58v5mb_m74cfdfcw0000gn/T/start-command-docker-1767841051864-c0qs07.log\n│ session f1efebcd-5426-437b-92db-b94acaaf421c\nkonard@MacBook-Pro-Konstantin ~ %\n```\n\nIf for screen, docker, tmux and so on the screen name is not the same as session UUID, we should output it separately, but if we can we should try to use the same UUID for screen name and docker name and so on. But if it is not possible we should make sure at start and end blocks we do display that info, so if for example we use detached mode, or attached mode without closing of screen/docker container we should be able to see all the data to reconnect to them.\n\nPlease download all logs and data related about the issue to this repository, make sure we compile that data to `./docs/case-studies/issue-{id}` folder, and use it to do deep case study analysis (also make sure to search online for additional facts and data), in which we will reconstruct timeline/sequence of events, find root causes of the problem, and propose possible solutions.","closed_by":null,"reactions":{"url":"https://api.github.com/repos/link-foundation/start/issues/67/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/link-foundation/start/issues/67/timeline","performed_via_github_app":null,"state_reason":null}
14 changes: 14 additions & 0 deletions js/.changeset/issue-67-display-session-name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
'start-command': patch
---

fix: Always display session/container name in isolation output

When using isolation backends (screen, docker, tmux), the output now shows the actual session/container name that users need to reconnect to sessions, especially in detached mode. Previously, only the session UUID was shown, but users need the actual backend name to:

- Reconnect to detached screen sessions: `screen -r <name>`
- Attach to tmux sessions: `tmux attach -t <name>`
- View Docker container logs: `docker logs <name>`
- Remove containers: `docker rm -f <name>`

Fixes #67
7 changes: 4 additions & 3 deletions js/src/bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,10 @@ async function runWithIsolation(
// Add isolation info to extra lines
if (environment) {
extraLines.push(`[Isolation] Environment: ${environment}, Mode: ${mode}`);
}
if (options.session) {
extraLines.push(`[Isolation] Session: ${options.session}`);
// Always add the session name so users can reconnect to detached sessions
// This is important for screen, tmux, docker where the session/container name
// is different from the session UUID used for tracking (see issue #67)
extraLines.push(`[Isolation] Session: ${sessionName}`);
}
if (effectiveImage) {
extraLines.push(`[Isolation] Image: ${effectiveImage}`);
Expand Down
94 changes: 94 additions & 0 deletions js/test/cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,97 @@ describe('CLI basic behavior', () => {
assert.ok(result.stdout.includes('Usage:'), 'Should display usage');
});
});

describe('CLI isolation output (issue #67)', () => {
const { isCommandAvailable } = require('../src/lib/isolation');

it('should display screen session name when using screen isolation', async () => {
if (!isCommandAvailable('screen')) {
console.log(' Skipping: screen not installed');
return;
}

const result = runCLI(['-i', 'screen', '--', 'echo', 'hello']);

// The output should contain the screen session name (in format screen-timestamp-random)
// Check that the session UUID is displayed
assert.ok(
result.stdout.includes('│ session'),
'Should display session UUID'
);
// Check that screen isolation info is displayed
assert.ok(
result.stdout.includes('│ isolation screen'),
'Should display screen isolation'
);
// Check that the actual screen session name is displayed (issue #67 fix)
assert.ok(
result.stdout.includes('│ screen screen-'),
'Should display actual screen session name for reconnection (issue #67)'
);
});

it('should display tmux session name when using tmux isolation', async () => {
if (!isCommandAvailable('tmux')) {
console.log(' Skipping: tmux not installed');
return;
}

const result = runCLI(['-i', 'tmux', '--', 'echo', 'hello']);

// The output should contain the tmux session name
assert.ok(
result.stdout.includes('│ session'),
'Should display session UUID'
);
assert.ok(
result.stdout.includes('│ isolation tmux'),
'Should display tmux isolation'
);
// Check that the actual tmux session name is displayed (issue #67 fix)
assert.ok(
result.stdout.includes('│ tmux tmux-'),
'Should display actual tmux session name for reconnection (issue #67)'
);
});

it('should display docker container name when using docker isolation', async () => {
const { canRunLinuxDockerImages } = require('../src/lib/isolation');

if (!canRunLinuxDockerImages()) {
console.log(
' Skipping: docker not available or cannot run Linux images'
);
return;
}

const result = runCLI([
'-i',
'docker',
'--image',
'alpine:latest',
'--',
'echo',
'hello',
]);

// The output should contain the docker container name
assert.ok(
result.stdout.includes('│ session'),
'Should display session UUID'
);
assert.ok(
result.stdout.includes('│ isolation docker'),
'Should display docker isolation'
);
assert.ok(
result.stdout.includes('│ image alpine:latest'),
'Should display docker image'
);
// Check that the actual container name is displayed (issue #67 fix)
assert.ok(
result.stdout.includes('│ container docker-'),
'Should display actual container name for reconnection (issue #67)'
);
});
});
13 changes: 13 additions & 0 deletions rust/changelog.d/67.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fix: Always display session/container name in isolation output

When using isolation backends (screen, docker, tmux), the output now always displays
the actual session/container name that users need to reconnect to sessions. Previously,
the session name was only shown if explicitly provided via `--session` flag.

This allows users to:
- Reconnect to detached screen sessions: `screen -r <name>`
- Attach to tmux sessions: `tmux attach -t <name>`
- View Docker container logs: `docker logs <name>`
- Remove containers: `docker rm -f <name>`

Fixes #67
7 changes: 4 additions & 3 deletions rust/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,10 @@ fn run_with_isolation(
// Add isolation info to extra lines
if let Some(env) = environment {
extra_lines.push(format!("[Isolation] Environment: {}, Mode: {}", env, mode));
}
if let Some(ref session) = wrapper_options.session {
extra_lines.push(format!("[Isolation] Session: {}", session));
// Always add the session name so users can reconnect to detached sessions
// This is important for screen, tmux, docker where the session/container name
// is different from the session UUID used for tracking (see issue #67)
extra_lines.push(format!("[Isolation] Session: {}", session_name));
}
if let Some(ref image) = effective_image {
extra_lines.push(format!("[Isolation] Image: {}", image));
Expand Down
Loading