Skip to content

Repository files navigation

keeper

keeper opens a folder of photographs and film and helps you pick the good ones and cut them to the shapes a website or an instagram post needs. it runs on your own computer. it does not need an account and it does not need the internet.

a shoot comes back as 1,768 frames and a website has sixteen holes. every hour between those two numbers goes on scrolling a finder window at 200px a thumbnail, and that is the hour this takes back.

it was written against a photographer's archive and it is not only for photographers. a pile of frames and a handful of holes to fill is the same job whether the pile came off a camera, a phone, a drone or a screen recorder.

keeper can also sort a folder into groups you name, by sending small contact sheets to a model, and that part is off until you turn it on. if you never turn it on, nothing here has changed: no request is made, nothing of yours leaves the folder, and it still runs with the wifi off.

the shelf: a wall of frames, the group
list with its counts down the left, and a search cutting 113 frames to 28

every frame in these shots is a generated stand in. real work does not go in a readme.

get it

everything is on the releases page and there is nothing to install alongside it.

on windows, run the .exe setup and open keeper from the start menu.

on a mac, open terminal and paste these two lines. terminal is in applications, utilities, or hold cmd, press space, and type its name.

curl -L -o ~/Downloads/keeper.tar.gz https://github.com/gntrs/keeper/releases/latest/download/keeper-macos-arm64.tar.gz
tar -xzf ~/Downloads/keeper.tar.gz -C /Applications

keeper is then in your applications folder and opens like anything else. the first line fetches it and the second unpacks it, and you can throw the download away afterwards. that is for an apple silicon mac, which is every mac sold since late 2020. on an older intel mac, arm64 becomes x64 in the first line.

there is a .dmg on that page as well and it holds exactly the same app. it is the familiar way to install something on a mac and it is the one your mac will argue with, which is why it is second here.

your computer will warn you, and here is why. letting a program pass without a warning costs money every year, on each platform, and that money has not been paid. so:

  • windows says it protected your pc. press more info, then run anyway.
  • the mac dmg says the developer cannot be verified. open system settings, go to privacy and security, scroll down, press open anyway. the two lines above do not hit this at all, and the difference is not a trick: a mac marks what a browser downloads and refuses to open it unchecked, and does not mark what you fetched yourself with a command you typed.

if you want to check what you downloaded before you unpack it, run shasum -a 256 ~/Downloads/keeper.tar.gz and compare the answer against the .sha256 file next to the download on the releases page.

you should not take that on trust from a stranger. everything keeper is made of is in this repository, the downloads are built by a script you can read, and every file has a checksum next to it so you can prove the one you downloaded is the one that was built.

the first two minutes

  1. open keeper. it opens in your web browser. that is just how the screen is drawn. nothing is on the internet and the page is coming from your own computer.
  2. drag a folder of photographs onto the page. any folder. keeper opens the folder where it already is and does not copy or move anything.
  3. wait once. keeper makes a small copy of each picture so the page can show hundreds at a time without crawling. a few thousand photographs takes a few minutes. it only ever happens once per folder.
  4. the shelf appears. every photograph in the folder, on one screen, and eight cards walk you round it. they say what the keys do, they run once, and skipping them is fine.

next time you open keeper it opens the same folder again. the question mark in the top corner holds every key and the settings, and the walkthrough is in there if you want it a second time.

picking the good ones

move with the arrow keys. press k to keep the one you are on. press space to see it big.

that is the whole loop, and it is meant to be done with one hand without looking down. a thousand photographs is about twenty minutes this way and an afternoon with a mouse.

delete does not delete. press it and the photograph disappears from the shelf and the file does not move. it goes to keeper's own bin, which is a list, not a folder. you can put it back.

the wall filtered to the bin, thirteen
frames set aside, the bin row lit in the accent

there is one button that really removes a file. it lives inside the bin, it asks first, it tells you how many, and it uses your computer's own delete, so the files land in the trash or the recycle bin and you can still get them back from there.

this is the second version of that and the first one was wrong. delete used to go straight to the trash. putting the fastest key in the app on the one thing you cannot undo is how a tool eats somebody's photographs.

cutting them to shape

instagram wants a tall picture. a youtube thumbnail wants a wide one. a banner across the top of a website wants something wider still. the same photograph does not survive all three, and you cannot tell which ones it survives by looking at it.

so click a photograph and keeper shows it in every shape at once.

the bench: one frame tried on in
instagram's tall post and its square, both at their true proportions, with the
picker strip down the right

drag it into the shape you want, drag inside that box to move the picture, hold option and scroll to zoom in. press export and the cut picture lands in your downloads folder, in a folder called keeper. the original is not touched.

the shapes are already there on the first run: instagram post, square, story and reel, x, youtube thumbnail, link preview, pinterest, and a few sizes of web banner. each one is the size that platform actually wants.

if you zoom in too far, keeper tells you before you export. past a certain point there are not enough pixels left to fill the shape, so somebody else's website would stretch it and it would look soft. keeper compares the two and says so in red.

piles

a pile is what you build while you browse. click photographs into it, keep going, start another one when the subject changes, then export that pile as a real folder of real files you can hand to anyone.

exporting never moves your originals. keeper reads from your folder and writes somewhere else. your folder comes out of it byte for byte identical.

film

clips sit on the same wall as the photographs, with a poster frame cut a third of the way in, because frame one is a lens cap or a whip pan often enough not to be worth trusting.

the posters actually appear now, and they had not in any release from v0.6.1 to v0.8.0. keeper wrote each still to a temp name ending .part, ffmpeg picks what it is writing from the extension, .part is not one of them, and it refused before it decoded a frame. the error then put the tile on the branch that means a file cannot be read, so keeper told people their footage was corrupt when the only broken thing was a filename.

with the sorting below turned on, a clip is grouped like a photograph, off a handful of frames spread across it. that is enough to put it in a group and no use at all for finding the good eleven seconds of a four minute take, which is what moments is for. there is a button under a clip that says find the moments in this clip: keeper finds the real cuts, and what comes back is a row of timestamps you can jump to. it is one clip at a time and never automatic, because it decodes the whole file.

a clip open with its moments underneath as
timestamps, and the one the playhead is inside ringed in the accent

what a clip says is the other half, and it is a separate yes. the frames are enough on their own: "find the moments in this clip" works with no key and nothing sent anywhere, off the frames alone. sound is people talking, whole, so before any of it goes out a card names the service it would go to, says how long the sound is and what it costs, and asks. yes covers this archive until keeper is closed and is never written down. two services are wired, deepgram and assemblyai, each with its own key in this machine's keychain, and a moment that came from the words is marked apart from one that came from the frames, because they are worth different amounts of trust.

film needs ffmpeg and keeper cannot ship it: every static build anybody actually publishes is licensed in a way that does not sit with the licence keeper ships under. so keeper fetches it instead, on the same one yes as the downloads tab, from a github release into its own folder, and never redistributes it.

a copy already on your machine wins. keeper looks on the path first, then in the folders ffmpeg is actually installed into, and only then at the one it fetched. that middle step is there because a mac app opened from the dock inherits a path with almost nothing on it, and the ffmpeg somebody installed themselves is invisible to everything keeper spawns without it. keeper doctor says whether it has one.

sorting it into your own groups

this is off until you turn it on, and with it off keeper is exactly the tool described above. no request is made, nothing leaves your folder, and the wifi test below still passes. if that is the keeper you wanted, the rest of this section is not something you have to opt out of.

with it on, keeper sorts the archive itself, from the analyse tab beside the shelf and the bench.

the analyse tab: nine rows with a name
and a sentence each, the endpoint, and a sort running at sheet 4 of 6

you write the groups. up to nine, each a name and one sentence of what you are looking for. that sentence is not a note for you to read later, it is what the model is told to look for, and there is nowhere else it is told anything. the digits 1 to 9 are those nine groups, and they do not move again for the life of the folder.

nine, and not ten, because a keyboard's number row ends in a 0 that a finger reaching for 9 finds by accident.

there is no fixed vocabulary any more. keeper used to ship sixteen letters meaning portrait, laughing, presenting and food, which described a conference and described nobody else's shoot at all. a wedding has no presenting, a building survey has no laughing, and both have three things that list had no letter for.

then two passes, and only the cheap one runs over everything. the first lays your photographs out as contact sheets, which are big grids of small pictures sized so a machine can still tell one face from another, and every frame comes back in one group or in none of them. the second is the expensive one, so it only runs over the groups you tick, one frame at a time, and it writes a sentence and a few words about each that the search box can then find.

writing a group, sorting, the wall coming
back sorted, and a search narrowing it

if a sheet comes back miscounted, keeper refuses that whole sheet rather than applying it. one bad count would shift every label after it onto the wrong photograph, quietly, which is worse than no labels at all.

what leaves is written on the card before you say yes: the contact sheets, and the group names and sentences you typed. the request carries the instruction that says how to answer along with them, and that is the whole of it: no file names, no folder names, no dates, no location, and never an original. one address, the one you picked, and nothing goes to the other one.

there are two addresses on that card and never both: a model running on your own machine, which is offered first, and the claude api, second.

it says what a run costs before you start it. the line under the buttons reads 126 frames, 6 sheets, about 0.02 dollars, and it counts what is about to be sent rather than the size of the folder, so a folder already sorted answers with the frames nobody has covered yet.

sort again is there for when the groups you wrote turn out to be the wrong groups. it says first, before you press it, that it writes over the group every frame already has, including the ones you put there by hand with the number row. it is off every time the tab is drawn.

changing the list tells you what it will do, with the count, before it does it. delete a group that forty frames are filed under and keeper says so: they keep the digit, they are not untagged, and that digit stops meaning anything until you write a group under it again. rename one and the frames stay where they are and wear the new name. nothing is migrated behind you, and a digit with frames on it and no group written keeps its own row on the shelf, so those frames are still one click away.

you can point it at a model on your own machine. the endpoint is a box you type a url into, so ollama, lm studio and anything else speaking that shape work here without keeper holding a list of them that would go stale. on that setting nothing leaves your machine at all.

and that path is slow, which is said here rather than left to be found out. this readme used to promise tagging without an assistant, and that it would ship only if it could be done locally, for free, and well enough to trust. locally and free are met. the speed is not: the only published number is an m4 max with 128gb of memory spending 1.5 to 4 seconds per picture on the vision encode alone, before the model has thought about any of it, and that is a better machine than most people are sitting at. a couple of thousand frames is most of an hour at the good end of that. so the local path is real, it works, and it is the slow one. the api is the one that answers in minutes and it is the one that sends something.

your key is not written into your archive. it goes in this machine's own keychain, and on a machine with no keychain into a file in keeper's folder that only you can read. a .keeper folder travels with the photographs, onto other drives and into other people's backups, and a credential does not belong in there.

the coding agent path still works, if you would rather use an assistant you already pay for than a key of your own. keeper sheets writes the sheets out, AGENTS.md is the brief you hand the agent along with your own group list, and keeper tag takes the answer back.

finding one again

the search box in the toolbar takes plain words, matched against the file name, the folder, and anything the second pass wrote. it also takes a few prefixes:

date:2026-07     camera:canon     lens:50mm      place:harbour
name:0034        group:3          group:harbour  has:note
has:date         is:kept          is:binned      is:film        is:still

place:"long table" typed in the
search box, cutting 113 frames down to 28

two words mean both of them. quotes hold a phrase together, because place:"long table" is one question and two loose words are not. a prefix keeper does not know is not an error: somebody typing colour:red has said perfectly clearly what they are after, so the word is searched and the prefix is dropped.

the date, the camera and the lens are read out of the file itself, and a file that carries none falls back to its own date on the drive. nothing is written for the search: the rows are built in memory when keeper opens the folder, and built then rather than when you start typing, so the first search is as quick as the tenth.

audio off a link

keeper opens a folder of photographs and film, and a piece of work often needs a piece of music as well. the downloads tab takes a youtube or spotify link and saves what is behind it into a folder you pick.

you choose what it saves as. mp3 because it plays in everything, m4a for the same quality in a smaller file, the original audio with no re-encoding at all, or the video, as an mp4. and how good: max is not a preset, it is whatever that link actually offers, so a 4k source comes down as 4k and a source that only has 720 comes down as 720. the two below it trade quality for a smaller file, in that order. what you pick is remembered.

it is off until you turn it on, and turning it on is a card that says what that costs before any of it happens: the internet, and programs keeper does not ship. yt-dlp and spotDL do the fetching, and ffmpeg turns what comes down into the file you asked for. say yes and keeper gets them from their own github releases, once on this machine, into its own folder. say no and none of it happens and it does not ask again.

that one yes is also what gets film working, because ffmpeg is what reads a clip at all.

a spotify link is a name rather than a file. spotdl is the one thing here that can turn that name into the track it stands for, and that is all it does: the download itself is yt-dlp both times. it is the half that has to stay current, so it is the half keeper keeps current.

one track a link. a playlist link gets the track it points at rather than the playlist, so a link pasted out of habit cannot start two hundred downloads.

what you may do with what comes down is between you and whoever made it. keeper does not check and does not know.

is it safe

it is the first thing to check about anything you point at your photographs, so it is written out rather than claimed in a badge.

with the analysis off, nothing of yours leaves this computer, and it is off until you turn it on. no upload, no account, no login, no key, and no licence check. it works with the wifi turned off, and you can test that: turn the wifi off and use it. the shelf, the bench, the groups you type, the crops, the exports and the search all work with it off, and none of them ever make a request.

that sentence used to read "your photographs never leave your computer" with nothing after it. it was true then, and it is true now for anybody who leaves the analysis alone, which is how it arrives. it stops being the whole story the moment you turn the analysis on, so the rest of it is written out here rather than left in a promise that has quietly gone out of date.

with the analysis on, this is all of what goes out. downscaled contact sheets, meaning your photographs at a few hundred pixels each in a grid, the group names and sentences you wrote, and the instruction that says how to answer. no file names, no folder names, no originals, and nothing about you or your machine. it goes to the one address you picked and to no other, and if you pointed it at a model running on your own machine it does not leave the machine at all.

and none of it carries the block your camera wrote. the make, the lens, the moment the shutter went and any gps that was on live in a frame's exif. keeper reads that on this machine, which is how camera: and date: work in the search, and it is not in the bytes that leave: every picture that goes out is re-encoded on the way, the exif does not survive that, and a contact sheet never had any to begin with. this was read off a real request rather than reasoned about.

your key is kept out of your archive, in this machine's keychain, or in a file in keeper's own folder that only you can read where there is no keychain. somebody sent you a key file? drag it onto the keeper window, or pick it from settings, and the key goes into the keychain and the file can be deleted. keeper refuses a key file that sits inside an archive or a git checkout, and never says more than the last four characters of what it read.

nothing is counted or reported. no analytics, no crash reports, no usage tracking. not turned off by default, not in there at all.

four things can reach the internet and every one of them asks you first. keeper can check whether a newer keeper exists, and saying yes fetches one small file that carries no name, no photographs and nothing about you. the downloads tab, which is the only part of keeper that fetches something that is not keeper, and which now fetches ffmpeg on that same yes. the analysis. and the sound of a clip, which goes to the transcription service you picked and only when you say so for that clip or that archive, an answer that dies when keeper closes. each of the four is a card that asks in words, before anything happens, and saying no to one means it never asks again and never makes the request.

your photographs are read and never written to. keeper makes one folder inside yours, called .keeper, and puts its small copies, your groups, your labels, anything the second pass wrote and your crops in there. delete that folder and your archive is exactly as it was.

nothing is generated. no picture is made here and nothing is painted into one of yours. the model is asked to read, and it answers in words: a digit, a sentence, a few keywords. not one pixel of anything you shot is changed by any of it.

what is coming

keeper is a side project. this is what it is pointed at, not a schedule, and it is written down so you can tell whether the thing you need is on the list or not on it at all.

  • cutting a clip to a shape, and trimming it. a clip gets a poster, a group and its moments now. the bench still crops stills and nothing else.
  • more inside the crop. the bench gives a slot one crop and stops there.
  • an export that goes where it is going, instead of landing in a folder you then have to open somewhere else to post it.
  • what a clip says, without sending it anywhere. the words come off a service now, on a yes that names it. speech recognition that runs on your own machine would make that yes unnecessary, and this line stays until an ordinary machine can do it in a time somebody will sit through.
  • an analysis that is local and fast. the local endpoint exists and works and is slow, for the reason written out above. this line stays here until an ordinary machine can do the cheap pass in a time somebody will sit through, and apple's on device vision framework is the thing worth watching for it.

none of that is promised for a date. it gets built when it gets built.

if something is wrong

keeper can check itself over and tell you what is missing.

on windows there is a keeper doctor shortcut in the start menu, next to keeper itself. on a mac it needs a terminal: keeper doctor.

either way it answers in plain sentences rather than error codes, and that is the thing to copy and send on when you ask anyone for help.

on windows, keeper cannot read raw camera files on its own, because windows does not come with anything that reads them. ffmpeg reads most of them, and the downloads card is where you say yes to keeper fetching it. jpg, png, heic and the rest work either way. macs read everything already.

for people who use a terminal

everything above works without one. this part is for people who want it.

npm install
node bin/keeper.mjs ~/Archive
keeper <folder>                 scan, thumbnail, and open the shelf
keeper app [folder]             the way the icon opens it: remembers the last
                                archive, takes its own port, and reuses the
                                copy that is already running
keeper sheets <folder>          contact sheets for a coding agent to read
keeper tag <folder> <file>      apply the tags that agent wrote
keeper export <folder>          write the placed crops out
keeper trays <folder>           what is in the trays, and how much
keeper init [folder]            create keeper.config.json
keeper doctor                   what this machine can and cannot do

--port defaults to 7777, --cols and --rows set the contact sheet grid at 6 by 4, --rescan rebuilds an index that already exists, and --no-open leaves the browser alone. typed bare, with no folder after it, keeper prints this list: a terminal opens in your home folder, and thumbnailing every file you own is not what someone asking what the command does had in mind.

the keyboard

arrows move the cursor, and a digit puts the frame it is on in that group
k keeps the frame
space quick look, the way it works everywhere else on this machine
click picks, shift+click a range, cmd+click one, cmd+drag a box
cmd+a everything the filters left, and not one frame more
a digit, with frames picked groups all of them at once, and moves nothing
cmd+return sends the picked frames to the tray
option+r reveals the original in finder, selected
cmd+f finds, option+o opens another folder, option+1 and option+2 change view
delete sets the frame aside in keeper's bin, nothing on the drive moves

the modifier is option and not cmd on three of those because chrome resolves cmd+r, cmd+o and cmd+1 above the page: preventDefault runs and the tab reloads anyway. the physical key is read off e.code rather than e.key, because option on a mac rewrites the character and option+r arrives as ®.

your own shapes

the built in formats live in src/formats.mjs. your own go in keeper.config.json:

{
  "slots": [
    { "id": "hero",    "aspect": "16/9", "width": 2400 },
    { "id": "about-1", "aspect": "3/2",  "width": 1200,
      "note": "the room rather than a wall of faces" }
  ]
}

the config is read from the folder you run keeper in, not from the archive, because the holes belong to the project and the photographs do not. keeper init writes the example there for you. a slot of yours with the same id as a built in one replaces it quietly, and "formats": false turns the whole standard set off.

if you have not zoomed in and you have a config, the bench also prints the exact object-position line for your stylesheet, so the original ships uncut and the browser does the cropping.

exporting a tray three ways

keeper trays ~/Archive
keeper trays ~/Archive --export tray-1 --to ~/Desktop/for-the-site
keeper trays ~/Archive --export tray-1 --to ~/Desktop/live --mode symlink

copies are real files, yours to hand to anyone. symlinks and finder aliases copy nothing and point at the originals, the first breaking if you move them and the second following them. the terminal names the mode it just ran every time, because a folder of links and a folder of copies look identical in a listing and weigh nothing alike.

keeper refuses to export into a folder inside the archive. it would work once. the next scan would find the copies, give them their own ids, thumbnail them, and you would be browsing every exported frame twice with the tags on only one of the pair.

how it works, for anyone reading the source

the server binds to 127.0.0.1. not 0.0.0.0, which means it cannot be reached from the other laptop on your own wifi, never mind from outside. one browser, one machine. every fetch in the source names a path on this machine, github, or the analysis endpoint you chose yourself, and grep -rn "fetch(" src web bin is still the whole audit.

a placement is stored in the negative's own coordinates, not the screen's. three numbers: where the centre of the crop sits in the source, and how wide it is as a fraction of the source. the height falls out of the slot's aspect at the moment of painting. that is what lets a layout change a frame's aspect at a breakpoint without silently meaning something different. a placement written in screen pixels would.

a frame's id is a hash of its path, not its position. drop 200 new photographs into the archive and every tag written last month still points at the same picture. position based ids would have slid by 200 and repointed the lot, quietly. it is also why a frame you take back out of the bin comes back to its own tags.

a browser is never told where a dropped folder lives. it gets the name, and for a folder it may list what sits directly inside, and that is the end of it. so keeper recovers the path three ways: the drag's own file:// url when the source writes one, the machine's search index, and a read of the handful of folders an archive is ever kept in. if all three come up empty the real folder dialog opens, which is the only thing on the machine that can hand a browser a path and mean it. nothing in it ever says the drop failed when what happened is that the browser withheld the path.

the two machines differ in five places and only five: the file manager, the wastebasket, the shortcut a tray exports as, the search index, and the list of folders to look in. those live in src/os/ and everything above them is one codebase.

reads jpg, png, webp, avif, tif, heic and dng, and mov, mp4, m4v, mkv, avi, webm and mts. raw files come in through their embedded preview, which is all a contact sheet needs. clips need ffmpeg, which is looked for on the path, then in the folders it is actually installed into, then in keeper's own, and fetched into that last one if you said yes. the middle step exists because a mac app opened from the dock inherits a path with no homebrew on it, and a tester's own ffmpeg is invisible to everything keeper spawns without it.

updating

keeper can update itself, and it asks before it ever looks. what comes down is about a quarter of a megabyte, because it is keeper and not the runtime under it. it is checked against the checksum the release published before a file moves, the copy being replaced is set aside rather than deleted so a failure puts it back, and a release that changes what keeper depends on cannot be installed this way, says so, and sends you to the downloads instead of installing half of something.

on a mac the app is signed again after the swap, with the same ad hoc signature the build gave it, and the quarantine mark a browser download carries comes off. without both, an app that updated would be refused as damaged the next time it opened, which is what happened to every keeper before 0.9.3: the update landed and the app never came back. one of those will tell you the newest keeper needs a full download and offer the downloads page. it is right: get the dmg once, and it updates itself from there.

where things live

everything keeper writes goes in <archive>/.keeper/: the index, the small copies, the contact sheets, the groups you wrote, your tags, the sentences the second pass wrote, your placements and your trays. delete that folder and the archive is exactly as it was. the groups live with the photographs and not with keeper, because they are a fact about this set of photographs: copy the folder to another machine and the names of the labels travel with the labels.

opened from its icon it keeps a little more, and this is all of it: which archive was open last, which port it is on, what you have answered about updates, downloads and the analysis, and which model and endpoint the analysis is pointed at. ~/Library/Application Support/keeper on macos, %LOCALAPPDATA%\keeper on windows. an api key is in neither of those files: it goes in this machine's keychain, and where there is no keychain, in a file beside them that only you can read. if you said yes on the downloads card, yt-dlp, spotdl, ffmpeg and ffprobe sit in a bin folder beside those, which is also why an update to keeper never has to fetch them again. deleting the lot loses the memory of where you were, and means they are fetched again next time you ask for them.

the look

a red square and the word keeper beside it, and a photograph is the only thing on the screen worth looking at.

two zones, and the split is the whole rule. anything that touches a photograph is strictly equal rgb: #0b0b0b for the wall, #101010 for the plate under a frame, black for quick look. a warm cast beside a picture lies about the picture. chrome that never borders one is a whisper warm, #151310 for bars and panels and #1d1915 above them, and there is one warm ink, #f2efe9, at three strengths.

#e1062c is the accent, and it is a fill or a ring and never a word: red as text is #ff5d75. amber #e0a458 means deal with this and green #4fc978 is quiet confirmation. the accent means one thing anywhere it appears, which is that you chose this. a tab you are already looking at is not that, and neither is a photograph.

the palette: the equal rgb greys that
touch a photograph, the warm chrome that never does, and the four colours that
are allowed to mean something

type is geist and geist mono, self hosted in web/font, ofl, nothing fetched at runtime. the mono carries the wordmark, the nav, every label, every chip and every number, and the sans is left to do the one thing a mono cannot, which is read as a sentence.

licence

source available, not open source. free while keeper is in testing, and it is in testing now: use it for anything, at home or at work, on as many machines as you like, no payment, no account, no key and no licence check. LICENSE says it in words rather than in a badge.

what you cannot do is sell it, redistribute it, or run it as a service. later versions may be sold under a one time licence, and every version published while keeper is in testing stays free under this licence forever, so a copy you already have never stops working and never has to be paid for.

it was mit, then apache 2.0 while there was nothing to sell. those releases are still apache and that cannot be taken back. a dmg is not source: it carries node, sharp and libvips, and libvips is lgpl, so shipping that binary means saying whose work is inside it and letting somebody swap it. NOTICE does both and names the file, and nothing in keeper's own licence takes away anything those licences give you.

About

a local culling and cropping bench for a photo and video archive. no api key, no uploads, no original ever edited.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages