# Workspace

Byte opens on its code workspace: in the suite from **Byte** in the workspace
sidebar, and in the standalone plugin from `SleekWP > Byte`. Settings and
License sit below Byte in the sidebar.

## The file tree and the editor

The file tree lists every file of every [source](/docs/byte/snippets/sources.md).
Before the first snippet exists, the editor area says so and offers
**Create snippet**.
With one source its files sit at the top level; with more, each source is a
top-level folder named after it. A folder that holds a `snippet.json` carries
a mark: **Snippet**, **Snippet (disabled)** when its `enabled` is false, or
**Snippet (invalid snippet.json)** when the file is not a valid JSON object,
which also stops the snippet from running.

Files open in tabs inside the editor, with PHP errors, per-file change marks
and search and replace across files. Every Byte tab in the workspace keeps its
own set of open files.

**Create snippet** and **Export snippets** sit beside **Snippets** above the
file tree: the first opens the create dialog, the second builds a plugin from
snippets; see [Export to a plugin](/docs/byte/snippets/export.md). The toolbar
above the editor holds, from the left:

| Button                             | What it does                                                                                      |
| ---------------------------------- | ------------------------------------------------------------------------------------------------- |
| Snippet configuration              | Edits the selected file's `snippet.json`; see [Configuration](/docs/byte/snippets/configuration.md). |
| Runtime errors                     | Opens the snippet's error log; see [Errors and safe mode](/docs/byte/snippets/errors.md).            |
| Delete snippet, or Delete file     | Removes the snippet the selected file belongs to, or the selected file when it belongs to none.   |
| Turn off safe mode, while it is on | Ends [safe mode](/docs/byte/snippets/errors.md) for you.                                             |
| Discard                            | Drops every unsaved change.                                                                       |
| Save                               | Saves every change; see below.                                                                    |

The configuration and error buttons act on the snippet the selected file
belongs to, and are unavailable while the selected file belongs to none.
When the toolbar is too narrow for the button labels, as on a phone, Delete
and Turn off safe mode show their icon alone, with the name as their tooltip.
**History**, beside **Snippets** above the file tree, lists the snippet's
commits in its place; see [History](/docs/byte/snippets/history.md).
The preview control sits in the workspace header; see
[Preview](/docs/byte/snippets/preview.md).

Right-clicking the tree offers **Add file** and **Add folder** on a folder,
**Create snippet** on a folder that is not inside a snippet, **Fix error** on a
file with a PHP error, which selects it, and a delete named for what it
removes. **Delete snippet** on a file or folder inside a snippet removes that
whole snippet from the draft, **Delete folder** removes any other folder with
everything in it, and **Delete file** a file outside every snippet.

Every delete asks first, naming what it removes. It only changes the draft:
until you save, **Discard** brings it back, and after that it cannot be
undone. While the draft holds unsaved changes, the browser asks before you
reload or close the page.

## Creating

**Create in Byte** creates a snippet, a file or a folder in the source listed
first in the tree; its button names the type you chose, such as **Create
file**. For a snippet, the path becomes its folder, and Byte writes
a `snippet.json` with the name, description and version `1.0.0`, plus one
starter file of the type you choose: `index.php`, `style.css`, `style.scss` or
`script.js`. Path segments are lowercased and reduced to letters, digits and
hyphens.

## Saving

Everything you change, create or delete is a draft until you choose **Save**.
About a second after you stop typing, the workspace sends the changed PHP
files to `Actions_testPhpCode`, which parses them and refuses shell execution
(`exec`, `shell_exec`, `system`, `passthru`, `proc_open`, `popen` and the
backtick operator) and variable function calls such as `$callback()`. A
rejected file is marked in the tree and the editor, and Save refuses to run
while one is. The check does not run the code, so an error that only happens
at run time, such as a call to an undefined function, passes it.

Save then writes the changed files and deletes the removed ones through
`Actions_updateFiles`, which only writes inside a source, records a
[Git commit](/docs/byte/snippets/history.md) for every snippet the save touched
when history is on, and refreshes an open preview. A saved PHP file runs on
the next request, so check it in the [preview](/docs/byte/snippets/preview.md)
first.

## Settings

Byte's **Settings** page has one card, Editor, saved with the page's **Save**
and confirmed as "Settings saved.":

- **Show line numbers**, on by default, shows the numbered gutter.
- **Wrap long lines**, off by default, wraps lines instead of scrolling them.

They apply to every administrator of the site, and the suite and the
standalone plugin read the same values. AI provider keys are not set here:
they live in the AI section of the settings panel that the settings button
beside the light and dark mode control opens, shared by every SleekWP product,
and in the standalone plugin in its Settings; see
[Assistant](/docs/byte/ai/chat.md).

## Links

The workspace keeps its state in the admin page's query, before the hash, so
a link can open it in that state:

- `file=<path>` selects that file, such as `file=demo/style.css` on the
  workspace's query, before `#/byte`, in the suite, or
  `admin.php?page=sleek-byte&file=demo/style.css` in the standalone plugin.
- `dialog=create` opens the create dialog, with `kind=snippet`, `kind=file` or
  `kind=folder` and `parent=<folder>` to preset it.
- `dialog=config` and `dialog=errors` open the configuration and runtime
  error dialogs of the selected file's snippet, and `dialog=export` opens the
  export dialog. A dialog the selected file cannot serve is dropped from the
  address.
- `view=history` shows the History view in the left bar; an older link's
  `dialog=history` shows it too.
