Topics
Topics
Section titled “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.
What a topic is
Section titled “What a topic is”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.
Topic syntax
Section titled “Topic syntax”All topics follow a typed format:
type:name- type:
file,web,app, orbash - 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:maindocs → file:docsAn empty or absent topic defaults to file:main.
In ChanFlow: string:<type:name>. In HTTP: body {"topic": "type:name"}.
Topic types
Section titled “Topic types”A file session is a named workspace for local file operations.
string:file:mainstring:file:docsstring:file:notesThe 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_1string:web:docsstring:web:competitor_researchWhen 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:gmailstring:app:slackstring:app:gmail:workstring:app:gmail:personalApps 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:devstring:bash:deploystring:bash:debugEach 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/myappexport NODE_ENV=developmentnpm 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.
Bash topics and commands
Section titled “Bash topics and commands”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.mdThis is the Unix convention. AI models already understand ~ as home.
No new concept to learn.
Path resolution
Section titled “Path resolution”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.mdExplicit relative paths (./, ../) resolve from the current
document’s directory when a document is open.
Inside a document — relative to the document’s own location.
See the [appendix](./appendix.md) ← ~/docs/appendix.mdCheck the [config](../config.md) ← ~/config.mdThis matches every Markdown viewer — GitHub, Obsidian, VS Code. Documents are portable.
Multi-topic operation
Section titled “Multi-topic operation”AI can hold multiple topics open at once. Each topic is independent:
| Concern | Scope |
|---|---|
History (/back) | Per topic |
| Current location | Per topic |
| Authentication | Per topic (web/app) |
| Working directory | Per 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.
Inspecting a topic
Section titled “Inspecting a topic”/info shows the current topic’s state:
<𝒞=string:web:docs>/info</𝒞>Session info---uri: https://docs.example.com/api/authmenus: mainactions: search(GET), get_token(POST)history: 3 entriesvars: {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.mdcwd: ~/docs/title: Quarterly Reporthistory: 2 entriesListing topics
Section titled “Listing topics”/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.
Closing topics
Section titled “Closing topics”/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.
Shell execution
Section titled “Shell execution”/exec — stateless one-shot
Section titled “/exec — stateless one-shot”/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.
bash:name — stateful terminal
Section titled “bash:name — stateful terminal”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.
When to use which
Section titled “When to use which”/exec | bash:name | |
|---|---|---|
| State | None — clean each time | Full shell state |
| Base path | Topic’s directory or ~ | Persisted cwd |
| Env vars | Base only | Accumulated |
| Use case | Quick checks, scripts | Development, builds, debugging |
| Risk | Low — isolated | Needs runtime boundary |
Opening a new tab
Section titled “Opening a new tab”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 copied | What doesn’t |
|---|---|
| Variables | History |
| Authentication / cookies | Current 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.
When to fork
Section titled “When to fork”- Exploring a side link without losing your place
- Comparing two pages from the same authenticated site
- Branching a workflow into parallel tracks
Works on any topic type
Section titled “Works on any topic type”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.
Summary
Section titled “Summary”| Concept | Rule |
|---|---|
| Topic | A named session — type:name format |
| Syntax | [a-zA-Z0-9_-]+ names only — no dots, no paths |
| Default | Empty/bare → file:main |
| File topic | file:name — named workspace, navigate files within |
| Web topic | web:name — pages change, session persists |
| App topic | app:name[:config] — same as web, with multi-session support |
| Bash topic | bash:name — stateful shell session, like a real terminal |
| Home | ~ or bare path → agent’s home directory (for commands, not topics) |
| Document paths | Relative to the document’s own location |
| State | History, location, auth — all per topic |
/exec | Stateless 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 |