Build Cluely

KINDAreplaces $19.99/mosaves $239.88/yrback to the verdict

0%0 of 17 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A desktop assistant with access to what is on your screen and, with consent, what is said on your calls, where the engineering is in capturing selectively and locally, and the design is entirely about the capture being visible to everyone it affects.

estimated effort multi-daythe files for this build are in the project pack

CaptureScreen region capture and system audio, each separately permittedProcessingLocal models by default, with any hosted call an explicit per-session choiceIndicationAn always-visible indicator that cannot be disabledRetentionShort by default, with transcripts and screen text expiring separatelyRuntimeA native overlay application with a hotkey

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. have readyfree

    Why Screen and audio capture each need a system permission, and what each grants and how it is requested differs by platform and version.

    Get it Read your platform's current documentation for both permissions before designing the consent flow.

    Verify Both permissions can be requested separately and their state read

  2. installfree, needs memory

    Why Screen contents and call transcripts are the most sensitive material on a machine and the default must not be sending them anywhere.

    Get it Any local runner with a model capable of answering from provided context. open ↗

    Verify A query answers from local context with networking disabled

  3. decidefree to read; an hour of advice if this is for work

    Why Capturing call audio records other people, and the rules attach to the recording rather than to the software being visible.

    Get it Identify where the people you call are, take the strictest applicable rule, and write down what you concluded.

    Verify A written note names the jurisdictions and the rule applied

  4. decidefree

    Why A password manager, a private message window or a medical portal captured once is captured, and deciding the list afterwards is deciding it too late.

    Get it List applications and window title patterns that must never be captured. Err wide.

    Verify The list is loaded by the capture path before the first run

  5. have readyfree

    Why Phase 3 refuses to operate in those contexts, and the check is only as good as the list.

    Get it Identify the proctoring and assessment tools in use where you are. Keep the list narrow so false positives stay rare, since there is no override.

    Verify A list exists and blocking is confirmed with at least one of them running

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- sessions(id, started_at, ended_at, screen_capture, audio_capture, disclosed_at, model_policy)
- captures(id, session_id, kind, at, text, region_json, redacted) · kind is screen_text or transcript
- exclusions(id, kind, pattern) · applications and window titles never captured, applied before writing
- queries(id, session_id, prompt, response, model, at, capture_ids_json) · what context each answer used
- consents(session_id, scope, granted_at, evidence) · screen and audio consented separately
- assessment_blocks(id, detected_signal, at) · when the tool refused to run and why
- A query records which captures it used, so you can always answer what the assistant saw when it said something.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DB_PATHrequired~/.local/share/assistant/captures.dbScreen text and transcripts. The most sensitive file this build produces.
DB_KEYsecretrequireda keychain referenceEncrypts the capture store at rest.
INDICATOR_DISABLErequiredimpossiblePresent as a constant so the answer is visible. Capture without indication is not a reachable state.
CAPTURE_RETENTION_MINUTESrequired60How long captures live. Minutes, because that is how long they are useful.
DISCLOSURE_RETENTION_DAYSrequired1825Much longer than the capture, because it is the evidence.
EXCLUSIONS_PATHrequired./config/exclusions.txtLoaded by the capture path before the first write, not applied at display.

The build, in order

  1. Capture that announces itself

    Nobody near this machine could be unaware that capture is running.

    1. Capture without indication should not be a reachable state.

      Files src/Indicator.swift

    2. Different intrusions. Bundling them makes both harder to refuse.

      Files src/Permissions.swift

    3. A password manager or a private message window should never reach disk.

      Files src/Exclusions.swift

    done when · tick each as it passes
    watch out
    • Building an indicator that any setting can hide means the invisibility is one configuration change away, and the position that this tool is ethical rests entirely on it not being. Make the indicator part of the capture path, so capture without indication is not a state the application can reach.
  2. Disclosure when other people are involved

    Starting audio capture prompts you to tell the people on the call.

    1. Every time. A remembered answer is not consent from the people on the call.

      Files src/Disclosure.swift

    2. One sentence. Making it easy is what makes it happen.

      Files config/disclosure.md

    3. In the list and on anything derived from them.

      Files src/Sessions.swift

    done when · tick each as it passes
    watch out
    • A prompt with a do-not-ask-again option becomes a tool that silently records other people's conversations within a week, and the recording of that decision is a checkbox nobody remembers ticking. Prompt every time, keep the record, and make an undisclosed session visibly different from a disclosed one everywhere it appears.
  3. Refusing the uses this should not have

    The tool declines to operate as undisclosed assistance in an assessment.

    1. Narrow enough that false positives are rare, since there is no override.

      Files src/Assessment.swift

    2. Not silently degrade. The user should know why.

      Files src/Query.swift

    3. Its absence is the point. An override makes the check decorative.

      Files src/Assessment.swift

    done when · tick each as it passes
    watch out
    • Detection here will be imperfect in both directions, and the temptation is to add an override for the false positives, which immediately makes the whole check optional. Accept the false positives, keep the check narrow enough that they are rare, and treat someone needing an override as a signal about the use rather than a gap to fill.
  4. Answers from context, kept local

    The assistant uses what it captured and you know exactly what it saw.

    1. Which captures. So you can answer what it saw.

      Files src/Query.swift

    2. Not a preference. A preference is set once and forgotten.

      Files src/ModelPolicy.swift

    3. Screen contents leaving the machine deserves a look first.

      Files src/Review.swift

    done when · tick each as it passes
    watch out
    • Sending the whole capture buffer to a hosted model on every query ships screen contents and call transcripts to a third party continuously, including from the sessions where you excluded an application but had it in the buffer from before. Select context deliberately, show what was sent, and make hosted use a per-session decision rather than a preference.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more ai assistants.