Skip to content
Merged
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
35 changes: 16 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ teams writing SOPs and runbooks, trainers and teachers, support teams answering
screenshot for email addresses, card numbers, passwords, API keys and more,
and blurs them.
- **Send a link, not a file.** Publish any guide as a web page in one click,
hosted free on your own GitHub. [More below](#share-a-guide-with-a-link).
hosted free on your own GitHub. [More below](#share-a-guide-with-a-web-link).
- **Export to what your team already uses.** PDF, Word, PowerPoint, Markdown,
HTML, Confluence, Wiki.js and more, so a guide lands where people will read it.

Expand All @@ -94,9 +94,6 @@ page and hands you a link to send. It's usually online in under a minute.
- **The same link, always up to date.** Changed the guide? Publish again and
the link stays the same. StepForge marks guides you've **edited since you
shared them**, so you never send out a stale version.
- **Checked before it goes public.** Screenshots are scanned for email
addresses, passwords, keys and card numbers, and those are blurred before
anything is uploaded.
- **Hard to stumble on.** Every link has a random ID, and pages ask search
engines not to index them. Want links on `guides.yourdomain.com`? Point a
[custom domain](docs/GITHUB_PAGES.md#use-your-own-domain) at it and
Expand All @@ -106,9 +103,9 @@ page and hands you a link to send. It's usually online in under a minute.
password.

> [!IMPORTANT]
> Shared guides are **public**: anyone with the link can open them. The
> privacy check catches a lot, but always look over your screenshots before
> publishing. [How sharing works](docs/GITHUB_PAGES.md)
> Shared guides are **public**: anyone with the link can open them. StepForge
> blurs the private details it finds before publishing, but always look over
> your screenshots yourself. [How sharing works](docs/GITHUB_PAGES.md)

## Install

Expand All @@ -119,14 +116,8 @@ page and hands you a link to send. It's usually online in under a minute.
| **Fedora 44 Workstation** | DNF repository | [Fedora](docs/linux/dnf.md) |
| **Other Linux** | Portable `.tar.gz` | [Linux overview](docs/linux/linux_install.md) |

Every build is also on the [Releases page](https://github.com/Twest2/StepForge/releases/latest).
The Microsoft Store updates StepForge automatically. Installing through
Chocolatey, APT or DNF keeps StepForge up to date with the rest of your system,
and with Chocolatey, **Settings → About → Update now** installs a new version
in one click.

**Windows:** open [StepForge in the Microsoft Store](https://apps.microsoft.com/detail/9NDH81CF1HGV)
and click **Get**.
**On Windows,** get StepForge from the Microsoft Store. It needs no
administrator rights and keeps itself up to date.

<a href="https://apps.microsoft.com/detail/9NDH81CF1HGV"><img src="https://get.microsoft.com/images/en-us%20dark.svg" alt="Get it from Microsoft" width="200"></a>

Expand Down Expand Up @@ -174,13 +165,19 @@ sudo dnf install stepforge

</details>

Chocolatey, APT and DNF keep StepForge up to date along with the rest of your
system. Every build is also on the
[Releases page](https://github.com/Twest2/StepForge/releases/latest).

## Your first guide in one minute

1. Open StepForge and choose **New guide**.
2. Choose **Capture → Start capture session**. StepForge steps out of the way.
3. Do the task you want to document, clicking as you normally would.
4. Stop the recording from the tray icon (Windows) or **StepForge REC** in the
GNOME top panel (Linux).
4. To stop on **Windows**, click the **red dot** beside the clock. Don't see
it? Click the **^** arrow near the clock, then the red dot. On **Linux**,
click **● StepForge REC → Stop recording** at the top right of the screen.
[More help](docs/GETTING_STARTED.md#stop-recording)
5. Tidy up titles, add annotations, then choose **Export**.

The [Getting Started guide](docs/GETTING_STARTED.md) walks through recording,
Expand Down Expand Up @@ -221,7 +218,7 @@ was recorded with StepForge.
annotated images.
- **Share a link.** Publish a guide as an interactive web page on your own
GitHub Pages site for 1, 7 or 30 days, removed automatically when its time
is up. [See how it works](#share-a-guide-with-a-link).
is up. [See how it works](#share-a-guide-with-a-web-link).
- **Publish to Confluence** (beta) on Confluence Cloud or your organization's
Data Center site, including sites that need a smart card (CAC).
- **Publish to Wiki.js** (beta), with the screenshots uploaded to the wiki.
Expand Down Expand Up @@ -260,7 +257,7 @@ each optional feature sends.
- [Getting started](docs/GETTING_STARTED.md): recording, editing and exporting
- [AI-written guides with Ollama](docs/getting_started_with_ai.md)
- [Let Claude or Codex write your guides](docs/AI_AGENTS.md)
- [Google Drive sync](docs/GOOGLE_DRIVE.md) · [OneDrive, Dropbox or Nextcloud](docs/CLOUD_ACCOUNTS.md)
- [Sync between computers](docs/CLOUD_ACCOUNTS.md) with Google Drive, OneDrive, Dropbox or Nextcloud
- [Share guides on the web with GitHub Pages](docs/GITHUB_PAGES.md)
- [Publish to Confluence](docs/CONFLUENCE.md) · [Publish to Wiki.js](docs/WIKIJS.md)
- [Brand your exported guides](docs/BRANDING.md): logos, colors, fonts and Advanced CSS
Expand Down
116 changes: 57 additions & 59 deletions docs/AI_AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,47 +13,6 @@ window opens, and nothing runs when no agent is connected.
> on your own computer through Ollama. See
> [AI-written guides with Ollama](getting_started_with_ai.md).

## What an agent can and can't do

| An agent can | An agent can't |
| --- | --- |
| List and read your guides | Change a placeholder you already have, or delete one |
| See each step's screenshot, with your blurs already filled in | Delete blurs, or see what they hide |
| Create guides, and move them to the Trash | Delete brand profiles |
| Rewrite a guide's title and description | Read anything outside your StepForge library, except a PNG you ask it to use as a screenshot, or an image or font file you ask it to add to a brand profile |
| Add, delete, and reorder steps, and make a step a substep of an earlier step | |
| Rewrite each step's title, description, and blocks, add notes, warnings, tips, and code, and delete blocks | |
| Replace a step's screenshot with a PNG file you point it to, or remove the screenshot | |
| Add guide and global placeholders, and use them as `[[Name]]` | |
| Draw on screenshots: rectangles, ovals, lines, arrows, text, callouts, numbered badges, blurs, highlights, magnifiers, and cursors. Delete what's drawn, except blurs | |
| If you allow it: make and change [brand profiles](BRANDING.md#let-an-ai-agent-set-up-your-brand), add a logo, banner or font file you point it to, and choose the active profile | |

Most of the time an agent works around your screenshots: it writes the text,
organizes the steps, and adds annotations on top. When it does more than that,
StepForge keeps a way back.

### Undoing what an agent did

Before an agent deletes, moves, or adds a step, replaces or removes a
screenshot, or deletes blocks or annotations, StepForge saves a snapshot of the
guide. To undo the change, open the guide and choose **More → Backups &
snapshots**. Each agent snapshot is named for what the agent was about to do,
for example "before agent deletes step 3". **Restore** the one from just before
the change you want to undo. Restoring snapshots the guide first, so a restore
can be undone too.

Automatic backups don't push agent snapshots out. StepForge keeps the newest 50
agent snapshots of each guide. Text rewrites, changing substep nesting with
`update_step`, adding placeholders and drawing annotations do not create agent
snapshots; create a manual snapshot first if you want a recovery point before
those edits.

A guide an agent deletes goes to the Trash, like one you delete. Restore it
from there. Its snapshot and Trash copy contain saved content; unsaved edits
in an open editor are not included when the agent deletes the guide. The
agent-access switch permits all the guide tools listed above; it is not a
separate approval for each deletion.

## 1. Turn on agent access

1. Open **Settings → AI**.
Expand Down Expand Up @@ -92,18 +51,61 @@ Record a guide in StepForge as usual, then ask your agent, for example:

The agent finds the guide, looks at each step's screenshot, and rewrites the
text. It uses your placeholders where their values would appear, and can add
new ones for values that repeat, such as a course code or product name. If
the guide is open in StepForge, it updates on screen within a couple of
seconds. If you're typing in the same step at that moment, your edit wins. If
the agent deleted that step, StepForge drops its pending save and shows the
remaining steps instead of recreating it. For a surviving step, changes to
different fields, blocks or annotations combine; your edit wins when both
sides changed the same field.

Before you share the guide, read what the agent wrote. To undo a big rewrite,
use **More → Backups & snapshots**. Annotations an agent drew can be moved or
deleted like your own. If you have the guide open when an agent moves it to
the Trash, StepForge takes you back to the library.
new ones for values that repeat, such as a course code or product name.

If the guide is open in StepForge, it updates on screen within a couple of
seconds. If you and the agent change the same thing at the same moment, your
edit wins.

Read what the agent wrote before you share the guide.

## What an agent can and can't do

An agent can:

- list and read your guides, and see each step's screenshot with your blurs
already filled in
- create guides, and move them to the Trash
- add, delete, reorder, and nest steps
- rewrite the guide's and each step's title, description, and blocks (notes,
warnings, tips, and code)
- replace a step's screenshot with a PNG file you point it to, or remove it
- add guide and global placeholders
- draw on screenshots (shapes, arrows, text, callouts, numbered badges, blurs,
highlights, magnifiers, and cursors), and delete annotations other than
blurs
- if you allow it, set up your
[brand profiles](BRANDING.md#let-an-ai-agent-set-up-your-brand)

An agent can't:

- delete blurs, or see what they hide
- change or delete a placeholder you already have
- delete a brand profile
- read files outside your StepForge library, except one you ask it to use as
a screenshot, logo, or font

StepForge doesn't ask before each change: turning on agent access allows
everything above.

## Undoing what an agent did

Before an agent deletes, moves, or adds a step, replaces or removes a
screenshot, or deletes blocks or annotations, StepForge saves a snapshot of the
guide. Each one is named for what the agent was about to do, such as "before
agent deletes step 3".

To undo a change, open the guide, choose **More → Backups & snapshots**, and
**Restore** the snapshot from just before it. Restoring snapshots the guide
first, so a restore can be undone too.

Rewriting text, changing substeps, adding placeholders, and drawing
annotations don't make a snapshot. If you want a way back before those, create
a snapshot yourself first. Annotations an agent drew can be moved or deleted
like your own.

A guide an agent deletes goes to the Trash, like one you delete. If you have
it open at the time, StepForge takes you back to the library.

## Privacy

Expand All @@ -113,12 +115,8 @@ its AI provider**, such as Anthropic for Claude or OpenAI for Codex. Their
privacy terms apply to that data.

- Screenshots are shared with your blurs filled in, so the agent never sees
what you hid. Agents can't delete blurs. Screenshot imports must come from
outside the library; raw originals, Trash and snapshot files cannot be
imported to bypass the blurs. Replacing a screenshot keeps its blurs,
including those added by Find private details.
- An agent reads a file outside your library only when it uses one as a
screenshot or adds one to a brand profile, and only the file it names.
what you hid. Replacing a screenshot keeps its blurs, and an agent can't
swap in an unblurred copy from your library.
- Agents never get the text you typed while recording, field values, or the
text StepForge read from the screen.
- Turning off **Let AI agents edit your guides** cuts off every connected
Expand Down
76 changes: 61 additions & 15 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,31 @@ Export dialog choice. In the profile editor, **Pick from logo** runs
`core/brand-palette.js` on a small canvas drawing of the logo, and **Write
with AI** asks Ollama for CSS (`core/ai-brand-css.js`, which also strips
`@import` and remote `url()`s); it's shown only when `ai:status` reports AI on
and the model installed. AI agents edit guides through `core/agent-tools.js`;
each tool that deletes, moves or replaces something first calls
`createAgentSnapshot` (`core/snapshots.js`). AI agents reach profiles through
`core/agent-brand-tools.js`, behind `ai.agents.branding`. The `--mcp` process
records each change in `agent-changes.json`; the running app saves an agent's
choice of active profile itself (it holds Settings in memory) and has the
renderer draw PNG copies of SVG or JPG images agents added
(`branding:pendingRasters`).
and the model installed.

## AI Agents (MCP)

`stepforge --mcp` runs an MCP server over stdio for agents such as Claude Code
and Codex, gated by `ai.agents` (re-read on every request).

- Guide tools live in `core/agent-tools.js`. Each tool that deletes, moves or
replaces something first calls `createAgentSnapshot` (`core/snapshots.js`).
Text rewrites, substep changes through `update_step`, new placeholders and
drawn annotations don't snapshot.
- Agents can't delete blurs or existing placeholders. A screenshot an agent
imports must come from outside the library, so raw originals, Trash and
snapshot files can't be used to get around blurs, and a replaced screenshot
keeps its blurs, including those from Find private details.
- When an agent deletes a guide, the snapshot and Trash copy hold the saved
content only, not unsaved edits in an open editor. If the editor has the
step an agent deleted, it drops that step's pending save instead of
recreating it; for surviving steps, edits to different fields combine and
the user's edit wins a field both changed.
- Profiles are reached through `core/agent-brand-tools.js`, behind
`ai.agents.branding`. The `--mcp` process records each change in
`agent-changes.json`; the running app saves an agent's choice of active
profile itself (it holds Settings in memory) and has the renderer draw PNG
copies of SVG or JPG images agents added (`branding:pendingRasters`).

## Shell / Core Boundary

Expand Down Expand Up @@ -250,7 +267,7 @@ opt-in and off by default:
untrusted and pass archive validation before a journaled, staged
replacement that keeps a local backup. Archive compression runs one job at a
time in a background worker shared with linked-archive writes and
automatic backups. See [GOOGLE_DRIVE.md](GOOGLE_DRIVE.md) and
automatic backups. See [CLOUD_ACCOUNTS.md](CLOUD_ACCOUNTS.md) and
[SECURITY.md](SECURITY.md).
- **Synced settings** (`core/shared-settings.js`): global placeholders, brand
profiles with the assets they use, the active profile, the language and
Expand All @@ -263,8 +280,12 @@ opt-in and off by default:
new computer's defaults never win a merge.
Per-value edit times travel in `settings.json.modifiedAt`; their local
copy is `settings/shared-settings-times.json`, updated only when that value
changes. Older archives fall back to their version time. Profile field
conflicts compare the profile's `updatedAt`.
changes, so editing one value never makes another look newer. Older
archives fall back to their version time. Profile field conflicts compare
the profile's `updatedAt`. A settings version that is damaged or needs a
newer StepForge stops settings sync with an error rather than being
skipped, because a merge published without it could discard values this
build couldn't read; guide sync carries on.
The base is `cloud/settings-base.json`. Incoming settings wait while the
Settings dialog is open. Incoming recording shortcuts re-register the running
app’s global hotkeys immediately. Every image and font is re-checked by
Expand All @@ -275,6 +296,9 @@ opt-in and off by default:
`core/folder-storage.js` keeps each version's details in a small
`objects/<id>.json` beside its data and names shared parts by their hash.
`settings.cloud.provider` picks the one service that syncs.
- **Unused parts** are garbage-collected after a sync and by **Free up
space**, except parts uploaded in the last hour, which another computer may
still be committing a version for.

The sandboxed renderer never makes network requests or sees tokens; all of
these run in the main process.
Expand All @@ -283,21 +307,43 @@ these run in the main process.

- Archive imports validate every entry name against path traversal and
absolute paths before extraction (`core/zip.js`).
- Linked guides use sidecar `*.lock-sfgz` lock files; conflicts surface a
- Linked guides use sidecar `*.lock-sfgz` lock files that record who is
saving, not who has the guide open. Saving while another client holds the
lock is refused unless the user saves anyway; conflicts surface a
keep-editing / discard dialog. A linked save re-reads the shared file under
the lock and three-way merges it (`core/guide-merge.js`) with the version
this library last saved or opened, kept in `history/linked-base.json`.
this library last saved or opened, kept in `history/linked-base.json`. A
value both sides changed goes to the more recent edit, the toast reports
the conflict count, and a backup is taken before each merge.
- Renderer runs with `contextIsolation: true`, `nodeIntegration: false`,
and `sandbox` enabled; only the preload API is exposed.
- Description HTML is sanitized against an allowlist on save and again on
render and export (`core/sanitize.js`).

## Workflow
## Tests and CI

1. Change core/exporter logic together with its workflow tests in
`tests/unit/`.
2. Put shell checks in `tests/checks/` so the shared runner picks them up.
3. Run `bash tests/run_test.sh` locally.
4. Open a pull request linked to an issue; CI runs the same suite.

The full process is in [CONTRIBUTING.md](CONTRIBUTING.md).
CI is `.github/workflows/ci.yml`. The runner accepts repeatable
`--skip test_name.sh` options for checks delegated to other jobs; an unknown
name fails before any check runs. Fedora CI delegates the Debian release
build to the pinned Ubuntu package job and units to the Linux/Windows unit
jobs. Ubuntu builds the Debian package once while verifying the release
report and sample manifest, then uploads those same artifacts. Locally, the
default command still runs the complete suite.

The Fedora build-deps installer includes Electron's system libraries for
repository checks. Its optional `--rpm-only` argument omits `dpkg` for jobs
that do not build Debian artifacts; contributor setup includes it by default.

Fedora CI builds test RPMs with `STEPFORGE_RPM_FAST=1`, selecting level-3
Zstandard compression with two threads. These packages contain the same
runtime files but can be larger. Normal RPM builds retain the distro's
compression defaults. A small real-RPM fixture checks both compression paths
on every Fedora PR run.

The full contributor process is in [CONTRIBUTING.md](CONTRIBUTING.md).
Loading
Loading