Skip to content

Releases: impressiver/snitt

Snitt 0.8.0

Choose a tag to compare

@impressiver impressiver released this 20 Sep 23:26
Immutable release. Only release title and notes can be modified.
19e8128

What's Changed

  • fix(release): narrow the one unreviewed push to the two files it needs by @impressiver in #191
  • chore(scripts): resolve bash through env, not /bin by @impressiver in #192
  • fix(build): stop a test deleting the developer's built app by @impressiver in #193
  • fix(tests): do not mistake the checkout path for a linked library by @impressiver in #194
  • deps: bump github.com/sparkle-project/sparkle from 2.9.6 to 2.10.0 by @dependabot[bot] in #170
  • fix(build): survive a dependency bump by @impressiver in #195
  • fix(build): compare each product against the sources it actually compiles by @impressiver in #198
  • docs(spec): one writer for a recording, and an agent that drives the editor by @impressiver in #197
  • fix(agent): refuse an edit to a recording open in the editor (W4) by @impressiver in #200
  • fix(test): assert the presentation span, not a frame count that stood in for it by @impressiver in #204
  • feat(agent): let an agent drive Snitt's own editor (D109 + W7) by @impressiver in #201
  • feat(editor): a lane only for an audio source that was actually captured (D110) by @impressiver in #206
  • feat(editor): the titlebar is a real NSToolbar (D97, half of #161) by @impressiver in #209
  • fix(editor): the scroll indicator follows the timeline it describes by @impressiver in #211
  • release: 0.8.0 by @impressiver in #212

Full Changelog: v0.7.0...v0.8.0

Snitt 0.7.0

Choose a tag to compare

@impressiver impressiver released this 19 Sep 21:23
Immutable release. Only release title and notes can be modified.
ea6f220

What's Changed

  • docs(plans): audit the agent API, and the work it implies by @impressiver in #178
  • fix(mcp): refuse string booleans everywhere, and file agent recordings with git context by @impressiver in #179
  • feat(mcp): give tool results a machine-readable half (D103) by @impressiver in #180
  • feat(mcp): let an agent actually see the frame it recorded by @impressiver in #181
  • fix(gate): give each checkout its own test logs by @impressiver in #186
  • feat(agent-api): three answers instead of one internal_error (D106) by @impressiver in #182
  • feat(agent-api): report dropped vocabulary, and grants before the call (D104) by @impressiver in #183
  • feat(agents): give pixels, tidy in one call, one verb per job (D105) by @impressiver in #184
  • feat(mcp): caption a demo, and write the narration it captions (D107) by @impressiver in #185
  • feat(mcp): let an agent find the recordings it left behind (D108) by @impressiver in #188
  • fix(permissions): spend the explanation only once it is answered by @impressiver in #189
  • release: 0.7.0 by @impressiver in #190

Full Changelog: v0.6.3...v0.7.0

Snitt 0.6.3

Choose a tag to compare

@impressiver impressiver released this 18 Sep 01:31
Immutable release. Only release title and notes can be modified.
f254708

What's Changed

Full Changelog: v0.6.2...v0.6.3

Snitt 0.6.2

Choose a tag to compare

@impressiver impressiver released this 18 Sep 00:59
Immutable release. Only release title and notes can be modified.
c8d3e5b

What's Changed

  • docs(runbook): a locked screen reports the notary credential as missing by @impressiver in #168
  • ci(dependabot): watch Sparkle, which alerts never covered by @impressiver in #169
  • fix(build): releases shipped a stale app binary from a dead product path by @impressiver in #173
  • fix(release): build releases optimised, and bump by the smallest increment by @impressiver in #174
  • release: 0.6.2 by @impressiver in #175

Full Changelog: v0.6.1...v0.6.2

Snitt 0.6.1

Choose a tag to compare

@impressiver impressiver released this 17 Sep 21:54
Immutable release. Only release title and notes can be modified.
2cd7cc9

What's Changed

Full Changelog: v0.6.0...v0.6.1

Snitt 0.6.0

Choose a tag to compare

@impressiver impressiver released this 17 Sep 06:00
Immutable release. Only release title and notes can be modified.
b7f81db

What's Changed

  • fix(appcast): emit the build number Sparkle compares, not the marketing version by @impressiver in #126
  • chore(oss): prepare the repository to go public by @impressiver in #127
  • fix(settings): even the divider margins; move "Export for" into the sheet by @impressiver in #128
  • feat(editor): record a voiceover after the fact, anchored to the footage (D93) by @impressiver in #129
  • feat(import): open plain video as a Snitt document, and save it somewhere by @impressiver in #130
  • test(capture): stop asserting an equivalence the platform never promised by @impressiver in #131
  • feat(menu): split New, gate it on the clipboard, and take Preview's icon by @impressiver in #132
  • fix(editor): show that a voiceover is recording, and let the fader reach silence by @impressiver in #133
  • fix(voiceover): reach the export mix, and show the lane on older documents by @impressiver in #134
  • docs(spec): record the CLA → DCO change as D98, and what M8 actually costs by @impressiver in #135
  • feat(transcript): narrate into the transcript, in its own colour, hidden when muted by @impressiver in #136
  • fix(timeline): colour the voiceover lane like its words, and sync the zoom control by @impressiver in #137
  • fix(timeline): one colour per track, and lanes in the order the file has them by @impressiver in #138
  • fix(subtitles): one voice per caption, two lines when they overlap by @impressiver in #139
  • fix(transcript): one voice per row, in the pane and on the phrase lane by @impressiver in #140
  • docs(licensing): retire the CLA for a DCO plus an Apache-2.0 grant (D98) by @impressiver in #141
  • fix(transcript): stop rows overlapping, and put the timestamp back on line one by @impressiver in #143
  • feat(transcript): write narration with +, and delete by keystroke (D100) by @impressiver in #144
  • feat(editor): open the transcript section when the recording has words by @impressiver in #145
  • fix(transcript): make the + actually open the narration field by @impressiver in #146
  • feat(audio): a take over-dubs the microphone; the third track is for synthesis (D102) by @impressiver in #147
  • feat(transport): a record button, a count-in, and a pause that keeps the take by @impressiver in #148
  • fix: restore the test gate on Xcode 27, and pre-public sweep by @impressiver in #150
  • fix(build): make the sources compile on both toolchains by @impressiver in #151
  • chore(gate): build with warnings-as-errors, the way CI does by @impressiver in #152
  • docs(ci): count the test-target warnings instead of remembering them by @impressiver in #153
  • fix(tests): declare the actor isolation, and gate the whole package by @impressiver in #154
  • release: 0.6.0 by @impressiver in #155
  • fix(release): the appcast/app build-number guard could never run by @impressiver in #156

Full Changelog: v0.5.0...v0.6.0

Snitt 0.5.0

Choose a tag to compare

@impressiver impressiver released this 14 Sep 06:31

What's Changed

  • fix(release): split the version keys, and leave main on the next version by @impressiver in #101
  • fix(automation): identify the caller on the socket, and gate reading recordings by @impressiver in #102
  • feat(export): copy the samples when nothing would change a pixel by @impressiver in #103
  • feat(editor): say why a transcript is empty, instead of showing nothing by @impressiver in #104
  • feat(transcription): move to SpeechAnalyzer, and delete the workaround it replaces by @impressiver in #105
  • feat(export): Export for a destination, and Share by @impressiver in #106
  • docs(spec): record on-device auto-titling as D94, deferred after measurement by @impressiver in #107
  • feat(overlay): the timing model for captions and marker banners, and a shared brand package by @impressiver in #109
  • feat(editor): preview captions and marker banners, on Playback ▸ Show by @impressiver in #111
  • feat(export): burn captions and marker banners into mp4 and GIF by @impressiver in #112
  • fix(timeline): make folds and cut lines selectable, so Delete can remove them by @impressiver in #113
  • fix(export): bound GIF dimensions, and give the sheet an Overlays section by @impressiver in #114
  • docs(spec): record unattended agent recording (D95) and GIF size estimation (D96) by @impressiver in #115
  • feat(consent): let an agent record unattended, on a grant that expires (D95) by @impressiver in #116
  • refactor(settings): group the Settings window, and name three settings honestly by @impressiver in #125
  • fix(markers): make a marker-pane click show the marker, and show it at once by @impressiver in #118
  • fix(transport): navigate marks from where a seek is going, not a stale clock by @impressiver in #119
  • fix(timeline): let a phrase click select the utterance, and stop it re-seeking by @impressiver in #120
  • feat(transcript): put the transcript in the left rail, as a timed phrase list by @impressiver in #121
  • fix(share): make File ▸ Share a submenu that opens instantly, like QuickTime's by @impressiver in #122
  • feat(editor): make the side panel a right-hand accordion, and un-lag word clicks by @impressiver in #123
  • test(diagnostics): wait for the log entry instead of racing it by @impressiver in #124

Full Changelog: v0.4.0...v0.5.0

Snitt 0.4.0

Choose a tag to compare

@impressiver impressiver released this 11 Sep 22:25
1c59ad8

What's Changed

  • Prove the notary credential; untrack appcast.xml by @impressiver in #87
  • Filmstrip test: assert luma spread, not first-versus-last by @impressiver in #88
  • docs(spec): the rev 5 UI spec — brand tokens, style sheet, 14 fleet work items by @impressiver in #89
  • feat(ui): one brand palette, and every surface that owned a colour forwards to it by @impressiver in #90
  • feat(ui): the recolour batch — transport, export sheet, settings, rail, menu bar by @impressiver in #91
  • feat(timeline): the geometry cluster — cuts as seams, segmented waveform, branded ladder, words lane by @impressiver in #92
  • feat(editor): the toolbar is the titlebar by @impressiver in #93
  • feat(icon): the mark, re-rendered for macOS 26+ by @impressiver in #94
  • feat(ui): the polish sweep, and the item the PR table lost by @impressiver in #95
  • fix: ten defects reported from use, plus open-on-launch and the finished HUD by @impressiver in #96
  • fix(tests): make the test gates safe under parallel execution by @impressiver in #97
  • feat: make clicks actually show — capture their positions (D64), and a Playback ▸ Show Clicks toggle by @impressiver in #98
  • fix(menu): trim the status menu, restore its divider, and bind Show Clicks to ⇧⌘C by @impressiver in #99
  • release: 0.4.0 by @impressiver in #100

Full Changelog: v0.3.0...v0.4.0

Snitt 0.3.0

Choose a tag to compare

@impressiver impressiver released this 10 Sep 22:10
1bcbc40

What's Changed

  • feat(release): ship a DMG installer alongside the update zip by @impressiver in #64
  • feat(export): choose a resolution, with its size ceiling, before exporting by @impressiver in #65
  • feat(hud): a floating recording HUD, and a human pause to go with it by @impressiver in #66
  • feat(editor): the timeline gets a budget, so the picture stops paying for it by @impressiver in #67
  • feat(editor): one transport, one shortcut registry, and marks you can step to by @impressiver in #68
  • fix(timeline): folds get a lane and a y-gate, markers get their 24pt back by @impressiver in #69
  • feat(a11y): make the timeline reachable without a pointer by @impressiver in #70
  • feat(editor): chrome follows the appearance, media surfaces do not by @impressiver in #71
  • feat(editor): transcript behind a toggle, and the word lane's tiers measured by @impressiver in #72
  • feat(timeline): a phrase-grouped transcript lane (D89) by @impressiver in #73
  • fix(timeline): halve the filmstrip's share, grow the transcript lane, drop its fill by @impressiver in #74
  • feat(editor): build the chrome the design asked for by @impressiver in #75
  • fix(editor): halve the filmstrip again, legible centred phrases, an adaptive well by @impressiver in #76
  • feat(editor): a digital VU ladder beside each audio lane by @impressiver in #77
  • fix(timeline): the filmstrip was never actually shrinking, and three UI fixes by @impressiver in #78
  • feat(timeline): marker double-click, fold expand-and-select, "Markers" everywhere by @impressiver in #79
  • fix(timeline): lanes take what they need, and fixture names stop colliding by @impressiver in #80
  • fix(timeline): restore right-click Remove Cut, and make Delete mean both edits by @impressiver in #81
  • test: fix the coordinate bug behind three test failures, add a gesture matrix by @impressiver in #82
  • feat(editor): resizable remembered panes, and a scrollable zoomed timeline by @impressiver in #83
  • Replace the export save panel with a designed sheet by @impressiver in #84
  • Release script: publish, then verify the assets landed by @impressiver in #85
  • Preflight: check credentials by asking the scripts that own them by @impressiver in #86

Full Changelog: v0.2.0...v0.3.0

Snitt 0.2.0

Choose a tag to compare

@impressiver impressiver released this 10 Sep 00:21
aa5e548

Snitt 0.2.0

v0.1.0 could record a window and trim it. 0.2.0 is where Snitt became an editor —
123 commits, 304 files, +28,013 lines — plus on-device transcription, a real agent
surface, and an open-source licence.

Universal (arm64 + x86_64), signed with Developer ID, notarized and stapled.

The editor

The timeline stopped being a scrub bar.

  • Waveforms and a filmstrip in every track — log-scale, with clipping marks, one
    band per audio source. Dark surface, orange waveform.
  • Per-track gain and mute, applied live in the preview and honoured by the export
    mix.
  • Crop as a bounding box you drag and adjust before committing — nothing reaches
    the edit until you press Apply.
  • Auto-deep-trim: cut the spans where nothing happens, with presets and the
    criteria behind them stated. An automatic fold says what it removed.
  • Expanded folds insert space, so the playhead skips them instead of walking
    through footage that isn't there.
  • A chapter panel for markers, with typed times and drag-to-move.
  • Transport: rewind, scrub-stops-playback, zoom and snapping with on-screen
    controls.
  • Opens centred at 75% of the screen.

Transcription — on device, and editable

Runs on your Mac with Apple's recognizer. The audio never leaves the machine.

  • The transcript is an editing surface: click a word to jump there, select a phrase
    and delete it to cut those seconds.
  • Correct a word in place — double-click, type, done.
  • Tell it what to expect. A recording carries a vocabulary of the symbol names,
    file names and product names a general speech model has never heard, and
    re-transcribes against them.
  • The spoken word highlights as playback reaches it, and the transcript breaks into
    lines at the speaker's own pauses.
  • Confidence is rendered, not hidden — a word the recognizer doubted looks doubted.
  • Marker transcripts export as WebVTT subtitles.

Agents

  • snitt_auto_deep_trim, snitt crop, pause/resume, and screenshot-the-recording over
    both MCP and the CLI.
  • snitt setup registers the MCP server with agent hosts.
  • Snitt starts on demand when a client finds it closed.
  • A client can report input the OS never saw — an agent's synthetic keystrokes and
    clicks land in the event log as content-free beats, and clicks can be drawn on the
    exported video.
  • Agent-initiated recordings disclose themselves in the UI.

Capture and export

  • Pause and resume a recording, from the menu bar or over the agent surface; a
    paused recording looks distinctly paused.
  • Microphone recording from the GUI, with a warning when your speakers will bleed
    into the mic.
  • A configurable save destination.
  • Customizable hotkeys for record and marker.
  • Export gained a resolution knob and a pre-flight menu that prices every option
    before you commit to one.
  • .snitt bundles get a Finder icon drawn from the recording itself.

The project

  • Licensed MPL-2.0, with a contributor agreement — file-level copyleft, so a
    commercial competitor cannot take the code closed, and GPL-compatible.
  • A README, a spec conformance pass, and CI.

Notable fixes

  • Clicking a transcript word highlighted the word before it — intermittently. The
    seek target quantizes to 1/600s, landing up to 0.8ms before the word's start, so
    the previous word won the lookup whenever a word's start time rounded down.
  • The Settings window was released out from under itself — a use-after-free that
    crashed shipped v0.1.0 when you toggled "Log input events".
  • Timeline gestures were interpreted on the wrong axis after the view moved to
    output time.
  • Transcription only covered the tail of a recording; it now runs per utterance.
  • Silence detection measures against the 90th percentile, not the max, so one loud
    moment no longer makes a quiet recording read as busy.
  • snitt trim discarded existing cuts instead of preserving them.
  • Adjusting gain no longer resets the playhead to the start.
  • events.json now guards its schemaVersion, like edit.json.

Upgrading

edit.json and events.json from v0.1.0 open unchanged — there is a pinned test
against a real captured v0.1.0 bundle, including the read-then-save path.

Existing installs with automatic checks enabled will be offered this build by Sparkle.
Updates are verified three ways before they install: TLS to github.com, the Developer ID
signature, and an EdDSA signature over the archive.