Skip to content

Topics

A topic is a session. Every command an AI sends through String is directed at a specific topic — a file, a web tab, or an app instance. Each topic maintains its own state independently.


When AI works through String, it doesn’t operate in a single global context. It works with topics — isolated units that each hold their own history, current location, and state.

Think of it like a desktop. A human has multiple windows open — a text editor, a browser with several tabs, an email client. Each window is independent. Scrolling in one doesn’t affect another. The back button in one browser tab doesn’t navigate a different tab.

Topics give AI the same capability.

<𝒞=string:file:main>
/open ~/report.md#summary
</𝒞>
<𝒞=string:web:docs>
/open @getting-started
</𝒞>
<𝒞=string:app:gmail:work>
/act.compose --to "team@company.com"
</𝒞>

Three topics, three independent sessions. The AI can switch between them freely. Each one remembers where it is.


All topics follow a typed format:

type:name
  • type: file, web, app, or bash
  • name: [a-zA-Z0-9_-]+ — letters, numbers, hyphens, underscores only

No dots. No paths. No spaces. Session names are short identifiers, not file paths or URLs.

A bare name (no type prefix) defaults to file::

main → file:main
docs → file:docs

An empty or absent topic defaults to file:main.

In ChanFlow: string:<type:name>. In HTTP: body {"topic": "type:name"}.


A file session is a named workspace for local file operations.

string:file:main
string:file:docs
string:file:notes

The session name identifies the workspace — not a specific file. Within a session, the AI navigates files freely with /open:

<𝒞=string:file:main>
/open ~/report.md
</𝒞>
<𝒞=string:file:main>
/open ~/docs/guide.md#setup
</𝒞>

Both commands topic the same session. History, current location, and variables persist across navigations within that session.

Multiple file sessions let the AI organize work by context:

<𝒞=string:file:docs>
/open ~/docs/api-reference.md
</𝒞>
<𝒞=string:file:notes>
/open ~/notes/meeting.md
</𝒞>

Each session maintains its own navigation history independently.

Relative paths in /open resolve from the current document’s directory. [Next](./chapter2.md) inside ~/docs/chapter1.md points to ~/docs/chapter2.md — exactly as in any Markdown viewer.

A browser tab is a topic. Pages change within the tab, but the topic stays the same.

string:web:tab_1
string:web:docs
string:web:competitor_research

When AI opens a URL inside a web topic, it navigates within that tab. The URL changes, but the session — history, cookies, authentication — persists. /back returns to the previous page in that tab, not a different tab.

Named tabs (web:docs, web:research) let the AI organize its browsing by purpose, just like a human labels browser tab groups.

Opening a URL without a topic automatically creates a new tab:

<𝒞=string>
/open https://docs.example.com/api
</𝒞>

String assigns web:tab_1, web:tab_2, … incrementally. To name the tab explicitly, use --tab:

<𝒞=string>
/open --tab docs https://docs.example.com/api
</𝒞>

This creates web:docs instead of web:tab_N.

An app instance is a topic. Same as web — pages change within the app, but the session persists.

string:app:gmail
string:app:slack
string:app:gmail:work
string:app:gmail:personal

Apps can define multiple sessions using the app:name:config form. This is how the same app serves different contexts — a work email account and a personal one, each with its own state, each as a separate topic.

Web and app topics follow the same grammar. The distinction is semantic: web topics are general browsing sessions, app topics are specific application instances with defined capabilities.

A shell session is a topic. It works like a real terminal — working directory, environment variables, and process state persist across commands.

string:bash:dev
string:bash:deploy
string:bash:debug

Each named bash session is independent. cd in bash:dev doesn’t affect bash:deploy. Environment variables set in one don’t leak to another.

<𝒞=string:bash:dev>
cd ~/projects/myapp
export NODE_ENV=development
npm install
</𝒞>

The next command to bash:dev starts in ~/projects/myapp with NODE_ENV=development still set — exactly like a real terminal.

Bash topics don’t have navigation history (/back doesn’t apply). They have command history and shell state instead.

Unlike other topic types, bash topics accept plain text as shell input. The command-only requirement does not apply:

<𝒞=string:bash:dev>
echo "this is shell input, not a String command"
</𝒞>

This text goes to the shell’s stdin. No / prefix needed.

To send String commands to a bash topic, use the // escape:

<𝒞=string:bash:dev>
//info
</𝒞>

The // prefix strips one slash, sending /info as a String command instead of executing //info in the shell. This lets you run /info, /close, and other String commands on bash topics while preserving normal shell input for everything else.


Every AI agent in String has a home directory — a personal workspace rooted at a known path.

Home is not part of the topic identifier — topics are session names, not paths. Home is the root from which file paths in commands resolve:

/open report.md → ~/report.md
/open ~/report.md → ~/report.md
/open docs/report.md → ~/docs/report.md

This is the Unix convention. AI models already understand ~ as home. No new concept to learn.


Topic identifiers are session names — no paths to resolve. Paths appear inside commands and documents.

In commands — bare paths resolve from home (workspace root).

/open report.md → ~/report.md
/open docs/guide.md → ~/docs/guide.md

Explicit relative paths (./, ../) resolve from the current document’s directory when a document is open.

Inside a document — relative to the document’s own location.

~/docs/report.md
See the [appendix](./appendix.md) ← ~/docs/appendix.md
Check the [config](../config.md) ← ~/config.md

This matches every Markdown viewer — GitHub, Obsidian, VS Code. Documents are portable.


AI can hold multiple topics open at once. Each topic is independent:

ConcernScope
History (/back)Per topic
Current locationPer topic
AuthenticationPer topic (web/app)
Working directoryPer topic (file)

This enables workflows that require parallel context:

<𝒞=string:web:api_docs>
/open @authentication
</𝒞>
<𝒞=string:file:code>
/open ~/src/auth.md#oauth_flow
</𝒞>

The AI reads API documentation in one topic and edits code in another. Both stay open. Both maintain their own position. The AI switches between them as needed — no reloading, no lost state.

/info shows the current topic’s state:

<𝒞=string:web:docs>
/info
</𝒞>
Session info
---
uri: https://docs.example.com/api/auth
menus: main
actions: search(GET), get_token(POST)
history: 3 entries
vars: {lang}="en", {version}="v2"

This tells the AI where it is (full URI), what state exists, and what’s available — without reading the whole document again.

For file topics, /info shows workspace-relative paths:

Session info
---
file: docs/report.md
cwd: ~/docs/
title: Quarterly Report
history: 2 entries

/topics shows all active topics. It works from any topic:

<𝒞=string:file:main>
/topics
</𝒞>
Active topics:
file:main file current: #summary
web:docs web current: /api/auth
app:gmail:work app current: inbox
bash:dev bash cwd: ~/projects/myapp
4 topics open.

Filter by type:

/topics web
web:docs current: /api/auth
web:research current: /pricing
2 web topics open.

Available type filters: file, web, app, bash.

/close without arguments closes the current topic:

<𝒞=string:web:docs>
/close
</𝒞>

/close with a topic name closes that topic from anywhere:

<𝒞=string:file:main>
/close bash:dev
/close web:research
</𝒞>

Closing discards the topic’s state — history, variables, and (for bash) the shell process. The topic can be reopened, but it starts fresh.


/exec runs a shell command and returns the output. It is stateless — each invocation starts clean with only base environment variables.

<𝒞=string:file:main>
/exec npm test
</𝒞>

The command runs from the topic’s base path. For file topics, that’s the current document’s directory (or home if none is open). For app/web topics, it’s the app’s workspace. Without a topic, it runs from the AI’s home directory:

<𝒞=string>
/exec ls ~/projects
</𝒞>

/exec doesn’t remember previous runs. cd has no lasting effect. Environment variables don’t carry over. This makes it safe and predictable — no hidden state, no side effects between invocations.

When the AI needs a real shell session, it opens a bash topic:

<𝒞=string:bash:build>
cd ~/project && npm run build
</𝒞>
<𝒞=string:bash:build>
npm run deploy
</𝒞>

The second command runs in ~/project because the cd persisted. This is a full shell session — working directory, environment variables, shell history all maintained.

/execbash:name
StateNone — clean each timeFull shell state
Base pathTopic’s directory or ~Persisted cwd
Env varsBase onlyAccumulated
Use caseQuick checks, scriptsDevelopment, builds, debugging
RiskLow — isolatedNeeds runtime boundary

Sometimes the AI needs to open a link in a new tab — keeping the current session where it is, but starting a new one that inherits the current state. Internally this forks the session — deep-copying state into a new independent topic.

<𝒞=string:web:docs>
/open --tab research @api-reference
</𝒞>

This creates a new topic web:research by deep-copying the current session’s state:

What gets copiedWhat doesn’t
VariablesHistory
Authentication / cookiesCurrent location
Runtime configuration

The shortcut resolves in the current session’s context, and the new session starts at that destination with a clean history. From this point, the two sessions are fully independent — changing a variable in web:research does not affect web:docs.

This is the browser’s “open in new tab” model. The new tab inherits cookies and login state but lives on its own.

  • Exploring a side link without losing your place
  • Comparing two pages from the same authenticated site
  • Branching a workflow into parallel tracks

Though most common for web topics, it works on app topics too:

<𝒞=string:app:gmail:work>
/open --tab gmail-search @search
</𝒞>

Creates app:gmail-search with the same auth and variables as app:gmail:work. File topics don’t need fork — opening a different file path already creates an independent topic.


ConceptRule
TopicA named session — type:name format
Syntax[a-zA-Z0-9_-]+ names only — no dots, no paths
DefaultEmpty/bare → file:main
File topicfile:name — named workspace, navigate files within
Web topicweb:name — pages change, session persists
App topicapp:name[:config] — same as web, with multi-session support
Bash topicbash:name — stateful shell session, like a real terminal
Home~ or bare path → agent’s home directory (for commands, not topics)
Document pathsRelative to the document’s own location
StateHistory, location, auth — all per topic
/execStateless one-shot shell command from topic’s base path
/topics [type]List active topics, optionally filter by type
/close [topic]Close current or specified topic
New tab/open --tab name url — deep-copy state into new topic