# Sessions

How nikcli creates, stores, streams, forks, reverts, and resumes agent sessions across CLI, TUI, mobile, and API clients.

## Overview

A session is the durable unit of work for an agent run. It owns the user and assistant message timeline, tool parts, status, permissions, questions, diffs, todo state, background children, workspace metadata, and share/export data.

Durable

### Storage

Session info is stored through `Storage.Service` under the project-aware JSON store. Messages and parts use `MessageV2`.

Runtime

### Execution

`SessionPrompt`, `SessionRunner`, and `LLM.stream` build context, call providers, run tools, and write streaming parts.

Live

### State

`SessionStatus`, monitor records, delegation jobs, and bus events drive TUI/mobile busy, retry, and idle states.

API

### Control

Session routes expose create, list, prompt, abort, fork, children, diff, revert, share, export, and message mutation flows.

## Create or continue

Sessions can be created from the root TUI command, `nikcli run`, mobile, the web app, or the API. The TUI entry command is `nikcli [project]`; it starts a worker, validates any provided session id, then opens either a direct RPC UI or a network-backed UI.

Terminal

bash 

```
nikcli                         # start TUI in the current directory
nikcli ../repo --model openai/gpt-5
nikcli --continue              # continue last session
nikcli --session ses_example   # open a specific session
nikcli run "fix the failing test"
```

$ shell · paste into your terminal

| Input | Where handled | Result |
| --- | --- | --- |
| `--session` | `cli/cmd/tui/thread.ts` | Validates the id through SDK `session.get` before rendering. |
| `--continue` | TUI args provider and local context | Resolves and opens the last usable session in the current project. |
| `--prompt` or piped stdin | TUI thread prompt resolver | Seeds the composer or immediate run prompt. |
| `POST /session` | `server/httpapi/session.ts` | Creates a session with optional parent, title, permission, skills, GitHub data, and workspace id. |

## Session record

The session info object is defined in `packages/nikcli/src/session/index.ts`. It carries identifiers, title, project/workspace metadata, directory, parent links, GitHub or container metadata, timestamps, and summary fields.

| Field area | Meaning | Used by |
| --- | --- | --- |
| ID and parent | `id`, optional `parentID` | Forks, child navigation, background worker grouping. |
| Project context | `projectID`, `directory`, optional `workspaceID` | Server workspace context and storage paths. |
| Title and time | `title`, created/updated/archived timestamps | Session list sorting, archive state, display title. |
| Execution metadata | Agent, model, mode, GitHub, workspace/container fields where present | TUI/mobile badges and future prompt defaults. |
| Summary | Diff totals and generated summaries | Lists, analytics, share/export, mobile cards. |

## Messages and parts

Messages are split from parts so streaming tool calls, text, reasoning, files, diffs, and metadata can update independently. The API exposes both full message reads and part-level mutation routes.

| Route | Purpose |
| --- | --- |
| `GET /session/:sessionID/message` | List messages for a session, optionally with a limit. |
| `GET /session/:sessionID/message/:messageID` | Read one message with its parts. |
| `DELETE /session/:sessionID/message/:messageID` | Remove a message after validating the session exists. |
| `DELETE /session/:sessionID/message/:messageID/part/:partID` | Remove one part from a message. |
| `PATCH /session/:sessionID/message/:messageID/part/:partID` | Replace a part after body/path id consistency checks. |

Streaming writes

During prompt execution, assistant output and tool activity are written as incremental parts. TUI and mobile screens subscribe to updates and render partial state before the assistant message is complete.

## Prompt execution

Prompt execution combines agent config, system prompts, message history, tool registry, MCP and connector tools, permissions, and provider selection. The hot path reaches `packages/nikcli/src/session/llm.ts`, which normalizes message shapes before calling the provider runtime.

1.  User input is persisted as a user message and queued for the session.
2.  Session services build system context from agent, config, instructions, tools, skills, project, and locale.
3.  Tool availability is gated by model capability, config, MCP state, connector state, and experimental flags.
4.  Permissions call `PermissionNext.ask` before risky actions such as edits, shell, or LSP.
5.  `LLM.stream` chooses provider/model, repairs UI-shaped messages when needed, and streams output.
6.  Assistant text, reasoning, tool calls, results, and completion metadata update the message timeline.

## Status and events

`SessionStatus` exposes busy, idle, and retry state. The typed API returns a status map at `GET /session/status`. The TUI reads status through the sync context and mobile displays status chips in lists and cards.

| Status | Meaning | Typical UI |
| --- | --- | --- |
| `busy` | A prompt, tool, monitor, or delegated worker is active. | Stop/Abort controls and live transcript follow. |
| `retry` | A retryable provider/tool path is waiting or reattempting. | Retry badge with attempt or message. |
| `idle` | No active execution is tracked for the session. | Composer is ready for new input. |

Terminal

bash 

```
curl "http://127.0.0.1:4096/session/status?directory=$PWD"
```

$ shell · paste into your terminal

## Permissions and questions

Pending permissions and questions are session-scoped live prompts. The TUI aggregates pending requests across a root session and its children; mobile exposes approval and question bars in the composer. Permission replies can approve once, approve always, or reject with optional correction feedback.

| Flow | Service | Persistence |
| --- | --- | --- |
| Ask permission | `PermissionNext.ask` | Pending in memory, published through bus events. |
| Always allow | `PermissionNext.reply` | Allowed rules are written under `storage/permission/:projectID`. |
| Ask question | `Question.Service` | Pending until the user replies or rejects. |
| Hydrate after reconnect | Permission and question route services | Used by mobile/TUI sync to rebuild visible pending prompts. |

## Fork, children, background

A fork creates a new child session from an existing session and optional message boundary. Background task tools also create worker sessions and attach them to a parent. The session UI treats root sessions and children differently so parent-level permission/question prompts are not duplicated inside child routes.

| Capability | Route or source | Behavior |
| --- | --- | --- |
| Fork | `POST /session/:sessionID/fork` | Creates a new session optionally rooted at a message id. |
| Children | `GET /session/:sessionID/children` | Lists sessions linked to the same parent. |
| Background worker | `delegation/manager` and task tool | Runs child work without taking over the root route. |
| Abort | `POST /session/:sessionID/abort` | Cancels prompt, owned delegation jobs, and monitors together. |

## Diff, revert, unrevert

Diffs are produced from snapshots, VCS state, and message/tool output. The summary diff route can scope to a message id. Revert and unrevert operate through `SessionRevert` and return the updated session info.

Terminal

bash 

```
curl "http://127.0.0.1:4096/session/ses_example/diff?messageID=msg_example"

curl -X POST http://127.0.0.1:4096/session/ses_example/revert \
  -H "Content-Type: application/json" \
  -d '{"messageID":"msg_example"}'

curl -X POST http://127.0.0.1:4096/session/ses_example/unrevert
```

$ shell · paste into your terminal

Reverts are real file operations

Revert endpoints apply changes to the current workspace. Review the diff first and make sure the request is scoped to the intended directory or workspace.

## Sharing and export

Sharing is controlled by config and environment flags. New root sessions may auto-share when `NIKCLI_AUTO_SHARE` is set or config `share` is `auto`. Public share reads are intentionally mounted before auth at `/s/:shareID`, `/share/:shareID`, and `/api/share/:shareID`.

| Feature | Source | Notes |
| --- | --- | --- |
| Auto share | `session/index.ts` | Runs for root sessions when config or env enables it. |
| Public data | `share/share-next.ts` | Served without server auth by explicit public share routes. |
| Export | `cli/cmd/export.ts` and TUI export dialogs | Formats transcript and related session data for local output. |

## Mobile and workspace sessions

Mobile sessions use the same core session services but route through `/mobile/*` endpoints that bundle status, git stats, project metadata, and execution target information. Workspace-backed sessions carry `workspaceID`, letting the server route later session requests to a local or remote workspace target.

-   Mobile lists pair `Session.Info` with optional `SessionStatus.Info`.
-   Container-backed workspaces report runtime availability from `workspace/adaptors`.
-   Remote workspace requests are proxied before the route group handlers execute locally.
-   Route-session lookup lets `/session/:id` requests recover the original workspace context even when the caller omits workspace headers.

## Failure modes

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| `Session.BusyError` | A prompt is already running. | Use abort, wait for idle, or fork a new child session. |
| Session not found in TUI | Invalid id or session belongs to another directory/workspace. | Validate the id and pass the correct project path or workspace header. |
| Assistant stream fails with invalid prompt | Malformed UI-shaped messages reached the provider path. | `LLM.normalizeStreamMessages` repairs known UI-message shapes before streaming. |
| Always approval does not apply | The persisted pattern does not match the later permission pattern. | Check stored rules under the project permission storage key. |
| Abort leaves work running | External process is owned by a monitor or delegated worker not tied to the session id. | Inspect monitors and background jobs for ownership. |

## Source anchors

| Need | File |
| --- | --- |
| Session service and schema | `packages/nikcli/src/session/index.ts` |
| Prompt execution | `packages/nikcli/src/session/prompt.ts`, `packages/nikcli/src/session/runner.ts` |
| LLM stream hot path | `packages/nikcli/src/session/llm.ts` |
| Message storage | `packages/nikcli/src/session/message-v2.ts` |
| Status | `packages/nikcli/src/session/status.ts` |
| Revert and diff | `packages/nikcli/src/session/revert.ts`, `packages/nikcli/src/session/summary.ts` |
| Typed API | `packages/nikcli/src/server/httpapi/session.ts` |
| Classic routes | `packages/nikcli/src/server/httpapi/session.ts` |
| TUI session view | `packages/tui/src/routes/session/index.tsx` |
| Mobile session routes | `packages/nikcli/src/server/httpapi/mobile.ts` |

---

Source: https://nikcli-ai.dev/docs/sessions
