TylerandClaude Fable 5 8aa9756b8a
Template tests / tests (pull_request) Failing after 33s
Harden archives, snapshots, locks, and search against corruption and races
Phase 1/2 of the improvement plan (PR 6 of the sequence). Recovery and
resource-limit hardening for the storage-adjacent modules.

ZIP resource limits (core/zip.js):
- unzipSync now enforces entry-count, total compressed, total inflated, and
  per-entry inflated budgets, and caps inflation with inflateRawSync
  maxOutputLength so a deflate bomb can't exhaust memory. Exact inflated-size
  match (not "at least") and CRC verification are kept. Import uses the
  default limits.

Transactional archive import (core/archive.js):
- The import validates the guide AND every step before writing anything, then
  stages the whole guide in a temp directory and publishes it with a single
  atomic rename. A corrupt step no longer leaves a partial guide in the
  library; a failure cleans up the staging directory.

Atomic snapshot restore (core/snapshots.js):
- Restore extracts and validates into a temp directory first; only then does
  it swap content in, moving live content aside so a mid-swap failure rolls
  back. A corrupt/truncated snapshot can no longer destroy the live guide
  (the old restore deleted live content before extracting).
- Fixed snapshot filename collisions: names kept milliseconds so two backups
  in the same second no longer overwrite each other.

Automatic backups (core/snapshots.js):
- Implemented the previously-dead backups.automatic/everyNSaves/keepLast
  settings: autoSnapshotIfDue snapshots every N saves and prunes to keepLast,
  wired into the save choke point in main.js. Never throws — a backup failure
  cannot break the save that triggered it.

Exclusive locks (core/locks.js):
- acquireLock uses O_CREAT|O_EXCL (flag 'wx') so only one writer wins the
  race; the old read-then-write left a window where two writers both believed
  they held the lock. Added a per-acquisition token so release only removes
  the exact lock it took (never one a force-steal replaced). Same-process
  re-acquire still succeeds; cross-process fresh locks conflict.

Search reconciliation (core/search.js):
- New reconcile(store) rebuilds/repairs the index against the library at
  startup using per-guide fingerprints (updatedAt+revision): reindexes new/
  changed guides, drops entries for deleted ones, and exposes a recovery
  status ('ok'|'reset'|'reconciled'). A missing/corrupt/version-mismatched
  index recovers instead of silently returning nothing. Wired into startup.

Recovery surface:
- New recovery:status IPC + preload method returns quarantined files (this
  session) and the search index status so the UI can surface data issues.

Tests: ZIP bomb/limits, transactional import abort with no partial guide,
atomic snapshot restore preserving the live guide on corruption, exclusive
lock conflict/steal/release-by-token, same-process re-acquire, search
reconcile (rebuild/drop/reindex/corrupt-reset), and automatic backup
cadence/pruning. 255 unit tests pass; startup smoke and workflow E2E pass.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-03 23:10:21 -05:00
2026-06-11 16:57:59 -05:00
2026-06-11 16:57:59 -05:00

StepForge

StepForge is a local-first, open-source desktop app for Windows, with Linux (WIP) builds. It captures step-by-step workflows as screenshots, lets you annotate and describe each step in a focused three-pane editor, and exports the result to Markdown, DOCX, PPTX, PDF, HTML (WIP), GIF (WIP), confluence (WIP), Wiki.js (WIP), and image bundles (WIP). The current reconmendations for exporting is Markdown and PDF.

It is an independent desktop guide-capture tool inspired by publicly documented workflow patterns of commercial documentation tools like Folge. It contains no third-party branding, assets, or code from those tools.

Network and privacy contract. StepForge has no telemetry, no update checks, no license checks, and no cloud. Guides never leave your machine on their own. The only outbound network feature is the optional AI integration: when you enable it and configure an Ollama endpoint, StepForge sends step screenshots and text to that endpoint to generate titles and descriptions. By default that endpoint must be local (loopback); sending data to a remote host requires the explicit "Allow remote AI host" opt-in. See docs/PRIVACY.md for exactly what is collected and sent. Note that OCR (Tesseract) and its English language data are bundled production dependencies — Electron is not the only one.

Overview

The core workflow:

  1. Capture — take full-screen, active-window, or region screenshots with configurable delay, pause/resume, and global hotkeys; or import images and paste from the clipboard.
  2. Annotate — rectangles, ovals, lines, arrows, text, tooltips, numbered markers, blur, highlight, magnify, and crop on a resolution-independent annotation scene graph.
  3. Describe — rich-text titles and descriptions, informational text blocks, code blocks, tables, step links, and placeholders.
  4. Export — every exporter renders from the same normalized Render AST, so output is deterministic across formats.

What's Included

  • Guide library with folders, favorites, title search, full-text search, duplicate/move/delete, and a quick-actions palette (Ctrl+/).
  • Capture engine — the editor's Capture ▾ button offers full screen, active window, and region capture (the app hides itself during the shot), plus continuous capture sessions that grab a step on every click where the OS allows it, or on a 3/5/10 s auto-interval everywhere else. The REC bar shows the live count and the start/pause control. Delay, global hotkeys, click markers, clipboard paste, and PNG/JPEG/GIF import included. The full keyboard shortcut list lives under More ▾ → Keyboard shortcuts in the editor.
  • Three-pane editor — step tree with substeps, statuses (todo/in-progress/done), hidden/skipped steps, focused view (zoom/pan that never mutates the original image), autosave, and command-stack undo/redo.
  • Annotation canvas — normalized JSON scene graph with resolution-independent coordinates; annotations render identically in the editor and in every exporter.
  • Sharing & backups — single-file .sfgz archives (zip-based, path- traversal validated), linked guides with .lock-sfgz lock files and explicit save, plus automated snapshot backups and restore.
  • Exports — JSON, Markdown, Simple HTML, Rich HTML (checkboxes + floating TOC), PDF, animated GIF, image bundle, DOCX, and PPTX, with per-format export templates shareable as .sfglt files.
  • Settings & theming — system/light/dark themes, capture options, keyboard shortcuts, preview step count.

Everything except the Electron shell is dependency-free Node.js: the ZIP, PNG, GIF, PDF, DOCX, and PPTX writers are all implemented in this repository using only Node built-ins.

Getting Started

For a Windows installation, see docs/windows_installation or for a developer/more in depth walkthrough, see docs/GETTING_STARTED.md.

On Linux (⚠️ work in progress — X11 vs Wayland, enabling per-click capture, the screen-share prompt), see docs/GETTING_STARTED_WITH_LINUX.md.

Requirements: Node.js 22.12+ and npm (pinned in .nvmrc; installs are refused on older Nodes because the packaging toolchain needs 22.12+).

npm ci             # one-time, installs the locked dependency tree
npm start          # launch StepForge

Dependencies are only ever installed by you, via npm ci — the app never downloads or repairs packages at runtime.

First run creates the local data directory (~/.local/share/stepforge on Linux (WIP), %APPDATA%/stepforge on Windows; override with STEPFORGE_DATA_DIR).

Testing

Please create your tests so that when the following is ran it automatically tests your test.

bash tests/run_test.sh

The runner executes every tests/checks/test_*.sh script; those scripts run the workflow test suites under tests/unit/ with node --test. The tests exercise real workflows like creating guides, round-tripping archives, exporting documents, and validating the bytes of the output, not string matching.

Building & Packaging

bash scripts/bootstrap-offline.sh   # verify toolchain availability
bash scripts/verify.sh              # full test suite + smoke checks
bash scripts/build-release.sh       # assemble runnable app directory
bash scripts/package-linux.sh       # local Linux packaging (WIP; not part of release)
npm run package:windows             # Windows installer .exe in releases/
pwsh scripts/package-windows.ps1    # same Windows installer build via PowerShell

See build/build_report.md for what was produced on this machine and which packaging tools were unavailable.

Offline Guarantee

The shipping app makes zero network calls. There is no telemetry, no update check, no license validation, no cloud sync, no account system, and no remote AI. Exports embed no remote fonts or CDN references. See docs/SECURITY.md for the threat model.

Contributing

See docs/CONTRIBUTING.md for the full contribution flow, including the issue-number requirement for every pull request and the clean-room rules.

Repository Layout

Project docs live in docs/ and prompt handoffs live in ai_prompts/.

See docs/ARCHITECTURE.md for the repo layout.

License

Creative Commons Attribution-NonCommercial

Basically, do whatever you want with it just don't make money off it or sell it.

S
Description
No description provided
Readme
24 MiB
Languages
JavaScript 93.5%
Shell 3.8%
CSS 2.1%
NSIS 0.3%
HTML 0.3%