lvwerra HF Staff commited on
Commit
2d4a54b
·
verified ·
1 Parent(s): bcfec39

New sessions land on top unless created inside a group; prompt tracks current dir relative to workspaces root

Browse files
Files changed (3) hide show
  1. server/src/runner.js +2 -1
  2. session.bashrc +19 -4
  3. web/src/App.tsx +10 -4
server/src/runner.js CHANGED
@@ -247,11 +247,12 @@ export function attach(session, cols, rows) {
247
  '-e', `AM_SESSION=${folder}`,
248
  '-e', `AM_NAME=${session.name}`,
249
  '-e', `AM_USER=${AM_USER}`,
 
250
  'sh', '-lc', full,
251
  );
252
  term = pty.spawn('tmux', args, { name: 'xterm-256color', cols, rows, cwd: workdir, env: TERM_ENV });
253
  } else {
254
- const env = { ...TERM_ENV, AM_SESSION: folder, AM_NAME: session.name, AM_USER };
255
  term = pty.spawn('bash', ['-lc', full], { name: 'xterm-256color', cols, rows, cwd: workdir, env });
256
  }
257
 
 
247
  '-e', `AM_SESSION=${folder}`,
248
  '-e', `AM_NAME=${session.name}`,
249
  '-e', `AM_USER=${AM_USER}`,
250
+ '-e', `AM_ROOT=${WORKSPACES_DIR}`, // prompt shows $PWD relative to this
251
  'sh', '-lc', full,
252
  );
253
  term = pty.spawn('tmux', args, { name: 'xterm-256color', cols, rows, cwd: workdir, env: TERM_ENV });
254
  } else {
255
+ const env = { ...TERM_ENV, AM_SESSION: folder, AM_NAME: session.name, AM_USER, AM_ROOT: WORKSPACES_DIR };
256
  term = pty.spawn('bash', ['-lc', full], { name: 'xterm-256color', cols, rows, cwd: workdir, env });
257
  }
258
 
session.bashrc CHANGED
@@ -3,8 +3,23 @@
3
  [ -f /etc/bash.bashrc ] && . /etc/bash.bashrc
4
 
5
  AM_USER="${AM_USER:-${SPACE_AUTHOR_NAME:-user}}"
6
- AM_SESSION="${AM_SESSION:-session}"
7
 
8
- # Prompt: "user/session $" colors come from the (theme-tuned) ANSI palette,
9
- # bold cyan user + bold green session, readable on both light and dark backgrounds.
10
- PS1='\[\e[1;36m\]'"${AM_USER}"'\[\e[0;2m\]/\[\e[0m\]\[\e[1;32m\]'"${AM_SESSION}"'\[\e[0;2m\] \$\[\e[0m\] '
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  [ -f /etc/bash.bashrc ] && . /etc/bash.bashrc
4
 
5
  AM_USER="${AM_USER:-${SPACE_AUTHOR_NAME:-user}}"
 
6
 
7
+ # The prompt's location segment: the CURRENT directory, shown relative to the
8
+ # workspaces root (AM_ROOT, exported by the manager) so it starts as the
9
+ # session's folder and follows you as you cd around. Falls back to ~-style
10
+ # for anything outside the workspace tree.
11
+ _am_pwd() {
12
+ local root="${AM_ROOT:-/data/workspaces}"
13
+ case "$PWD" in
14
+ "$root") printf 'workspaces' ;;
15
+ "$root"/*) printf '%s' "${PWD#"$root"/}" ;;
16
+ "$HOME") printf '~' ;;
17
+ "$HOME"/*) printf '~/%s' "${PWD#"$HOME"/}" ;;
18
+ *) printf '%s' "$PWD" ;;
19
+ esac
20
+ }
21
+
22
+ # Prompt: "user/current-dir $" — colors come from the (theme-tuned) ANSI
23
+ # palette, bold cyan user + bold green location, readable on both light and
24
+ # dark backgrounds. $(_am_pwd) is single-quoted so it re-evaluates per prompt.
25
+ PS1='\[\e[1;36m\]'"${AM_USER}"'\[\e[0;2m\]/\[\e[0m\]\[\e[1;32m\]$(_am_pwd)\[\e[0;2m\] \$\[\e[0m\] '
web/src/App.tsx CHANGED
@@ -93,12 +93,18 @@ export default function App() {
93
  }, [visibleIds, focusedId]);
94
 
95
  // actions
96
- const newSession = async (name: string, cli: string, path: string) => {
97
- const s = await api.createSession(name, cli, activeGroup?.id, path);
98
  rememberPath(s.path);
99
  await refresh();
100
- setActiveRef(`s:${s.id}`);
 
101
  };
 
 
 
 
 
102
  const newGroup = async (name: string, cart?: { cli: string; count: number }[], path = '') => {
103
  const g = await api.createGroup(name);
104
  for (const { cli, count } of cart || []) {
@@ -221,7 +227,7 @@ export default function App() {
221
  <div className="empty-card">
222
  <h2>{activeGroup.name}</h2>
223
  <p>Create an agent here, or drag one in from the sidebar.</p>
224
- <NewSession clis={clis} sessions={tree.sessions} defaultPath={lastPath} onCreate={newSession} />
225
  <div className="dropline">⤓ drop an agent to add it to this group</div>
226
  </div>
227
  </div>
 
93
  }, [visibleIds, focusedId]);
94
 
95
  // actions
96
+ const createSession = async (name: string, cli: string, path: string, groupId?: string) => {
97
+ const s = await api.createSession(name, cli, groupId, path);
98
  rememberPath(s.path);
99
  await refresh();
100
+ if (groupId) { setActiveRef(`g:${groupId}`); setFocusedId(s.id); }
101
+ else setActiveRef(`s:${s.id}`);
102
  };
103
+ // Sidebar + quick-add creations always land loose at the top of the list —
104
+ // never in a group just because one happens to be selected.
105
+ const newSession = (name: string, cli: string, path: string) => createSession(name, cli, path);
106
+ // The empty-group card explicitly creates "an agent here".
107
+ const newSessionHere = (name: string, cli: string, path: string) => createSession(name, cli, path, activeGroup?.id);
108
  const newGroup = async (name: string, cart?: { cli: string; count: number }[], path = '') => {
109
  const g = await api.createGroup(name);
110
  for (const { cli, count } of cart || []) {
 
227
  <div className="empty-card">
228
  <h2>{activeGroup.name}</h2>
229
  <p>Create an agent here, or drag one in from the sidebar.</p>
230
+ <NewSession clis={clis} sessions={tree.sessions} defaultPath={lastPath} onCreate={newSessionHere} />
231
  <div className="dropline">⤓ drop an agent to add it to this group</div>
232
  </div>
233
  </div>