Skip to content
nikcli
Docs
Documentation

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"
InputWhere handledResult
--sessioncli/cmd/tui/thread.tsValidates the id through SDK session.get before rendering.
--continueTUI args provider and local contextResolves and opens the last usable session in the current project.
--prompt or piped stdinTUI thread prompt resolverSeeds the composer or immediate run prompt.
POST /sessionserver/httpapi/session.tsCreates 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 areaMeaningUsed by
ID and parentid, optional parentIDForks, child navigation, background worker grouping.
Project contextprojectID, directory, optional workspaceIDServer workspace context and storage paths.
Title and timetitle, created/updated/archived timestampsSession list sorting, archive state, display title.
Execution metadataAgent, model, mode, GitHub, workspace/container fields where presentTUI/mobile badges and future prompt defaults.
SummaryDiff totals and generated summariesLists, 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.

RoutePurpose
GET /session/:sessionID/messageList messages for a session, optionally with a limit.
GET /session/:sessionID/message/:messageIDRead one message with its parts.
DELETE /session/:sessionID/message/:messageIDRemove a message after validating the session exists.
DELETE /session/:sessionID/message/:messageID/part/:partIDRemove one part from a message.
PATCH /session/:sessionID/message/:messageID/part/:partIDReplace 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.

StatusMeaningTypical UI
busyA prompt, tool, monitor, or delegated worker is active.Stop/Abort controls and live transcript follow.
retryA retryable provider/tool path is waiting or reattempting.Retry badge with attempt or message.
idleNo 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"

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.

FlowServicePersistence
Ask permissionPermissionNext.askPending in memory, published through bus events.
Always allowPermissionNext.replyAllowed rules are written under storage/permission/:projectID.
Ask questionQuestion.ServicePending until the user replies or rejects.
Hydrate after reconnectPermission and question route servicesUsed 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.

CapabilityRoute or sourceBehavior
ForkPOST /session/:sessionID/forkCreates a new session optionally rooted at a message id.
ChildrenGET /session/:sessionID/childrenLists sessions linked to the same parent.
Background workerdelegation/manager and task toolRuns child work without taking over the root route.
AbortPOST /session/:sessionID/abortCancels 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
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.

FeatureSourceNotes
Auto sharesession/index.tsRuns for root sessions when config or env enables it.
Public datashare/share-next.tsServed without server auth by explicit public share routes.
Exportcli/cmd/export.ts and TUI export dialogsFormats 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

SymptomLikely causeFix
Session.BusyErrorA prompt is already running.Use abort, wait for idle, or fork a new child session.
Session not found in TUIInvalid 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 promptMalformed UI-shaped messages reached the provider path.LLM.normalizeStreamMessages repairs known UI-message shapes before streaming.
Always approval does not applyThe persisted pattern does not match the later permission pattern.Check stored rules under the project permission storage key.
Abort leaves work runningExternal process is owned by a monitor or delegated worker not tied to the session id.Inspect monitors and background jobs for ownership.

Source anchors

NeedFile
Session service and schemapackages/nikcli/src/session/index.ts
Prompt executionpackages/nikcli/src/session/prompt.ts, packages/nikcli/src/session/runner.ts
LLM stream hot pathpackages/nikcli/src/session/llm.ts
Message storagepackages/nikcli/src/session/message-v2.ts
Statuspackages/nikcli/src/session/status.ts
Revert and diffpackages/nikcli/src/session/revert.ts, packages/nikcli/src/session/summary.ts
Typed APIpackages/nikcli/src/server/httpapi/session.ts
Classic routespackages/nikcli/src/server/httpapi/session.ts
TUI session viewpackages/tui/src/routes/session/index.tsx
Mobile session routespackages/nikcli/src/server/httpapi/mobile.ts