Repository navigation
Releases: kulehq/kule
Release list
Kule 0.2.0-preview.6
Signed ad hoc. Kule's macOS app is signed ad hoc and not notarized by
Apple, so macOS refuses to open it the first time. After you have checked
the download (below), either open System Settings → Privacy & Security
and choose Open Anyway for Kule, or run once:xattr -dr com.apple.quarantine /Applications/Kule.appThe same goes for the
kulecommand from
kule-0.2.0-preview.6-macos-universal.tar.gzdownloaded in a browser:
xattr -d com.apple.quarantine kule.Check the download first. Every file comes with
SHA256SUMSand a build
provenance attestation, which says it was built from this repository by
this release's workflow:shasum -a 256 -c SHA256SUMS --ignore-missing gh attestation verify Kule_0.2.0-preview.6_universal.dmg --repo kulehq/kule \ --signer-workflow kulehq/kule/.github/workflows/release.yml \ --source-ref refs/tags/v0.2.0-preview.6Or build it yourself:
cargo build --release -p kule -p kule-desktop.
A security preview. An agent's output and the files it writes keep to
limits: Kule's memory, disk and window stay in hand however much the agent
says or writes, and nothing a run or kule exec started outlives it, nor
escapes the run's limits. Open with its app looks inside PDFs too, and on
macOS a task's servers are kept off your network wherever they run.
Security
- An agent keeps to what Kule can hold: a message longer than 16 MiB, or
more than 1024 tool calls left open at once, stops the run; a tool call's
title is cut to 200 characters; Kule runs at most 32 of its commands at
once. Its log keeps its last 8 MB, with the 8 MB before in
agent.log.1. What the daemon keeps of a task's runs for the window
stays near 32 MB. - Every run, from the app,
kule runor an agent's trial, andkule exec
end whatever was left running in the sandbox, whatever became of its
parent; a run's limits count such a process while it runs. - A preview of a document, sheet or CSV holds at most 16 MB; JSON or XML
nested more than 256 levels deep is shown as written; a list marker
keeps to 64 characters. - Connections that have not shown the daemon's token yet never keep its
clients out. - The window lays out an agent's messages and Markdown files in time that
grows with their length, nests quotes at most 32 deep, and shows a
message or file it cannot lay out as plain text, so the stream, Review,
Files, Preview and Timeline keep working. A message is laid out once,
not again on every event of the run. - Open with its app looks inside PDFs too, the objects packed into
compressed streams included, and opens none with a script, a program to
start, a form that sends itself, another document or an attached file,
media that runs, or an action that runs by itself as it opens; nor an
encrypted one. Links you click stay. - On macOS, where a task's servers may listen, Kule finds its processes by
its sandbox, whatever started them and whatever became of their parent,
and keeps their servers off your network in the agent's runs, the task's
terminals,kule exec,kule runandkule shellalike. A process that
a connection from the network reached in the moment before Kule looked
is stopped.
Kule 0.2.0-preview.5
Signed ad hoc. Kule's macOS app is signed ad hoc and not notarized by
Apple, so macOS refuses to open it the first time. After you have checked
the download (below), either open System Settings → Privacy & Security
and choose Open Anyway for Kule, or run once:xattr -dr com.apple.quarantine /Applications/Kule.appThe same goes for the
kulecommand from
kule-0.2.0-preview.5-macos-universal.tar.gzdownloaded in a browser:
xattr -d com.apple.quarantine kule.Check the download first. Every file comes with
SHA256SUMSand a build
provenance attestation, which says it was built from this repository by
this release's workflow:shasum -a 256 -c SHA256SUMS --ignore-missing gh attestation verify Kule_0.2.0-preview.5_universal.dmg --repo kulehq/kule \ --signer-workflow kulehq/kule/.github/workflows/release.yml \ --source-ref refs/tags/v0.2.0-preview.5Or build it yourself:
cargo build --release -p kule -p kule-desktop.
A security preview. What an agent wrote opens with its app only as Kule's
own checked copy, keeping to itself. On macOS a task's servers listen only
where you allow them, and the system's /tmp stays closed to it. The proxy
passes a tunnel only to the host it was opened to, and on hosts Kule holds
a secret for, only your credentials.
Security
- Open with its app opens Kule's own copy of the file, made before it is
checked and readable only by you, without the file's extended attributes,
and on macOS marked as downloaded. Kule looks inside Word, Excel,
PowerPoint, OpenDocument and CSV files first, and opens none that holds
macros, controls or embedded objects, links to anything outside the file
but a web page or an email address, or has a field, formula or CSV cell
that fetches or runs something. Pages, Numbers, Keynote, EPUB and RTF
files are no longer opened with their app. - On macOS, while a task's network goes through the proxy, its programs do
not listen for connections unless you allow servers for it: the new
serverslimit (Settings → Limits,kule limits servers=on), off by
default. The macOS sandbox sees the port a server listens on but not its
address, so allowing servers is weaker isolation you accept under
Policy: Node, Python and Ruby servers are pointed at this computer, and
while an agent runs in the app the others are kept off your network from
outside the sandbox. A refused server is
listed after the command, with how to allow it. - On macOS a task's commands no longer write to the system's
/tmp, which
your other programs and tasks share:TMPDIR, and now zsh'sTMPPREFIX
and Claude Code'sCLAUDE_CODE_TMPDIR, point at the task's own temporary
directory. - A tunnel the proxy does not look inside goes on only once the client's
TLS hello asks for the host it was opened to, without hiding the name it
asks for; port 443 carries nothing but TLS. Plainhttp://requests are
read one by one, each for the host it was let through to. A cut
connection is logged ascut, with why. - On a host Kule holds a secret for, a request carries no credentials but
Kule's: headers and URL parameters named as credentials by any spelling,
Basicwith the placeholder as the password, and the fields of JSON and
multipart bodies as well as forms. That host is asked for whole responses
only, and a response that repeats a secret has it blanked in more of the
forms it can take (base64, escapes in either case), even split between
chunks. - For IPv6, only the global unicast range counts as public, with the IPv4
address inside 6to4 judged as itself. Host names are judged in lower
case and without a final dot.Content-Lengthtakes digits alone.
Kule 0.2.0-preview.4
Signed ad hoc. Kule's macOS app is signed ad hoc and not notarized by
Apple, so macOS refuses to open it the first time. After you have checked
the download (below), either open System Settings → Privacy & Security
and choose Open Anyway for Kule, or run once:xattr -dr com.apple.quarantine /Applications/Kule.appThe same goes for the
kulecommand from
kule-0.2.0-preview.4-macos-universal.tar.gzdownloaded in a browser:
xattr -d com.apple.quarantine kule.Check the download first. Every file comes with
SHA256SUMSand a build
provenance attestation, which says it was built from this repository by
this release's workflow:shasum -a 256 -c SHA256SUMS --ignore-missing gh attestation verify Kule_0.2.0-preview.4_universal.dmg --repo kulehq/kule \ --signer-workflow kulehq/kule/.github/workflows/release.yml \ --source-ref refs/tags/v0.2.0-preview.4Or build it yourself:
cargo build --release -p kule -p kule-desktop.
A security preview. Nothing an agent writes in Kule reaches your home:
Kule's own agents keep their settings, history and transcripts in a home
of their own in Kule, start every time from your settings as they are, and
anything else an agent writes in your home stays in the task's copy of it.
Security
- Nothing an agent writes in Kule reaches your home. Each of Kule's own
agents has a home of its own in Kule (CLAUDE_CONFIG_DIR,CODEX_HOME,
GEMINI_CLI_HOME), where its settings, history and transcripts in Kule
are kept across tasks;~/.claude,~/.codexand~/.geminiare hidden
from it. Sessions run in Kule before stay where they were. - At every start Kule copies your settings, hooks, skills, commands,
extensions, rules, trusted folders and instructions into that home,
read-only while the agent runs. Whatever an agent left there or beside
them, the shell snapshots Claude Code sources included, is gone at the
next start. Claude Code's plugins are not copied. - An agent's
stateis a copy in the task's home layer: the agent writes
there, and none of it is applied to your home or offered for review. - Codex signed in with ChatGPT signs in once more, in its home in Kule
(see Agents); Kule never copies that sign-in. Claude Code on Linux keeps
its sign-in in~/.claude/.credentials.json, which Kule reads and the
agent never sees, as on macOS with the keychain. - Profiles take
outside,carryandlogin_filefor the same in your
own agents.protectedis no longer needed; a profile that has it still
loads, andkule agents showsays so.
Kule 0.2.0-preview.3
Signed ad hoc. Kule's macOS app is signed ad hoc and not notarized by
Apple, so macOS refuses to open it the first time. After you have checked
the download (below), either open System Settings → Privacy & Security
and choose Open Anyway for Kule, or run once:xattr -dr com.apple.quarantine /Applications/Kule.appThe same goes for the
kulecommand from
kule-0.2.0-preview.3-macos-universal.tar.gzdownloaded in a browser:
xattr -d com.apple.quarantine kule.Check the download first. Every file comes with
SHA256SUMSand a build
provenance attestation, which says it was built from this repository by
this release's workflow:shasum -a 256 -c SHA256SUMS --ignore-missing gh attestation verify Kule_0.2.0-preview.3_universal.dmg --repo kulehq/kule \ --signer-workflow kulehq/kule/.github/workflows/release.yml \ --source-ref refs/tags/v0.2.0-preview.3Or build it yourself:
cargo build --release -p kule -p kule-desktop.
A security preview. Your terminals run in the task's sandbox, and the copy
opens outside it only when you choose, after seeing what changed. Secrets
you keep stay masked inside longer lines, and Kule's own files in a task's
temporary folder go only where it means them to. Releases now carry what
they are built from, and are checked before they are published.
Security
- A secret you keep is masked wherever it is in the settings files Kule
masks (the copy's.envfiles, and.zshrc,.profile,~/.envand
the like in the home layer): inside a longer value, in an alias, a
command or a comment, as it is or as a URL or JSON writes it. Secrets
kept for other folders are masked too, under placeholders no host
fills, since the home is the same for every folder. A commit or an
apply puts such a line back only where it is as Kule masked it, and no
more times than the file held it. - Anything in
.gitthat git does not keep as data (objects, refs, the
index, logs) counts as git config: it waits for you as git config does,
and keeps the terminal and the editor closed on the copy. - Kule's terminal,
kule shelland Open the copy in your editor wait
while an agent is at work in the task, and stay closed while the task
has changed a file that a shell prompt or an editor runs by itself: a
toolchain pin (rust-toolchain.toml,.nvmrc,.python-version,
.tool-versionsand the like),.envrc, an editor's settings and
tasks, and the rest of what theautomationrule names. The built-in
policy decides this, whatever policy you chose. - A change in another version control system's repository (Mercurial,
Sapling, Jujutsu, Darcs, Pijul, Bazaar, Subversion, Fossil), at any
depth, waits for you (other-vcs) and keeps the terminal and the editor
closed on the copy: its config and hooks run on its next command, and
Kule reads none of it as a repository. - The version pins a shell prompt reads on entering a folder (
.nvmrc,
.node-version,.python-version,.ruby-version,.java-version,
.go-version,.sdkmanrc,.terraform-version, mise's other files) and
*.code-workspacewait for you at commit (automation). - What Kule writes in a task's temporary folder (the proxy's certificate,
the loopback hooks, the package caches) goes through folders it opens
without following a link, and replaces whatever stands at the name. - The window's terminals and
kule shellrun your shell in the task's
sandbox, askule execruns a command, on a terminal of their own:
what you run there, and what your prompt runs by itself, reaches only
what the agent's commands reach.kule shell --outsideopens your
shell outside the sandbox, as before. - While a terminal is open on a task, no agent starts work there, and
commit, sync and applying home changes wait until you close it, rather
than ending what runs in it. - Open in terminal app, Open the copy in your editor and
kule shell --outsideshow the changes not committed yet and ask before they open
the copy outside the sandbox, each time. Kule remembers what it opened
the copy in, and before the task's next run asks you to close it
(kule closed TASKfrom a terminal). - The desktop app no longer depends on
portable-pty; its terminals use
the system's pseudo-terminals directly.
Fixes
- A setting that is only a switch (
true,false,yes,no,on,
off) or a number of fewer than 8 digits is no longer taken for a
secret because of its key (AUTH_ENABLED=true,MAX_TOKENS=4096); a
number stays one where the key names a password or a PIN. Masked, such a
setting stopped working in the task, and the task's proxy blanked the
same word in every response, so installs from crates.io and npm failed
for anyone whose home held one. - A search path or a folder under a key that names one
(PATH="$HOME/.cargo/bin:/opt/homebrew/bin:$PATH",GOPATH,
JAVA_HOME,XDG_DATA_DIRS) is no longer taken for a secret by its
length. It stays as it is in the task's.zshrc,.profileand.env
files and shows in their diff, so a login shell in the task finds its
tools. It stays masked where the key names a secret, where a part of it
is no path or looks like a token, and where a secret Kule keeps or
masked elsewhere is in it. - A file you save in your home while Kule makes a task's home layer is
compared with its clone once the disk's clock has moved on, as the
workspace copy already is, and cloned again when they differ. On a disk
whose clock is coarse, a same-size save then could go unseen: the layer
held what the file was before, and an apply wrote over your save. Each
file's stamp is now read by the clock of the disk the file is on.
Development
- The kule CLI in a release carries its dependency tree (built with
cargo-auditable), socargo audit binand other scanners can read what
is inside it. The release workflow audits the very binaries it is about
to publish, on macOS (each slice of the universal binary) and on Linux,
and the gate refuses a binary without that tree, of which cargo audit
reads only part. CI runs osv-scanner over every lockfile on every
change. - The release gate runs sandbox-probe in a task, against a home with
something at every path Kule hides, and installs, builds and tests real
projects in a task (ripgrep from crates.io, commander from npm). CI runs
both on macOS and Linux on every change; the release workflow runs them
on the binaries it is about to publish, and publishes nothing unless
they pass.
Kule 0.2.0-preview.2
Signed ad hoc. Kule's macOS app is signed ad hoc and not notarized by
Apple, so macOS refuses to open it the first time. After you have checked
the download (below), either open System Settings → Privacy & Security
and choose Open Anyway for Kule, or run once:xattr -dr com.apple.quarantine /Applications/Kule.appThe same goes for the
kulecommand from
kule-0.2.0-preview.2-macos-universal.tar.gzdownloaded in a browser:
xattr -d com.apple.quarantine kule.Check the download first. Every file comes with
SHA256SUMSand a build
provenance attestation, which says it was built from this repository by
this release's workflow:shasum -a 256 -c SHA256SUMS --ignore-missing gh attestation verify Kule_0.2.0-preview.2_universal.dmg --repo kulehq/kule \ --signer-workflow kulehq/kule/.github/workflows/release.yml \ --source-ref refs/tags/v0.2.0-preview.2Or build it yourself:
cargo build --release -p kule -p kule-desktop.
A small preview: up-to-date certificate checks, and the security model
says what Kule does not cover.
Security
- Every HTTPS connection Kule makes itself, its proxy's included, checks
certificates with webpki-roots 1.0.10 and rustls-webpki 0.103.16, which
no longer trust the distrusted emSign certificates (RUSTSEC-2026-0381,
RUSTSEC-2026-0382).
Documentation
- The security model has a section on what Kule does not cover. An action
with no copy, no diff and no undo (a click, a keystroke, a message sent
from an app on your screen) is refused in a task by design; tool calls
have no gate; and nothing outside a task is protected, even while Kule
is running.
Development
- A sandbox test no longer fails, or leaves a server running, on a Mac
with the application firewall on.
Kule 0.2.0-preview.1
Signed ad hoc. Kule's macOS app is signed ad hoc and not notarized by
Apple, so macOS refuses to open it the first time. After you have checked
the download (below), either open System Settings → Privacy & Security
and choose Open Anyway for Kule, or run once:xattr -dr com.apple.quarantine /Applications/Kule.appThe same goes for the
kulecommand from
kule-0.2.0-preview.1-macos-universal.tar.gzdownloaded in a browser:
xattr -d com.apple.quarantine kule.Check the download first. Every file comes with
SHA256SUMSand a build
provenance attestation, which says it was built from this repository by
this release's workflow:shasum -a 256 -c SHA256SUMS --ignore-missing gh attestation verify Kule_0.2.0-preview.1_universal.dmg --repo kulehq/kule \ --signer-workflow kulehq/kule/.github/workflows/release.yml \ --source-ref refs/tags/v0.2.0-preview.1Or build it yourself:
cargo build --release -p kule -p kule-desktop.
The first preview: the macOS app (universal) and Linux .deb and .rpm
packages, with the kule command-line tool inside each, and the tool
alone for each system. Expect changes from one preview to the next.
Tasks on a copy of any folder
- A task is a copy-on-write copy of a folder: code, notes, photos or data.
Everything an agent does there is one uncommitted transaction; commit
applies it with a checkpoint, rollback throws it away, undo reverts the
last commit. Checkpoints live in a Lonca store, and every commit and undo
is an entry in a signed, hash-chained history. - Review shows what changed inside each file (methods, sections, keys), a
picture before and after, moves told apart from deletions, and where two
tasks on one folder meet. A file two tasks changed merges method by
method; only the same parts changed twice conflict. - Writes in your home directory (
~/.zshrc,git config --global) are
caught for review, with a line diff, a mark on files that run at every
start, and undo.
A sandbox and a policy
- Commands run in Seatbelt on macOS and Landlock (with a network namespace
of their own) on Linux: they write only to the copy, credentials are
hidden, and the network goes through the task's proxy. - Kule's home is hidden from a task's commands, but for the task's own
copy and tmp: the one the task is in, and~/.kuletoo when the task's
is another (--home,KULE_HOME). - A Cedar policy decides what passes, what waits for you and what never
passes. Choose Kule's balanced or careful one, or write your own; a
repository can add refusals. What you approve can be remembered. - Secrets reach the hosts they are for and never the agent: it sees a
placeholder, and the proxy fills in the value, in headers and bodies.
The built-in agents' API keys go the same way.
Agents
- Claude Code, Codex and Gemini over the Agent Client Protocol, each with
a profile that opens only its own state and login. Add any other ACP
agent from the registry or by hand; it runs once you approve what it
opens, and a trial suggests what it needs. - Costs as the agents report them, with a budget per task and a daily one
for every task together, and a notice at 80%.
The app
- Live stream, approval inbox, review and timeline, around a daemon that
keeps the runs going when the window is closed. - Tasks with names, colours and an order of your own; a ⋮ menu on each.
- Settings for agents, the policy, remembered rules, secrets and the
budget, and a first-run screen that checks the agents and asks how
careful to be.
Documentation
- A documentation site, in English and Turkish, at
https://kulehq.github.io/kule/: install, a quick start, the concepts,
the desktop app panel by panel, a page for everykulecommand, the
files and settings Kule keeps, platforms, troubleshooting, and a video
tour. It is built from the Markdown indocs/(website/). - The README is a shorter, task-first introduction: what Kule does, a
quick start from source, the commands at a glance and how to develop it.
Releases
- A version with
-(0.2.0-preview.1) is drafted as a GitHub
pre-release, never shown as the latest one. - Publishing a release can also put it on npm (
@kulehq/kule, a pointer
to the releases, under thepreviewdist-tag for a pre-release) and on
crates.io, each once a repository variable turns it on. Both use trusted
publishing in thereleaseenvironment, so no registry token is kept,
and the crates are built in a job that can mint no token.
Writes in your home
kule home TASK diff|apply|discardtakes a path however it is typed:
~/.zshrcunquoted (which the shell turns into your full home path),
quoted, or relative to your home. A path outside your home, or one with
.., is refused with a message that says so.- A home diff (
kule home TASK diff, Show in Review) hides what looks
like a secret on both sides, as‹hidden …›: settings named like keys,
tokens or passwords, the secrets Kule keeps, and anything shaped like a
token. One value has one mark in a diff, so a changed secret still
reads as changed.
Keeping up with the folder
- A task brings what its folder changed meanwhile into its copy: your own
edits, or another task's commit.kule sync TASK, Bring into the
copy under Review, the task's menu, or Mod+Shift+G.- A file only the folder changed comes in as it is; a file the task
changed too is merged by method, section or key and stays the task's
change; when anything does not merge, nothing comes in and Kule
names what both changed. - Commits, branches and staged files in the folder's repository come
in too; a branch both moved does not. - Settings files come in masked, the folder is only read, and steps
start over as after a commit. - The agent hears what came in at the start of its next turn.
- A file only the folder changed comes in as it is; a file the task
- Review, the task list and
kule statusshow what the folder changed
since the copy was last brought up to date, and which of those files
the task changed too.
Outside Kule
- A file of the copy opens with its app: right-click it in Files, ⌘O, or
Open with its app where the Preview does not show it (a PDF, a film)
or shows it in part (Word, Excel). Only documents, pictures, sound and
video that are what their name says, and only while no agent is at
work; never a program, a script, a web page or a file with macros. - Show in Finder (Files on Linux) points at a file, a folder or the
whole copy without opening it; Copy path copies where it is on disk. - The task's menu opens the copy in VS Code, Cursor or Zed, the ones the
computer has, refused like the terminal while the task changed the
copy's git config or hooks. The first time for each editor, Kule says
what an editor runs by itself from a folder and how to keep it from
doing so. kule open TASK FILEopens a file of the copy with its app, held to the
same kinds and checks (--dry-runchecks it and prints where it is).
kule path TASK FILEprints where a file of the copy is, andkule pathsays on stderr when git in the copy would run what the task
changed.- Opening a file with its app also waits while an agent
kule run
started is at work.
Disk space
- The guide says what a task really takes on disk, on macOS and on
Linux, and why Finder anddushow more than that.
Budgets and limits for a group
- A group has a budget and limits of its own. Its tasks share the budget:
over all of their runs, over any 24 hours, or both. Its limits hold each
of its tasks where the task sets none of its own, and every task's hold
where the group sets none. - Every budget over a run holds, its own, its group's and the daily one
for every task, and the tightest decides; a refusal names the budget
that is spent. A run counts for the group its task was in when it ran. - Settings → Budget and Settings → Limits show one scope at a time, picked
under Applies to: every task, one group or one task. The scope is named
in capitals with whom it holds, each choice says where an inherited
value comes from, a task's scope lists every budget over its next run
and the one that holds, and each change is confirmed with the scope's
name. A group's ⋮ menu opens its budget and limits. - Moving a task into or out of a group asks first when its limits or group
budgets would change, and says how. - A notice at 80% and when it is spent, as for a task's budget, now also
for a group's budgets and the daily one for every task, each named. A
24-hour budget that drops below 80% again is told again when it nears. kule limitsshows and sets every task's limits,--group IDa group's
and--task TASKa task's, each line naming the scope its value comes
from.kule group budget ID AMOUNT [--daily]sets a group's budgets,
andkule budget TASKwithout an amount lists every budget over the
task's next run.- A run slowed to its processor limit keeps to it, on a busy computer
too: what its processes take before Kule first sees them counts, and
so does a slice that ran longer than planned. Before, a run held to
40% could get about half of a core. - A slowed run that goes quiet, waiting on a timer or the network, runs
on; before, it could stay paused until its time limit.
The window
- The left and right sides grow as far as the window allows, and the
bottom panel as high: the main area between them always keeps at least
360 pixels across and 160 high. A window made smaller takes the room
from the sides first, and gives it back when it grows again. - Settings → Agents shows each agent as one line, its name, where it
comes from, whether it can run, h...