- milestone: truthful first-render / readiness / recovery UX
- status: shipped bounded UI slice without PTY embedding
- sandbox target:
my-assistant
- Added
/operator-terminalpage. - Dashboard CTA now routes to
/operator-terminal?sandboxId=.... - Page fetches
/api/openshell/terminal/introspectand shows:- explicit non-embedded status
- readiness state
- exact SSH attach commands
- retry + copy actions
- live introspection evidence + recovery notes
npm installsucceeded.eslint app/operator-terminal/page.tsx app/components/SandboxList.tsxpassed.- Full
tsc --noEmitstill fails on pre-existing unrelated type errors outside this slice. - Linux-side direct
ssh openshell-my-assistantvalidation blocked because alias is Mac-local here.
- Hardened
/api/openshell/terminal/readinessso a missing sandbox pod returns a truthful non-degraded readiness contract instead of collapsing into a generic 500. - Shell probing now skips absent pods and reports an explicit not-found note for
my-assistant-style operator checks. - Added a bounded dashboard command runner:
/api/openshell/terminalnow accepts POST for one-shot sandbox commands with input validation, timeout/length limits, and real stdout/stderr/exit-code reporting. - Updated
/operator-terminalto consume the readiness contract, surface probe evidence, show resolved attach commands, and expose the bounded one-shot command runner while explicitly keeping PTY embedding marked as not-yet-live.
npm run lint -- app/operator-terminal/page.tsx app/api/openshell/terminal/route.ts app/api/openshell/terminal/readiness/route.ts app/lib/openshellHost.tspassed.- Full live shell/SSH validation against the Mac/OpenShell runtime is still pending from a host that can actually reach the alias/path.
- Validate the readiness + bounded-command contract against the live Mac/OpenShell path for
my-assistant, then layer in streamed attach transport only after the route truth matches real runtime states.