Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/help-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Publish help

on:
push:
branches: [dev]
paths:
- 'docs/help/**'
- 'docs/screenshots/workspace-0.20.png'
- 'images/CodeNomad-Icon.png'
- 'scripts/build-help.mjs'
- 'scripts/test-help.mjs'
- 'package-lock.json'
- '.github/workflows/help-pages.yml'
pull_request:
paths:
- 'docs/help/**'
- 'docs/screenshots/workspace-0.20.png'
- 'images/CodeNomad-Icon.png'
- 'scripts/build-help.mjs'
- 'scripts/test-help.mjs'
- 'package-lock.json'
- '.github/workflows/help-pages.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: npm
- run: npm ci --ignore-scripts
- run: node --test scripts/test-help.mjs
- run: node scripts/build-help.mjs
- uses: actions/upload-pages-artifact@v3
with:
path: dist/help

deploy:
if: github.ref == 'refs/heads/dev' && github.event_name != 'pull_request'
needs: build
runs-on: ubuntu-24.04
permissions:
pages: write
id-token: write
concurrency:
group: help-pages
cancel-in-progress: false
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/configure-pages@v5
- uses: actions/deploy-pages@v4
id: deployment
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@

## Multi-Language Support (i18n)

- The separate public user guide lives in `docs/help/` and is intentionally English-only for now. `scripts/build-help.mjs` renders its Markdown using the existing `marked` dependency; `docs/help/help.css` owns the standalone site's square, responsive chrome. It does not import the application runtime or add an app locale. Validate it with `npm run test:help`; GitHub Pages publishes `dist/help` through `.github/workflows/help-pages.yml`.

The UI uses a small custom i18n layer (no ICU/messageformat). When building features, never hardcode user-visible strings.

- **Runtime API:** use `useI18n()` in components (`const { t } = useI18n();`) and `tGlobal(...)` in stores/non-component code.
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ CodeNomad is a **desktop and browser workspace for OpenCode V2** — built for d

*The 0.20 interface, rendered with demonstration data. [Download the latest stable release](https://github.com/NeuralNomadsAI/CodeNomad/releases/latest).*

[User help](https://neuralnomadsai.github.io/CodeNomad/) · [Read the guide on GitHub](docs/help/index.md) — a short English guide to current CodeNomad and OpenCode V2.

---

## Features
Expand Down
44 changes: 44 additions & 0 deletions dev-docs/USER_HELP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Public user help

The English guide in `docs/help/` covers current CodeNomad with OpenCode V2,
not the old runtime or every upstream configuration option. Assume readers
already know OpenCode: document CodeNomad's controls, workflow differences,
and state/scope boundaries instead of teaching agents, prompts, Git, or MCP.
Keep pages short, use current English interface labels, and link to the
official V2 docs for native configuration details.

## Build and check

```sh
npm ci --ignore-scripts
npm run test:help
npm run build:help
```

Output is `dist/help/`. Serve that directory with any static HTTP server to
preview it; no app backend, credentials, or OpenCode service is needed. The
builder uses the existing `marked` dependency, copies local screenshots/logo,
and generates relative links that work under a GitHub project-site path.
The site has no client JavaScript, remote fonts, analytics, or runtime requests.

## Publish on GitHub Pages

In **Repository Settings → Pages → Build and deployment**, select **GitHub
Actions** as the source. The repository currently has no Pages site; this is a
one-time administrator setup, not something the workflow silently enables.
Allow the `github-pages` environment to deploy from `dev` if its protection
rules require a branch allowlist.

After merging the workflow into `dev`, it builds and publishes changes to the
help sources. It can also be started manually from `dev`. Pull requests build
and check the site but never deploy it. Deployment needs `pages: write` and
`id-token: write`; the build job only reads repository contents.

Expected URL: **https://neuralnomadsai.github.io/CodeNomad/**. No separate
repository, paid hosting, domain, or additional deployment secret is needed.
The site follows `dev` (the current implementation); it is not an archive of
versioned guides. Update the help alongside user-visible behavior changes.

The desktop Help link should use this URL once deployment is available. Native
Help menu items are maintained in both desktop hosts; the updater work from
issue #606 remains separate from documentation hosting.
32 changes: 32 additions & 0 deletions docs/help/conversations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Conversations

The controls around your OpenCode sessions: composer context, pending requests, and full-history navigation.

## Composer controls

**Agent**, **model**, and **thinking** selectors live in the composer footer, alongside the session's worktree selector. Resize the composer without changing its draft; long drafts scroll within it.

The composer remains available during execution. Subsequent submissions may enter the session's pending queue; **Stop** targets the current execution.

## Context attachments

- **`@`** searches project files, agents, and skills available in the session's Location. Selecting a skill attaches a removable badge rather than inserting its instructions into your draft.
- The **attachment** action, drop, and paste use files from your client device. Project file references resolve on the execution host.
- **`/`** lists the Location's commands. **`/btw`** opens a temporary side-question window without replacing the main conversation.

## Requests across conversations

Pending questions and permissions are edited **above the composer**, not in transcript cards. Request drafts survive queue refreshes and session navigation.

The request area includes the open session, its descendants, and other conversations. Origin labels identify the source; **View conversation** navigates there. External requests start compact and can be answered in place. Arrival does not replace the request being edited or switch your session. Use previous/next controls when several requests are pending.

CodeNomad's **Yolo mode** applies to the session family: it automatically approves permissions, not questions or other Forms.

## History navigation

- **Search** queries full history, not just mounted transcript rows.
- **Timeline** markers jump to messages and tool activity. Hover/focus previews let you inspect a point without loading a whole transcript section. At narrow conversation widths, the rail is hidden and header actions move into overflow.
- **Message content visibility** controls reasoning and tool presentation without changing stored history.
- **Fork** continues from a history point in a separate session.

Subsessions appear beneath their parent in normal browsing. Session search uses flat results, with an option to include subsessions. View closure, session deletion, and history pruning are separate operations; the latter two can remove stored content.
37 changes: 37 additions & 0 deletions docs/help/files-and-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Files and tools

The right panel combines workspace browsing, Git inspection, and project services. Readers open centrally, above the composer.

## Workspace files

In **Files → Workspace**, expand folders and select a row. Use its **eye** action to open the central file reader; selecting a row alone does not open it.

Text files, including Markdown source, are editable. Use **Save** or **Ctrl/Cmd+S** to write changes. If the file changed on disk, CodeNomad asks you to resolve that conflict rather than silently replacing it. Images and binary previews are read-only.

Close the reader with its **X** to return to the conversation.

## Review Git changes

Switch **Files** to **Changes** to inspect staged and unstaged files. Open a diff with the eye action, stage or unstage files, and use the commit controls at the top of the staged section.

Switch to **Commits** to browse repository history and inspect historical diffs. Diffs are read-only; use the layout switch to choose unified or split views.

## Check Status

The **Status** panel shows project services and background activity, including **MCP Servers** and **Plugins**.

- **MCP Servers** exposes connection state and activation controls.
- **Plugins** have separate **Global** and **Project** activation switches. Global changes can affect other projects; a project rule can override the global choice.
- Background shell activity is distinct from an interactive terminal and from the agent's current reply.

## Preview a web app

Open the session's **browser preview** from the conversation toolbar. It is attached to that session; the agent can target the visible preview through CodeNomad's browser tools. Opening it does not start a development server.

Agent-driven native browser control is available in Electron and **Windows Tauri**. Other Tauri platforms use an iframe preview; that is not equivalent to native browser automation. Some sites also prevent iframe embedding.

## Add a SideCar

**SideCars** are tabs for web tools running on the CodeNomad server host, such as an editor or terminal service.

Start the tool separately, then add it in **Settings → SideCars** with its name, port, and protocol. The port refers to the **server host**, not necessarily the device displaying CodeNomad. Match the prefix mode to the tool's base-path support; see the [SideCar examples](https://github.com/NeuralNomadsAI/CodeNomad#sidecars).
31 changes: 31 additions & 0 deletions docs/help/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Connect OpenCode

Use your existing OpenCode V2 setup from a local desktop host or through a CodeNomad server.

## Local desktop

Download [the current desktop build](https://github.com/NeuralNomadsAI/CodeNomad/releases/latest), then select your OpenCode executable in setup. CodeNomad prefers executables on `PATH`; **Settings → OpenCode** exposes the selected CLI and the running shared service separately. An installation action is available if you need it. Desktop builds bundle Node.js/npm.

Open the repository or folder whose sessions you want to access. CodeNomad uses directory ownership to determine which sessions belong to that project; see [projects and worktrees](projects.md).

## Backend versus execution host

Git must be available in the **CodeNomad backend's `PATH`**, even when OpenCode executes inside WSL. Git installed only in WSL does not satisfy a Windows backend. Restart the backend after changing its environment.

With Git unavailable, folder-only sessions remain usable, but Git/worktree features and cross-checkout discovery are unavailable.

## Browser and remote desktop

Run CodeNomad on the host containing your projects and OpenCode setup. The standalone server requires Node.js 24 LTS/npm:

```sh
npx @neuralnomads/codenomad --password "your-password" --launch
```

Use the printed connection URL in a browser or CodeNomad's remote connection screen. The server binds to loopback by default; use the [server guide](https://github.com/NeuralNomadsAI/CodeNomad/blob/dev/packages/server/README.md#remote-access-binding-rules) for remote binding, authentication, and TLS options.

Project paths, commands, and SideCar ports refer to the **server host**, not the client displaying CodeNomad. Device attachments are the exception: they come from the client device.

## CLI updates are not service restarts

Updating OpenCode through CodeNomad changes the installed executable, not the running service. Restart explicitly when you want to activate it; this can interrupt work in all connected clients. Closing CodeNomad leaves the service running.
93 changes: 93 additions & 0 deletions docs/help/help.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
:root {
color-scheme: light dark;
--canvas: #edf0f4;
--panel: #e0e6ed;
--text: #283a4a;
--muted: #526373;
--accent: #375c9b;
--border: #bdc9d6;
--code: #dce3ec;
font-family: "Segoe UI", system-ui, sans-serif;
line-height: 1.65;
background: var(--canvas);
color: var(--text);
}
@media (prefers-color-scheme: dark) {
:root {
--canvas: #272f40;
--panel: #333e52;
--text: #dce3ef;
--muted: #adbed4;
--accent: #c6b58c;
--border: #53647c;
--code: #333e52;
}
}
* { box-sizing: border-box; }
body { margin: 0; }
a { color: var(--accent); text-underline-offset: .2em; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.skip-link { position: fixed; top: -100px; left: 1rem; padding: .5rem 1rem; background: var(--canvas); z-index: 3; }
.skip-link:focus { top: 1rem; }
.site-header { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 1rem 2rem; border-bottom: 1px solid var(--border); }
.brand { display: flex; align-items: center; gap: .7rem; color: var(--text); font-size: 1.25rem; font-weight: 650; text-decoration: none; }
.brand span { font-size: .875rem; font-weight: 400; color: var(--muted); border-left: 1px solid var(--border); padding-left: .7rem; }
.site-header nav { display: flex; gap: 1.5rem; font-size: .875rem; }
.layout { display: grid; grid-template-columns: 230px minmax(0, 760px) 190px; gap: 3rem; max-width: 1400px; margin: auto; padding: 2.5rem 2rem; }
.sidebar, .outline { position: sticky; top: 2rem; align-self: start; max-height: calc(100vh - 4rem); overflow: auto; font-size: .875rem; }
.eyebrow { margin: 0 0 .75rem; text-transform: uppercase; letter-spacing: .1em; font-size: .75rem; color: var(--muted); font-family: ui-monospace, monospace; }
.sidebar nav { display: grid; gap: .2rem; }
.sidebar nav a { padding: .6rem .75rem; color: var(--text); text-decoration: none; border-left: 3px solid transparent; }
.sidebar nav a:hover { background: var(--panel); }
.sidebar nav a[aria-current] { background: var(--panel); border-color: var(--accent); font-weight: 600; }
.scope { color: var(--muted); border-top: 1px solid var(--border); margin-top: 1.5rem; padding: 1rem .75rem; font-size: .8rem; }
main { min-width: 0; }
main:focus { outline: none; }
h1, h2, h3 { font-family: "Segoe UI", system-ui, sans-serif; line-height: 1.25; font-weight: 650; scroll-margin-top: 1.5rem; }
h1 { font-size: clamp(2rem, 3vw, 2.8rem); letter-spacing: -.035em; margin: 0 0 1.2rem; }
h2 { font-size: 1.4rem; margin: 2.5rem 0 1rem; }
h3 { font-size: 1.1rem; margin-top: 2rem; }
article > p:first-of-type { font-size: 1.15rem; color: var(--muted); }
p, ul, ol { margin: 0 0 1.2rem; }
ul, ol { padding-left: 1.5rem; }
li { margin: .4rem 0; }
article img { max-width: 100%; height: auto; display: block; border: 1px solid var(--border); margin: 1.5rem 0; }
strong { font-weight: 650; }
code, kbd, pre { font-family: "Cascadia Code", "SFMono-Regular", Consolas, monospace; font-size: .875em; }
code { background: var(--code); padding: .15em .3em; overflow-wrap: anywhere; }
pre { background: var(--code); border-left: 3px solid var(--accent); padding: 1rem; overflow-x: auto; }
pre code { padding: 0; overflow-wrap: normal; }
kbd { border: 1px solid var(--border); padding: .1em .3em; }
table { border-collapse: collapse; width: 100%; font-size: .95rem; margin: 1.5rem 0; }
th, td { border-bottom: 1px solid var(--border); padding: .65rem .5rem; text-align: left; overflow-wrap: anywhere; }
th { font-weight: 600; }
blockquote { border-left: 3px solid var(--accent); margin: 1.5rem 0; padding-left: 1rem; color: var(--muted); }
.outline { color: var(--muted); font-size: .8rem; }
summary { cursor: pointer; color: var(--text); font-weight: 600; }
.outline ul { list-style: none; padding: .5rem 0; margin-bottom: 1rem; }
.outline a { color: var(--muted); text-decoration: none; display: block; padding: .2rem 0; }
.outline a:hover { color: var(--accent); }
footer { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 1rem; margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--border); font-size: .8rem; }
@media (max-width: 1150px) {
.layout { grid-template-columns: 210px minmax(0, 760px); gap: 2rem; }
.outline { display: none; }
}
@media (max-width: 720px) {
.site-header { padding: 1rem; gap: .5rem; }
.brand { font-size: 1rem; gap: .4rem; }
.brand span { padding-left: .4rem; }
.site-header nav { gap: .75rem; font-size: .8rem; }
.layout { display: block; padding: 1rem; }
.sidebar { position: static; max-height: none; overflow: visible; border-bottom: 1px solid var(--border); margin-bottom: 2rem; padding-bottom: 1rem; }
.sidebar nav { display: flex; flex-wrap: wrap; gap: .25rem; }
.sidebar nav a { padding: .45rem .6rem; }
.scope { border: 0; margin: .75rem 0 0; padding: 0; }
.scope br { display: none; }
td:last-child { width: 42%; }
}
@media print {
.site-header, .sidebar, .outline, footer, .skip-link { display: none; }
.layout { display: block; padding: 0; }
:root { --canvas: white; --text: black; --muted: #333; --accent: #222; --code: #eee; }
}
26 changes: 26 additions & 0 deletions docs/help/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# CodeNomad help

An OpenCode workspace, across projects, sessions, and worktrees.

This guide assumes you already use **OpenCode V2**. It covers CodeNomad's interface and workflow, not the basics of agents or OpenCode configuration.

![CodeNomad workspace with project tabs, sessions, a conversation, and the Status panel](../screenshots/workspace-0.20.png)

## Find the control you need

| I want to… | Read |
|---|---|
| Connect CodeNomad to my OpenCode setup | [Connect OpenCode](getting-started.md) |
| Navigate history, attach context, handle requests across sessions | [Conversations](conversations.md) |
| Move a session family between checkouts | [Projects and worktrees](projects.md) |
| Use the file reader, Git views, browser preview, and SideCars | [Files and tools](files-and-tools.md) |
| Control model visibility, accounts, and Global/Project settings | [Settings](settings.md) |
| Diagnose a CodeNomad-specific problem | [Troubleshooting](troubleshooting.md) |

## What stays shared

CodeNomad uses the shared OpenCode service. Sessions and history remain available to compatible OpenCode clients; tabs, drafts, and layout are restored separately per CodeNomad window. Closing a tab or window does **not** stop the service.

## Reference

For native configuration, use the [OpenCode V2 documentation](https://opencode.ai/v2/docs/). For hosting options, use the [CodeNomad server guide](https://github.com/NeuralNomadsAI/CodeNomad/blob/dev/packages/server/README.md).
Loading
Loading