Commit Graph
25 Commits
Author SHA1 Message Date
TylerandClaude Sonnet 4.6 d244626583 ai smart auto-documentation and text rewrite
- Store captureMetadata (OCR text, window/app/element info) with each
  step at capture time so AI always has the original rich context.
- Add buildCaptureContext() to TextIntelService; capture.js uses it
  instead of buildCaptureTitle() so both title and metadata come from
  one pass.
- generateStepPatch() prefers stored captureMetadata over re-running
  OCR, giving the AI the best possible context when the user clicks
  an AI button later.
- Add autoDoc setting: when enabled every capture (shoot, region, and
  session hotkey/click) is automatically documented by AI. Manual
  captures await AI before returning; session captures fire-and-forget
  and push a step:updated event so the renderer reloads seamlessly.
- Add ai:rewriteText IPC and rewriteText() method for plain-text
  polishing via a separate callOllamaText() that skips JSON mode.
- Add "AI Rewrite" section in the editor right panel: textarea + AI
  button that rewrites whatever the user types in place.
- Improve buildAiPrompt() rules: action-focused title instructions,
  explicit anti-junk rules (no "Capture the screen / OCR" blocks),
  and a context-quality gate that suppresses blocks when context is
  thin.
- Add autoDoc checkbox to AI settings dialog.
- Renderer handles step:updated to reload the selected step after
  background auto-doc finishes.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-24 09:17:31 -05:00
Tyler 375c14b028 prefer OCR for capture titles 2026-06-24 08:55:19 -05:00
Tyler 33eb0f745e semantic titles ai assist 2026-06-23 17:46:33 -05:00
Tyler 8cc1ba3532 Add Wiki.js markdown export option 2026-06-15 13:59:04 -05:00
Tyler b51a4c46ce Make PDF Contents entries clickable links to each step's page
Adds PdfBuilder.linkRect() for /Subtype /Link annotations with a
/Dest pointing at another page's destination. TOC entries record a
target placeholder that the per-step loop fills in once it knows
which page the step landed on, so clicking a Contents line jumps the
reader straight to that step.
2026-06-15 13:22:51 -05:00
TylerandClaude Sonnet 4.6 0b490e2aa9 Add guide metadata, redesign PDF cover, paginate steps per-page, and run exports in a helper process
Lets users record author/co-authors/organization for a guide via a new
"Guide information…" dialog; this metadata renders below the title on
the PDF cover (title now sits above the accent rule). PDF export also
paginates so each step fits its own page where possible, keeps a
step's title/image/lead-in together, and forces the next step onto a
fresh page after an oversized step overflows. Exports now run in a
forked helper process so large guides no longer freeze the UI.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-15 12:54:31 -05:00
Tyler 58b4182c54 Add global undo for step deletion; simplify capture session UI
Template tests / tests (push) Successful in 1m41s
Template tests / tests (pull_request) Successful in 1m39s
- The canvas Undo/Redo buttons now also undo/redo step deletion
  (single or multi-select), restoring the step's data, images, and
  position in the order. Backed by a new step:restore IPC call and
  GuideStore.restoreStep().
- Remove "Finish capture session" from the capture menu. The
  top-right recording bar in the guide editor is now the only place
  to start/stop recording, with its toggle relabeled
  "Start recording" / "Stop recording".
2026-06-15 10:15:15 -05:00
TylerandClaude Sonnet 4.6 f094bbbd73 Fix inflated word spacing in PDF description text
Template tests / tests (push) Successful in 1m39s
Template tests / tests (pull_request) Successful in 1m40s
writeDescription/emitBlocks rendered each word as a separately positioned
Tj, advancing by our approximate average-glyph-width estimate — which is
much wider than real space/character widths, producing "This  is  bold"
style gaps. Render each line as one continuous text object instead
(PdfBuilder.textRun), so consecutive Tj operators advance using the
viewer's real font metrics.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-13 21:42:26 -05:00
TylerandClaude Sonnet 4.6 0ead121327 Render rich text, links, and special characters correctly in PDF exports
Template tests / tests (push) Successful in 1m40s
Template tests / tests (pull_request) Successful in 1m39s
PDF exports now preserve bold/italic/links/lists/blockquotes from the
description editor (via a new HTML block/run parser) instead of flattening
to plain text. Literal "[text](url)" links inserted by the editor's Link
button are converted to real <a> tags before rendering. Tabs and common
"smart typography" characters (smart quotes, dashes, ellipsis, bullet) are
mapped to their WinAnsiEncoding glyphs instead of rendering as "?".

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-13 21:35:55 -05:00
TylerandClaude Sonnet 4.6 602e70a7e1 Linearize focused-view pan to the available range and flip Pan Y
Template tests / tests (push) Successful in 1m39s
Template tests / tests (pull_request) Successful in 1m39s
panX/panY now represent 0..1 fractions of the pannable range rather
than absolute image positions, so the slider's full travel always
covers edge-to-edge regardless of zoom level. Pan Y is inverted so
sliding right moves the view up. Updated both the editor canvas and
core/raster.js export so they stay in sync.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-13 18:21:00 -05:00
Iisyourdad f88ff0259e Fix guide editor issues 4-10
Template tests / tests (pull_request) Has been cancelled
Template tests / tests (push) Has been cancelled
2026-06-12 11:07:57 -05:00
IisyourdadandClaude Fable 5 3d0b753205 Add a 200ms click debounce with extensive behavioral tests
Template tests / tests (push) Successful in 2m1s
Template tests / tests (pull_request) Successful in 1m50s
Per request: clicks of the same button closer together than
capture.clickDebounceMs (default 200ms) now collapse into a single step, so
accidental fast/double clicks don't each become a step. It is a leading-edge
debounce measured from the last *accepted* click, so a run of fast clicks
can't push the next deliberate click out — two clicks spaced beyond the
window (e.g. the reported 400-500ms apart) always register.

Replaces the prior 8ms duplicate-delivery suppression (subsumed by the
window). Configurable; 0 captures every click.

Tests (the point of this change is that it can't silently regress):
- 13 behavioral unit tests in capture.test.js that drive real onOsClick
  calls with controlled timestamps and assert which clicks survive — the
  reported 400/450/500ms cases, sub-window collapse, the 200ms boundary,
  per-button independence, configurability, debounce=0, last-accepted (not
  last-dropped) reference, session reset, and a full onOsClick -> queue ->
  store integration check. No keyword/comment assertions.
- A fourth end-to-end self-test scenario (burst of 40ms clicks collapses to
  1; three 300ms-apart clicks each register => 4 total). The marker/drain
  scenarios set debounce to 0 so they keep stressing the frame pipeline.

147 unit tests + all repo checks pass.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 09:02:51 -05:00
IisyourdadandClaude Fable 5 0ab29e4ff0 Warm the frame recorder before hiding the window at recording start
Template tests / tests (push) Successful in 1m52s
Template tests / tests (pull_request) Successful in 1m46s
The first screenshot of a session was late while every later one was fine.
Cause: on 'Start recording' the window hid first and the capture backend
started warming up after — creating worker, getUserMedia, first frame takes
~1s. A click in that gap found no buffered frame and took the post-click
fresh shot.

armRecording() now warms the recorder while the window is still visible and
only hides once frames are buffering (with a brief post-hide settle so the
first frame shows the user's screen, not the dismissed app window). Verified
end to end with a new self-test scenario that clicks 250ms after start: the
first click is now served a pre-click frame instead of a post-click shot.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 08:48:54 -05:00
IisyourdadandClaude Fable 5 5b89b5c927 Capture the screen slightly before each click; record milestone in CHANGELOG
Template tests / tests (push) Successful in 1m58s
Template tests / tests (pull_request) Successful in 1m47s
Real-world recording now saves every click with exact markers; the only
remaining nit was screenshots feeling a touch late. Add a configurable
click-lead (capture.clickLeadMs, default 120ms) that targets the screen
just before the hook timestamp, and tighten the stream sampling cadence to
50ms so a frame near that target always exists. Verified end to end: frames
now land ~120-160ms before the click (was 25-57ms), markers stay at 0.00%
offset, and the 8-click burst still saves all 8.

Also document the milestone in docs/CHANGELOG.md and remove an accidental
paste of Gitea commit-page text from it.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 08:12:13 -05:00
IisyourdadandClaude Fable 5 a0b69f8cc7 Rearchitect click capture: strict click-time frames, off-main-process recorder, exact marker coordinates
Template tests / tests (push) Successful in 1m50s
Implements the architecture change from ai_prompts/prompt3.md:

- New app/click-frames.js: shared timestamped frame ring + strict
  click-to-frame pairing (never a frame whose grab started after the
  click); legacy slack behavior kept behind capture.strictClickFrames=false.
- New stream capture backend (app/stream-backend.js + hidden worker
  window): per-display desktop media streams sampled into ring buffers
  and PNG-encoded entirely off the main process, so click delivery is
  never starved by capture work. Auto-degrades to the legacy in-process
  frame loop when streams cannot start or the worker stops answering.
- Clicks are paired with their frame at event time (eager pairing in
  enqueueClickCapture); only the storing is serialized, so slow encodes
  cannot skew later clicks in a fast burst.
- Linux watcher: restored event-time root coordinates from
  xinput test-xi2 and merge raw/regular twin events structurally.
- Replaced the 40ms time debounce with source-aware duplicate
  suppression: fast legitimate clicks are never dropped.
- New app/coords.js: physical-to-DIP conversion with multi-monitor and
  scale-factor handling; Windows keeps screenToDipPoint.
- STEPFORGE_CLICK_SELFTEST end-to-end hook: 3/3 clicks become steps via
  the stream backend with 0.00% marker offset on this host.
- Tests rewritten/added: strict selection, coords, stream backend,
  Linux coordinate parsing, twin merge, burst clicking (126 passing).

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-11 21:33:31 -05:00
Iisyourdad 33c421b746 Added select button toggle for trash library grid
Template tests / tests (push) Successful in 2m0s
2026-06-11 11:31:58 -05:00
Iisyourdad 572b66650b Fix settings button on library view
Template tests / tests (push) Failing after 46s
2026-06-11 10:47:32 -05:00
Iisyourdad dca3e042f2 Cleanup
Template tests / tests (push) Successful in 1m48s
2026-06-11 09:44:52 -05:00
IisyourdadandClaude Fable 5 52fd516a5d Make capture sessions continuous: click-capture + interval auto-capture
Template tests / tests (push) Failing after 29s
The session previously only listened for the global hotkey, which is
unreliable under WSLg/Wayland — users got one screenshot and nothing
more. Sessions now layer three triggers:

- click-capture via OS adapters (xinput test-xi2 on X11, PowerShell
  GetAsyncKeyState polling on Windows), debounced, ignoring clicks on
  StepForge itself
- interval auto-capture (3/5/10 s) as the always-works fallback,
  enabled by default when click detection is unavailable
- the existing global hotkey, plus a manual Shoot button

The REC bar now shows live count + active trigger with Shoot / Auto /
Pause / Finish. New captures and added steps are selected in the
editor (explicit reload(stepId) wins over a surviving selection).
Capture self-test hook (STEPFORGE_CAPTURE_SELFTEST) verifies 3x
hotkey-path captures and interval capture end-to-end.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 22:33:12 -05:00
IisyourdadandClaude Fable 5 a5bbdde480 Add binary exporters and template manager
Template tests / tests (push) Failing after 52s
- Native PDF exporter (cover, TOC, bookmarks, images, code, tables,
  text blocks); validated under Ghostscript
- Animated GIF exporter (title card, title overlay, progress bar)
- Image bundle exporter with watermark compositing
- DOCX and PPTX emitters (hand-built OOXML over our zip writer) with
  structural + relationship + XML well-formedness validation in tests
- Per-format template manager with .sfglt share archives
- Unified export dispatcher covering all nine formats
- 10 more workflow tests (52 total)

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 16:59:19 -05:00
IisyourdadandClaude Fable 5 ca73db68e3 Add Render AST and text exporters: JSON, Markdown, HTML simple/rich
- Render AST: placeholder expansion, hierarchical numbering (1, 1.1),
  hidden/skipped filtering, preview step limit, annotated image rendering
- JSON exporter with sidecar annotated PNGs
- Markdown exporter: TOC with resolving anchors, text blocks as
  blockquotes, fenced code, tables, Azure-wiki image sizing option
- Self-contained HTML exporters (data-URI images, zero external refs);
  rich variant adds floating TOC, checkboxes, localStorage progress
- HTML->Markdown converter for the sanitizer-allowed tag set
- 7 exporter workflow tests (42 total)

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 16:53:23 -05:00
IisyourdadandClaude Fable 5 b7e64c79b4 Add imaging/document primitives: PNG codec, rasterizer, GIF, PDF
- Pure-JS PNG decode (grey/RGB/palette/alpha) + RGBA encode, CRC-checked;
  decode verified byte-identical with ImageMagick
- Software rasterizer: shapes, arrows, blur, highlight, magnify, tooltip,
  number badges, cursor, bitmap text (vendored public-domain font8x8),
  crop/resize, focused-view rendering
- GIF89a encoder with LZW (cross-validated pixel-for-pixel against
  ImageMagick decode) + NETSCAPE looping
- Minimal PDF 1.4 writer: pages, fonts, rects, images, outlines, valid
  xref; rendering validated under Ghostscript
- 12 imaging workflow tests (35 total)

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 16:48:57 -05:00
IisyourdadandClaude Fable 5 0edcc38886 Add full-text search index over guides, steps, blocks, and placeholders
Pure-JS inverted index persisted under library/index/ (documented FTS5
fallback). AND queries, last-token prefix matching, title boosting,
step deep-links, snippets. 4 workflow tests (23 total).

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 16:39:49 -05:00
IisyourdadandClaude Fable 5 3c51cf6f81 Add archive layer: zip, .sfgz share files, locks, snapshots
- Hand-rolled ZIP writer/reader (node:zlib only) with CRC verification,
  UTF-8 names, store/deflate, path-traversal validation; verified
  interoperable with system unzip
- .sfgz guide archives: export, copy-import (fresh ids, remapped
  substeps), linked-import with explicit write-back save
- Advisory .lock-sfgz sidecar locks with stale detection and force-steal
- Snapshot backups with pruning and undoable restore
- 7 more workflow tests (19 total)

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 16:38:30 -05:00
IisyourdadandClaude Fable 5 2a602d7477 Add core domain layer: schema, store, sanitizer, placeholders, settings
- Folder-based GuideStore with atomic writes, trash/restore, duplicate,
  substep reparenting, folders/favorites, working-image crop/reset
- Allowlist HTML sanitizer applied on every store write
- Placeholder scopes (guide > global > system) and collection
- Persisted app settings with deep default merge
- 16 workflow tests exercising real on-disk round-trips

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 16:34:15 -05:00