diff --git a/src/css/terminal.css b/src/css/terminal.css
index fd5c3d8..3fa8169 100644
--- a/src/css/terminal.css
+++ b/src/css/terminal.css
@@ -160,4 +160,19 @@
#scrollback .output {
white-space: pre-wrap;
+}
+
+#statusline {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ padding: 2px 8px;
+
+ background: var(--c64-light-gray);
+ color: var(--c64-dark-blue);
+
+ font-size: 14px;
+ display: flex;
+ justify-content: space-between;
}
\ No newline at end of file
diff --git a/src/html/terminal.tsx b/src/html/terminal.tsx
index 3cc5b09..6fce011 100644
--- a/src/html/terminal.tsx
+++ b/src/html/terminal.tsx
@@ -34,5 +34,7 @@ export const Terminal: FC = async () => (
**** NOSE PLUTO V{new Date().getMonth() + 1}.{new Date().getDate()} ****
VRAM 000KB
+
+
>
)
\ No newline at end of file
diff --git a/src/js/commands.ts b/src/js/commands.ts
index 8e9d043..117ba49 100644
--- a/src/js/commands.ts
+++ b/src/js/commands.ts
@@ -38,5 +38,4 @@ export function cacheCommands(cmds: string[]) {
commands.push(...cmds)
commands.push(...Object.keys(browserCommands))
commands.sort()
- console.log("CMDS", commands)
}
\ No newline at end of file
diff --git a/src/js/dispatch.ts b/src/js/dispatch.ts
index 477251f..8435c78 100644
--- a/src/js/dispatch.ts
+++ b/src/js/dispatch.ts
@@ -4,6 +4,7 @@ import { handleOutput } from "./scrollback"
import { handleStreamStart, handleStreamAppend, handleStreamReplace, handleStreamEnd } from "./stream"
import { handleGameStart } from "./game"
import { browserCommands } from "./commands"
+import { handleSessionUpdate } from "./session"
// message received from server
export async function dispatchMessage(msg: Message) {
@@ -26,6 +27,8 @@ export async function dispatchMessage(msg: Message) {
await handleGameStart(msg); break
case "ui:mode":
browserCommands.mode?.(msg.data as string); break
+ case "session:update":
+ handleSessionUpdate(msg); break
default:
console.error("unknown message type", msg)
}
diff --git a/src/js/session.ts b/src/js/session.ts
index 5f980e8..160f5e1 100644
--- a/src/js/session.ts
+++ b/src/js/session.ts
@@ -2,6 +2,22 @@
// Each browser tab is a shell session. This means you can run multiple sessions
// in the same browser.
+import type { Message } from "@/shared/types"
import { randomId } from "../shared/utils"
+import { $ } from "./dom"
-export const sessionId = randomId()
\ No newline at end of file
+export const sessionId = randomId()
+export const projectName = $("project-name") as HTMLSpanElement
+export const projectCwd = $("project-cwd") as HTMLSpanElement
+
+export function handleSessionUpdate(msg: Message) {
+ const data = msg.data as Record
+
+ if (data.project) {
+ projectName.textContent = data.project
+ }
+
+ if (data.cwd) {
+ projectCwd.textContent = data.cwd
+ }
+}
\ No newline at end of file
diff --git a/src/session.ts b/src/session.ts
index db1e1e3..65be714 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -2,6 +2,7 @@
// Session storage. 1 browser tab = 1 session
import { AsyncLocalStorage } from "async_hooks"
+import { send } from "./websocket"
export type Session = {
taskId?: string
@@ -35,6 +36,12 @@ export function sessionSet(key: keyof Session, value: any) {
const store = ALS.getStore()
if (!store) throw "sessionSet() called outside of ALS.run"
store[key] = value
+
+ if (!store.ws) return
+ send(store.ws, {
+ type: "session:update",
+ data: { [key]: value }
+ })
}
export function sessionStore(sessionId: string, taskId?: string, ws?: any): Session {
diff --git a/src/shared/types.ts b/src/shared/types.ts
index 4129e37..f0d0819 100644
--- a/src/shared/types.ts
+++ b/src/shared/types.ts
@@ -3,7 +3,7 @@ export type Message = {
id?: string
type: MessageType
data?: CommandResult | CommandOutput
-}
+} | SessionUpdateMessage
export type MessageType = "error" | "input" | "output" | "commands" | "save-file"
| "game:start"
@@ -20,3 +20,8 @@ export type CommandResult = {
status: "ok" | "error"
output: CommandOutput
}
+
+type SessionUpdateMessage = {
+ type: "session:update",
+ data: Record
+}
\ No newline at end of file