Skip to content
dabit3Public

About

No description, website, or topics provided.

Resources

Stars

9 stars

Watchers

0 watching

Forks

Latest commit

 

History

69 Commits

Folders and files

Repository files navigation

Intern

Built with Devin

Intern hero: the title above the panel ranking Q3-Roadmap-Review.pdf first for “the pdf I just downloaded”, with a Built by Devin mark

Intern is a native macOS app that finds things the way you remember them. Press ⌥Space, describe what you want — the pdf I just downloaded, files I used in the last hour, the typesafe pages I read today — and press Enter to open it.

Intern searches your files and Chrome history locally, then Jev judges which candidate you mean on every keystroke, about 100 ms per round trip. When one thing clearly fits, it is selected and a green ↵ appears. When several do, Intern offers to open them all, and that group can be saved as a workspace and recalled later by name.

Four Intern examples: finding the PDF you just downloaded, opening the files you used in the last hour, reopening the Devin Ambassador pages you visited today, and saving three apps as a Writing workspace you recall by name

The first five examples show live Jev ranking against single targets. The final example uses the current panel's scopes and Actions menu to group three apps, save them as Writing mode, and recall the workspace by name.

Download for Mac

Download Intern.dmg from GitHub Releases. Requires macOS 14 or later on Apple silicon or Intel. You do not need Xcode or a terminal.

  1. Open Intern.dmg.
  2. Drag Intern into Applications.
  3. Open Intern from Applications.
  4. Press Option-Space to open the launcher.

Intern runs in the menu bar, not the Dock.

First-time setup

You need a TypeSafe API key for AI-powered ranking. Local search works without one.

  1. Sign in to the TypeSafe dashboard and get an API key. See the TypeSafe quick start for more details.
  2. Click Intern's bolt icon in the macOS menu bar and choose Settings…. If the icon is hidden, press Option-Space and then Command-Comma (⌘,). The Add a TypeSafe key in Settings message also links to Settings, and ⌘Q quits Intern from the launcher.
  3. In the TypeSafe section, paste your key into API key and click Save (or press Command-S). Unsaved changes becomes API key saved once it is stored. No terminal command is needed for the downloaded app.
  4. Under Search and privacy, leave Keep searches on this Mac turned off to enable online ranking. You can also choose whether to search files with Spotlight and include Chrome browsing history.
  5. Close Settings, press Option-Space, and try the pdf I just downloaded. Press Return to open the selected result. Allow access to folders you want to search when macOS asks.

If online ranking is unavailable, Intern keeps showing local results. Check that your API key is valid, your Mac is online, and Keep searches on this Mac is off. Turn that setting on whenever you want local-only search; it disables TypeSafe requests even with a key configured.

To replace your key, edit the field and click Save again. To remove it, clear the field and save; the status becomes No API key saved. The saved status confirms storage, not API validation. When running from a terminal, a nonempty TYPESAFE_API_KEY environment variable takes precedence over the saved key.

What Intern does

  • Describe a file instead of naming it.
  • the pdf I just downloaded opens the newest arrival.
  • the last pdf I opened, by when you opened it, not when it changed.
  • files I modified yesterday, the deck from last week.
  • the devin links I visited today reopens the Chrome pages you mean.
  • open the ambassador links I visited this week, all in one go.
  • Time windows in plain words: last hour, this morning, a few days ago.
  • Group the files you used this morning into a single Open all.
  • Uncheck a member before opening the group.
  • Save a group as a workspace and recall it by name.
  • Clear launch history when you want a clean slate.

Under the hood: local search finds candidates, Jev re-ranks them by meaning on every keystroke in about 100 ms, and decides whether you mean one item or all of them. A green ↵ appears the moment your intent is unambiguous. Chrome history is read locally and only the matching rows are ever sent.

You can also do the usual launcher things: open apps and files, toggle dark mode, turn Wi-Fi on or off, sleep or lock the screen, empty the Trash, calculate 15% of 240 inline, run Shortcuts, Quick Look a file, reveal it in Finder, copy a path, pin anything, and search the web.

Why speed matters

A launcher is judged per keystroke. Previous single-target runs measured about 100 ms per Jev round trip from this VM. Local results appear immediately; Jev refines them when its answer arrives. Superseded requests are canceled, old responses are rejected, and manually selected rows stay selected when ranking changes. Spotlight searches in parallel and can trigger a fresh judgment when it finds more candidates.

How it works

Find files by what happened

The immediate index covers Downloads, Desktop and Documents. Spotlight expands search across indexed content in your home directory, excluding hidden paths, Library, app contents and node_modules. Searches use filename words and file-type metadata and map at most 150 retrieved items into candidates.

Recency has three distinct meanings:

Query Evidence used
the last pdf I opened Spotlight last-used date, or a successful launch recorded by this app
the pdf I just downloaded Date added to the folder, with modification time as a fallback when added metadata is unavailable
files I modified yesterday File modification date

Files with unknown last-used dates are excluded from opened/used queries. A recently edited file is not treated as recently opened. Finder metadata is not available for every file, and "added" does not prove a browser download.

Jev also receives the query-relevant file age in seconds and its evidence source. Two files labeled "added 7 min ago" can still be distinguished without mistaking a recent edit for a recent arrival.

A launcher that remembers

Pins and recent launches fill the empty screen. Successful launches build a small local history of frequency, recency and query aliases, used as bounded boosts in the fuzzy shortlist. Clear launch history in Settings to reset these boosts while keeping pins and workspaces.

The scope bar switches between All, Files, Apps, Links and Workspaces. Tab and Shift-Tab cycle through scopes. The calculator appears in All; web-search fallback appears in All and Links.

Act without opening

Press ⌘K for the selected result's actions. Arrow keys select an action and Enter runs it. Files support Quick Look and Reveal in Finder; files, links and calculations can be copied; apps, files and links can be pinned. Escape closes the current overlay before dismissing the launcher.

Save a workflow

Check or uncheck members of a suggested group, or build a group yourself with ⇧⌘Space on individual results. Save group as workspace gives it a name, such as Writing or Launch research. That name becomes a searchable result containing 2 to 25 apps, files or links. Open its Actions menu and choose Review and edit items to adjust the group before opening it or saving a new workspace. Workspaces are local, capped at 20, and removable from their Actions menu.

Only openable items can belong to groups. System commands and shortcuts cannot be bundled into a workspace. Empty Trash requires a separate confirmation after selection.

Single targets

Historical live examples, rather than guaranteed probabilities:

Query Top hit Jev target probability
dark Toggle Dark Mode 99%
wifi off Turn Wi-Fi Off (not Turn Wi-Fi On, which has the same fuzzy score) 100%
15% of 240 = 36, evaluated in code; Enter copies it 100%
the pdf I just downloaded Q3-Roadmap-Review.pdf, the newest of six PDFs 100%
sleep Sleep 99%

The fuzzy matcher gets plausible PDFs into the shortlist. Jev compares their added, opened and modified details with what the query actually asks for.

One item or all of them

open devin ambassador links I visited in the past 24 hours produces the second screenshot above. In order:

  1. Time window, in code. TimeWindow.parse recognises past 24 hours, last hour, yesterday, today, this week, last month, this morning, earlier today, a few days ago and similar phrases and turns them into a since/until pair. Only candidates dated inside the window are eligible, the phrase is stripped from the text that gets fuzzy-matched, and the window is sent to Jev as time_window.
  2. Chrome history, in code. ChromeHistory queries each regular profile read-only, including committed WAL visits. When Chrome holds an exclusive lock, it copies the database and journal sidecars into a private disposable snapshot, checks for concurrent file changes and lets SQLite recover and validate only that copy. The snapshot fallback is limited to 256 MiB. It keeps the last 90 days of http(s) visits, merges duplicate URLs across profiles and turns each row into a candidate: page title, host, absolute visit time, plus host and title words as keywords. Only the rows that survive the window and the fuzzy filter are sent (up to 30 with a window, 13 without). The database never leaves the machine.
  3. Two extra questions in the same request. scope is a Choice between one (a specific item) and all (every candidate that fits). match_cN is one Noul per real candidate: does this row fit the description? This is the rerank pattern from the TypeSafe cookbooks. Both come back in the same round trip as target, action and ready.
  4. Group row, in code. Rows with match ≥ 0.6 (at least two, at most 25) form the set. The panel adds a synthetic Open all 3 links row: first when P(all) ≥ 0.5, right under the best single hit when Jev is torn (0.15 ≤ P(all) < 0.5), and not at all when the query is clearly about one thing (P(all) < 0.15). Members get a checkmark; ↓ still walks through them one by one. The group row is ready only when P(all) ≥ 0.75.
  5. Enter opens them. URLs use their registered browser, with group members batched by application handler; other members run through the normal single-item path. Nothing runs without Enter.

The same machinery is not Chrome-specific. the files I used in the last hour can offer an Open all row over files with matching last-opened evidence, with older files excluded before Jev sees them. Mixed sets (Open all 4 items) work too. Membership checkboxes remain editable while an answer is in flight, and a new answer does not overwrite those choices.

Historical group-query measurements:

Query P(all) Top row Set
open devin ambassador links I visited in the past 24 hours 1.00 Open all 3 links three Ambassador pages at 0.89 to 0.94; GitHub, Hacker News and TypeSafe docs from the same day at 0.06 or less; a 70-hour-old duplicate excluded by the window
the files I downloaded in the last hour 1.00 Open all 3 files the three PDFs modified in the last hour
pages about typesafe I read today 0.99 System One, TypeSafe Docs one match, so no group row
the pdf I just downloaded 0.00 Q3-Roadmap-Review.pdf (target 1.00) none offered, even though five PDFs individually fit
dark, wifi off 0.00 Toggle Dark Mode, Turn Wi-Fi Off none

Measured numbers

These baseline figures come from earlier live runs on this macOS VM (macOS 26.5, ARM64, Xcode 26.6) against jev-latest, which resolved to jev-1.13.0. They are not a benchmark of every new feature. Latency is the full HTTPS round trip measured in the app, including network and inference.

Metric Value
Median round trip (p50) about 100 ms for single-target queries
p95 round trip about 200 to 300 ms
First request of a session about 500 ms (TLS setup)
Set query with a time window (30 candidates) 160 to 330 ms, about 2.7k input tokens
Input tokens per decision about 1,400 without a window, up to 3,700 with one
Output tokens 0; typed judgments never generate text
Cost per keystroke about $0.00006 at $0.042 per million input tokens
Cost of a five-query session about $0.003

Questions share one round trip and are evaluated in parallel. Candidate and question counts still affect tokens and latency. The footer shows only the latest round trip and estimated running cost. Hover for p50, p95, decision count and tokens per decision. Canceled requests may still incur server charges that the app cannot count without a usage response.

How the Jev request is built

Each query change starts a POST /v1/systemone with model: jev-latest, unless local-only mode, a missing key or a rate-limit cooldown prevents it. A completed Spotlight search or index refresh can issue a replacement judgment. Jev returns typed probabilities; indexing, prefiltering, time parsing, arithmetic and execution remain plain Swift.

State, abbreviated (Sources/JevQuestions.swift):

{
  "query": "the pdf I",
  "query_note": "Text the user has typed so far into a Spotlight-style macOS launcher. It is often an incomplete prefix or a short natural-language phrase.",
  "context": { "frontmost_app": "Finder", "recent_apps": ["Finder", "Safari"], "clipboard_kind": "text", "time_of_day": "afternoon", "weekday": "Thursday" },
  "time_window": null,
  "candidates": [
    { "id": "c0", "kind": "open_file", "title": "Q3-Roadmap-Review.pdf", "detail": "PDF in ~/Downloads · modified 16 min ago", "recency": { "basis": "modified", "seconds_ago": 964, "newest_rank": 1 } },
    { "id": "c1", "kind": "open_file", "title": "invoice-2026-08.pdf", "detail": "PDF in ~/Downloads · modified 1 month ago", "recency": { "basis": "modified", "seconds_ago": 2678400, "newest_rank": 2 } },
    { "id": "c6", "kind": "web_search", "title": "Search the web for “the pdf I”", "detail": "Opens your default browser" }
  ]
}

Candidates are the top 13 fuzzy matches from the merged local sources (30 when the query names a time window), after scope filtering and personal boosts. Synthetic rows add arithmetic results in All and web search in All/Links. They carry short ids (c0 to cN) that the code maps back to real candidates when the answer arrives, so Jev only ever sees a few dozen rows, never the whole index or browser history.

Questions, all in one questions object:

  1. target: Choice over c0 to cN plus none. Which entry is the item they intend to open or run, treating query as a possibly incomplete prefix or paraphrase and matching on meaning. The full distribution is used: each row's percentage is probabilities[cK].
  2. action: Choice over open_app, open_file, open_url, web_search, calculate, system_toggle, run_shortcut, unclear, each with a one-line rubric. A candidate whose kind matches the chosen action gets a ranking boost.
  3. ready: Noul. The launcher is about to run the best candidate the instant Enter is pressed; is query already unambiguous enough for that? The top row gets the green ↵ when this is at least 0.6, or when Jev gives one target at least 90%. The second rule exists because on the PDF query ready hedges around 0.4 while target is 98 to 100% on the newest file.
  4. scope: Choice between one and all, described above.
  5. match_cN: one Noul per real candidate (synthetic calculator and web rows excluded), described above.

Ranking is deterministic given the answer. Let w = min(1, 2 · max(target confidence, lead over the next candidate)). Then score = w · (0.65 · P(target) + 0.20 · P(action matches kind)) + (1 − 0.85 · w) · fuzzy, plus 0.25 · P(all) · P(match) for rows in the set. Strong online judgments use the full semantic weighting; uncertain judgments retain more local relevance. Small probability-total differences from hundredth-place rounding are normalized; incomplete or invalid target distributions fall back locally. Without an answer the score is just fuzzy. Rows whose name you typed exactly always form a tier above the rest.

Steadiness. Local results update on every keystroke; Jev and Spotlight are asked 150 ms and 60 ms after typing pauses, and an identical question is never asked twice. While you extend or backspace a query, the previous answer stays in force at half weight, dimmed, until the new one arrives, so the list refines instead of snapping between local and online order. Only a fresh answer can light the green ↵ or offer a group row. Rows animate into their new positions, and the panel waits 120 ms before shrinking.

In-flight handling: a response must belong to the current sequence and its task must not be canceled. Spotlight callbacks also check their search generation. While a replacement request is in flight, previous probabilities may stay visible but cannot light the readiness badge. Manual selection is preserved by candidate identity. Membership edits survive reordering. Late action completions cannot dismiss a newer query.

Iteration notes

The ready wording went through several rounds against the five queries plus deliberately ambiguous ones. The first version ("is this unambiguous?") scored 0.3 to 0.4 even for dark. Telling Jev that candidates is the complete option set, that web_search is only a fallback, and giving one concrete example of a short but unambiguous prefix produced this spread:

Query Candidates ready
calc 15% of 240 = 36, Calculator, web 0.88
the pdf I just downloaded 3 PDFs of different ages, web 0.84
dark Toggle Dark Mode, web 0.64
da Toggle Dark Mode, Dashboard, web 0.29
sle Sleep, Slack, web 0.29
wifi Turn Wi-Fi Off, Turn Wi-Fi On, web 0.16
s Sleep, Safari, Slack, web 0.13

wifi alone is correctly not ready (on or off?) while wifi off is; sle is correctly torn between Sleep and Slack. The target question needed an explicit hint that detail carries recency before "the pdf I just downloaded" reliably preferred the newest file over the alphabetically first one. ready is worded for a single target and stays low (around 0.2) on set queries, which is why group readiness uses P(all) instead.

What is local (code, not Jev)

  • Index (LocalIndex.swift): application bundles in standard and nested installation folders, Finder and the system Cryptex app folder; ~/Downloads, ~/Desktop, ~/Documents themselves and their files (up to eight nested levels and 4,000 inspected entries per root, at most 250 newest entries per folder so one log directory cannot crowd out the rest, retaining 400 candidates by modified/added recency); user Shortcuts; nine system toggles; optional Chrome history (regular profiles, last 90 days, at most 3,000 URLs). Packages, hidden/private directories, symlink trees and cache/log/node_modules folders are excluded from file traversal. The last index is saved under ~/Library/Application Support/<bundle id>/index.json and loaded at launch, so results appear before the first rebuild finishes. Folder and app scans are reused for 90 seconds; Chrome history is re-read only when its database files change. With Spotlight enabled, files you opened in the last 30 days anywhere in your home folder join the index too.
  • Spotlight (SpotlightSearch.swift): cancellable NSMetadataQuery searches with a one-second collection timeout. Results merge with the static index and library by identity before the bounded fuzzy prefilter.
  • Personal library (PersonalLibrary.swift): at most 200 local records, eight query aliases per record and 20 workspaces, persisted as Codable data in UserDefaults under launcher.library.v1. No file contents are stored.
  • Time windows (TimeWindow.swift): relative (past 24 hours, last 3 days, a couple of weeks ago), named (today, yesterday, this week, last month, this morning, tonight, last night, just now, recently) and number words, resolved against the local calendar.
  • System toggles (Executor.swift): Dark Mode (AppleScript to System Events), Wi-Fi on/off (networksetup -setairportpower), Do Not Disturb (opens Focus settings), Sleep (AppleScript), Lock Screen (CGSession -suspend), Empty Trash (AppleScript to Finder), Show/Hide hidden files (defaults write plus killall Finder).
  • Calculator (Calculator.swift): a bounded recursive-descent parser for + - * / ^ ( ), Unicode operators (− × ÷ √), scientific notation, implicit multiplication, sqrt, and percentages (15% of 240, 200 * 10%), with an optional calc or = prefix. No NSExpression, no eval.
  • Fuzzy prefilter (Fuzzy.swift): exact, prefix, word-initial, single-edit typo and subsequence scoring over titles, keywords and the two enclosing folder names, tokenized once per item so a keystroke over thousands of candidates costs about a millisecond. Starting the first word of a name scores higher than starting a later word. Natural-language filler is stripped, including a filler word still being typed. Your own history adds to the score: an item you opened for this exact query before wins outright (a learned alias, even when the words differ), typing the start of a short learned query lifts its item, and pinned, recently or often opened items win ties. Among browser links with the same score, the hub comes first: shallower paths before deep links with record ids and query strings, then more often visited, then more recent. So stripe dashboard offers the dashboard home rather than the coupon you looked at last, while stripe coupons still goes straight to that coupon. Time-window queries keep newest-first order.
  • Execution: NSWorkspace.open for apps, files and web searches; URLs and URL groups use their registered browser, passed as values, never through a shell. Group members are validated and deduplicated before opening. The calculator result is copied to the clipboard; subprocess actions have cancellation, timeout and output bounds.

Run

Requirements: macOS 14 or later, Xcode 16 or later (built with 26.6), a TypeSafe API key for online ranking, and XcodeGen if you change project.yml or add/remove source or test files (the generated project is committed).

git clone https://github.com/dabit3/intern.git
cd intern
export TYPESAFE_API_KEY=...        # read from the environment; never hardcoded
./run.sh --show                    # builds Debug and launches with the panel open

The built application is Intern.app. The Xcode project, scheme and module are named Intern.

Debug builds appear as Intern Dev in macOS permission prompts and use separate settings from the signed release. Their bundle identifier is com.devin.typesafe.jev-launcher.debug. The release keeps com.devin.typesafe.jev-launcher, so existing release settings remain available. run.sh quits only this checkout's development copy before rebuilding, not the installed release.

run.sh execs the binary from the shell so the environment variable is inherited. If you launch the .app from Finder instead, the key is read from the Settings field (menu bar ⚡, then Settings, stored in UserDefaults under typesafeAPIKey). With no key the panel works locally and a header icon explains why. Settings also control Spotlight, Chrome history and local-only mode. Source and local-only changes invalidate pending searches immediately.

  • ⌥Space toggles the panel from anywhere (Carbon RegisterEventHotKey; no Accessibility permission needed).
  • ↑ / ↓ move the selection, ↵ runs it, esc hides the panel. The example chips in the empty state (dark, wifi off, 15% of 240, the pdf I just downloaded, links I visited today) are clickable.
  • The menu-bar ⚡ item has Toggle Intern, Settings and Quit. The app has no Dock icon (LSUIElement). If the menu bar hides the item, ⌘, opens Settings and ⌘Q quits from the launcher.
  • The panel is a translucent NSVisualEffectView HUD that resizes to its content (up to seven rows). App and file rows show the real Finder icon; toggles, the calculator, web search, links and group rows use tinted SF Symbols. A small dot next to the field shows while a request is in flight; the bolt turns green when the top row is ready. The footer is just latency and cost.
Shortcut Action
⌘K Open or close Actions
⌘Y Quick Look the selected file
⌘R Reveal the selected app or file in Finder
⇧⌘C Copy path, link, result or group values
⌘P Pin or unpin
⇧⌘Space Include or exclude the selected item in a group
Tab / Shift-Tab Next / previous scope
⌘, Open Settings
⌘Q Quit Intern

The older ⌘Space group shortcut remains available when it is not assigned to macOS Spotlight. Use ⇧⌘Space, the member checkbox or the Actions menu with the default macOS shortcuts.

Privacy and failure behavior

The request contains the query, short candidate titles/details, query-relevant file ages and limited context. Details can include folder names, browser hosts and workspace member names. File contents, clipboard text, the complete index and raw browser databases stay local. Local-only mode disables Jev requests; pinning, workspaces, previews, calculations and manual groups still work.

Errors and action feedback appear in a compact status line. Missing keys, HTTP errors, timeouts, malformed rankings and transport failures preserve local results. Queries over 2,048 UTF-8 bytes remain local rather than sending a truncated intent. HTTP 429 and 529 pause new requests, honor bounded Retry-After values when supplied, and use increasing cooldowns for repeated limits. Enter remains explicit even when Jev reports high confidence. File existence, URL schemes and group eligibility are validated before execution.

Permissions

  • Automation (Apple Events): the first Dark Mode, Sleep or Empty Trash toggle prompts to control System Events or Finder. NSAppleEventsUsageDescription is set in project.yml. The build is unsandboxed so it can read the folders it indexes.
  • Wi-Fi toggling uses networksetup, which may ask for an administrator password on some macOS versions.
  • Folders: macOS manages access to Downloads, Desktop and Documents separately. Use one installed, signed release for normal use. Old unsigned builds that share its identifier can invalidate saved permissions and cause repeated prompts. Folder scans run one at a time and stop at cancellation checkpoints when the panel closes. Chrome's history lives under ~/Library/Application Support.
  • Nothing else: no Accessibility, Screen Recording or Full Disk Access.

Build and test

xcodebuild -project Intern.xcodeproj -scheme Intern -configuration Debug \
  -destination 'platform=macOS' -derivedDataPath build CODE_SIGNING_ALLOWED=NO build
xcodebuild -project Intern.xcodeproj -scheme Intern -configuration Debug \
  -destination 'platform=macOS' -derivedDataPath build CODE_SIGNING_ALLOWED=NO test
xcrun swift-format lint --strict --recursive Sources Tests

The offline suite covers ranking, typed requests, arithmetic, Chrome history, recency semantics, scopes, persisted pins and workspaces, action validation, manual selection and group edits during late responses, local-only mode and destructive confirmation. LiveJevTests and LiveExperienceTests are opt-in API probes. See TESTING.md for commands, coverage and the desktop checklist.

Package a release

The DMG contains a universal app for Apple silicon and Intel, an Applications shortcut, and a Retina installer background. It uses the same bundle identifier as earlier builds, so existing settings stay available.

For a local build, run ./scripts/make-dmg.sh. This creates Intern.dmg and Intern.dmg.sha256, a SHA-256 checksum for verifying the download. Local builds use an ad-hoc signature, which does not identify an Apple-registered developer, and are not notarized.

For public distribution, use a Developer ID Application certificate and a notarytool profile stored in Keychain:

SIGNING_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
NOTARY_PROFILE="your-profile" \
RELEASE_VERSION=0.2.2 RELEASE_BUILD=8 \
  ./scripts/make-dmg.sh

REQUIRE_NOTARIZATION=1 sh scripts/verify-dmg.sh Intern.dmg
shasum -a 256 -c Intern.dmg.sha256

Notarization is Apple's automated security check. The script signs both the app and DMG, submits each to Apple, and attaches Apple's approval tickets. It verifies both architectures, the installer contents, the signatures, and macOS security acceptance before it produces the final files. Failed signing or notarization stops the build. Existing output files are never overwritten. Finder can ask for permission to arrange the installer window.

Keep Apple credentials in Keychain, not in source files or release notes. Upload Intern.dmg and Intern.dmg.sha256 to a GitHub release whose tag matches the source used for the build. Use a normal release, not a draft or prerelease, so the latest-download link resolves.

The static marketing site is in site/. Open site/index.html directly or publish that folder on any static host. Its Download button points to https://github.com/dabit3/intern/releases/latest/download/Intern.dmg, so release assets must use that filename.

Intern was extracted from dabit3/jev-experiments. This repository is its maintained home, including Spotlight search, pins, saved workspaces and keyboard actions. It keeps the original com.devin.typesafe.jev-launcher bundle identifier so existing settings, pins and workspaces remain available.

Limitations

  • The list is always shown. Hiding it on a probabilistic signal felt wrong for a launcher, so readiness is the green ↵ on the top row; Enter always runs the selected row regardless.
  • Latency is network-bound. The numbers above are from a US VM; p50 will track your distance to api.typesafe.ai.
  • Cancellation is best effort. It avoids applying old answers, but cannot guarantee an already received server request stops processing.
  • Context is minimal. frontmost_app, recent_apps, clipboard_kind, time_of_day and weekday are sent; the app does not read window titles, open browser tabs or clipboard contents. Chrome history is read locally and only the rows that match the query and time window are sent, as title plus host plus relative visit time.
  • Chrome only, and only visits. Safari's history is not read (it needs Full Disk Access); the Chrome downloads table and open tabs are not used. History is re-read when the panel opens and Chrome's database has changed, so a page visited seconds ago appears on the next ⌥Space. Folder scans are reused for 90 seconds; a file saved seconds ago is still found through the live Spotlight search.
  • Set thresholds are tuned by hand on the queries above (Ranker.setThreshold, memberThreshold, offerThreshold).
  • Metadata coverage varies. Spotlight must be enabled and the location indexed. Opening a file in another app does not always update its last-used date. The local library records only successful launches through this launcher. Moved or missing files are not automatically repaired.
  • Grouped opens are not transactional. A mid-execution app or OS failure can leave some members open; the launcher reports the failure rather than recording the whole group as successful.
  • Settings keys use UserDefaults, not Keychain. Use the environment variable if you do not want the launcher to persist the API key.
  • Screenshots use fixture documents and browsing history. Current desktop interactions need a separate UI verification pass; automated checks do not validate macOS permission dialogs or preview rendering.

About

No description, website, or topics provided.

Resources

Stars

9 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages