Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
56dbbb7
feat: add first-class agent ops commands
OneNoted Mar 21, 2026
eec3bd8
feat: surface agent ops in shell
OneNoted Mar 21, 2026
1269ba1
feat: add browser p0 automation parity
OneNoted Mar 21, 2026
0c8a158
feat: add terminal debug and identify parity
OneNoted Mar 21, 2026
c759869
test: cover terminal debug and identify flows
OneNoted Mar 21, 2026
89980ea
refactor: add notification lifecycle state
OneNoted Mar 21, 2026
30f600b
feat: deliver desktop notifications
OneNoted Mar 21, 2026
078d0e8
feat: persist notification preferences
OneNoted Mar 21, 2026
e11e9f9
feat: add cmux notification terminal protocol
OneNoted Mar 21, 2026
35b3cd4
docs: rewrite active taskers docs
OneNoted Mar 21, 2026
3683160
docs: add operator and release guides
OneNoted Mar 22, 2026
dca4397
feat: polish cross-workspace tab transfers
OneNoted Mar 22, 2026
1b21dc4
refactor: add shell-core surface drag sessions
OneNoted Mar 22, 2026
bf4aaba
feat: fix tab drag and tab-strip add controls
OneNoted Mar 22, 2026
76e5187
fix: restore tab drag and drop behavior
OneNoted Mar 22, 2026
98ab2eb
fix: keep native panes out of tab chrome
OneNoted Mar 22, 2026
23eb314
fix: replace broken tab drag with pointer interactions
OneNoted Mar 22, 2026
baa18b7
feat: add SVG icon module for shell UI
OneNoted Mar 22, 2026
1b024de
style: add border-radius, shadows, scrollbars, and backdrop polish
OneNoted Mar 22, 2026
7b81338
style: redesign sidebar with icons and compact brand
OneNoted Mar 22, 2026
488dbcb
style: redesign pane toolbar and tab strip with icons
OneNoted Mar 22, 2026
c8f7a5b
style: polish browser toolbar and surface backdrop
OneNoted Mar 22, 2026
e919e9b
style: polish settings toggles and notification panel
OneNoted Mar 22, 2026
92019a9
chore: remove unused icons and dead CSS cleanup
OneNoted Mar 22, 2026
2e3914c
feat: simplify pane and window chrome
OneNoted Mar 22, 2026
4e6eb54
fix: restore settings scrolling
OneNoted Mar 22, 2026
65a46e8
refactor(domain): separate agent-hook notification context from termi…
OneNoted Mar 22, 2026
15d556d
feat(shell): add runtime-aware snapshots and workspace icons
OneNoted Mar 22, 2026
33bd954
refactor(ghostty): make embedded config overrides explicit and minimal
OneNoted Mar 22, 2026
a14741f
docs(usage): document embedded ghostty config inheritance
OneNoted Mar 22, 2026
bf9b96d
chore(dev): point local launcher workflows at cargo-bin installs
OneNoted Mar 23, 2026
0334b5b
fix(ghostty): restore embedded terminal surface startup
OneNoted Mar 23, 2026
bac087a
fix(shell): stabilize surface drag state
OneNoted Mar 23, 2026
3ce9954
fix(startup): hide ghostty self-probe window
OneNoted Mar 23, 2026
e5067e9
feat(shell-core): expose surface activity and status labels
OneNoted Mar 23, 2026
15a1b11
feat(shell): show active task and agent state in pane headers and tabs
OneNoted Mar 23, 2026
5ba8a62
test(shell): cover activity and status label rendering
OneNoted Mar 23, 2026
a422e57
fix(shell): show runtime badge in pane selector
OneNoted Mar 23, 2026
a12b1ad
fix(notifications): repair center dismiss action
OneNoted Mar 23, 2026
f1b2ac5
fix(notifications): hide cleared items from center
OneNoted Mar 24, 2026
dddad5c
feat(attention): derive agent notification ring state
OneNoted Mar 24, 2026
3f0a9b7
feat(shell): style agent attention rings
OneNoted Mar 24, 2026
0e9a767
fix(shell): strengthen agent attention ring styling
OneNoted Mar 24, 2026
aee8878
fix(shell): surround panes with attention ring
OneNoted Mar 24, 2026
8199de6
fix(shell): surround panes with attention ring
OneNoted Mar 24, 2026
c8b6f1a
fix(host): render pane notification rings in native overlays
OneNoted Mar 24, 2026
f827965
fix(host): raise pane notification rings above terminal surfaces
OneNoted Mar 24, 2026
1f842fd
fix(domain): retain agent metadata for notification rings
OneNoted Mar 24, 2026
30ae58c
fix(shell): key surface tabs by identity
OneNoted Mar 24, 2026
21110b1
fix(shell-core): keep terminal targets bound to surfaces
OneNoted Mar 24, 2026
2d1a905
fix(notifications): require pane context for implicit notify targets
OneNoted Mar 24, 2026
1f13a86
fix(runtime): bind embedded notifications to pane tty
OneNoted Mar 24, 2026
59d5dfc
fix(cli): harden Codex notify helper targeting
OneNoted Mar 24, 2026
2ce18de
refactor(shell): remove sidebar branding, nav toggle, and section header
OneNoted Mar 24, 2026
df35e28
refactor(shell): replace dead sidebar-nav-icon CSS with settings-icon…
OneNoted Mar 25, 2026
8a9ba9c
feat(core): add workspace-window tab plumbing
OneNoted Mar 25, 2026
8688b37
feat(shell): add window-tab chrome and terminal gutter
OneNoted Mar 25, 2026
5d877b9
fix(packaging): preserve desktop integration and Ghostty themes
OneNoted Mar 27, 2026
190ac55
chore(release): bump workspace version to 0.3.1
OneNoted Mar 27, 2026
1e874a7
fix(ci): stabilize release asset workflow
OneNoted Mar 27, 2026
250ec2a
fix(launcher): migrate legacy desktop entries
OneNoted Mar 27, 2026
cfdc45e
fix(runtime): harden agent shims and kitty notifications
OneNoted Mar 27, 2026
a42a936
fix(pr): address follow-up review comments
OneNoted Mar 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions .github/workflows/release-assets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
- name: Run headless app smoke
run: |
TASKERS_TERMINAL_BACKEND=mock \
TIMEOUT_SECONDS=90 \
bash scripts/headless-smoke.sh \
./target/debug/taskers-gtk \
--smoke-script baseline \
Expand All @@ -63,14 +64,19 @@ jobs:
- name: Build Linux bundle
run: bash scripts/build_linux_bundle.sh

- name: Build Ghostty runtime bundle
run: bash scripts/build_ghostty_runtime_bundle.sh

- name: Run launcher smoke
run: bash scripts/smoke_linux_release_launcher.sh
run: TIMEOUT_SECONDS=90 bash scripts/smoke_linux_release_launcher.sh

- name: Upload Linux bundle
- name: Upload release assets
uses: actions/upload-artifact@v4
with:
name: linux-bundle
path: dist/taskers-linux-bundle-v*.tar.xz
name: release-assets
path: |
dist/taskers-linux-bundle-v*.tar.xz
dist/taskers-ghostty-runtime-v*.tar.xz

release-manifest:
needs:
Expand Down Expand Up @@ -124,6 +130,7 @@ jobs:
echo 'files<<EOF'
echo 'dist/release/taskers-manifest-v*.json'
echo 'dist/release/taskers-linux-bundle-v*.tar.xz'
echo 'dist/release/taskers-ghostty-runtime-v*.tar.xz'
echo 'EOF'
} >> "$GITHUB_OUTPUT"

Expand Down
29 changes: 17 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ edition = "2024"
homepage = "https://github.com/OneNoted/taskers"
license = "MIT OR Apache-2.0"
repository = "https://github.com/OneNoted/taskers"
version = "0.3.0"
version = "0.3.1"

[workspace.dependencies]
adw = { package = "libadwaita", version = "0.9.1" }
Expand All @@ -47,12 +47,12 @@ ureq = "2.12"
uuid = { version = "1.22.0", features = ["serde", "v7"] }
webkit6 = { version = "0.6.1", features = ["v2_50"] }
xz2 = "0.1"
taskers-core = { version = "0.3.0", path = "crates/taskers-core" }
taskers-control = { version = "0.3.0", path = "crates/taskers-control" }
taskers-domain = { version = "0.3.0", path = "crates/taskers-domain" }
taskers-ghostty = { version = "0.3.0", path = "crates/taskers-ghostty" }
taskers-host = { version = "0.3.0", path = "crates/taskers-host" }
taskers-paths = { version = "0.3.0", path = "crates/taskers-paths" }
taskers-runtime = { version = "0.3.0", path = "crates/taskers-runtime" }
taskers-shell = { version = "0.3.0", path = "crates/taskers-shell" }
taskers-shell-core = { version = "0.3.0", path = "crates/taskers-shell-core" }
taskers-core = { version = "0.3.1", path = "crates/taskers-core" }
taskers-control = { version = "0.3.1", path = "crates/taskers-control" }
taskers-domain = { version = "0.3.1", path = "crates/taskers-domain" }
taskers-ghostty = { version = "0.3.1", path = "crates/taskers-ghostty" }
taskers-host = { version = "0.3.1", path = "crates/taskers-host" }
taskers-paths = { version = "0.3.1", path = "crates/taskers-paths" }
taskers-runtime = { version = "0.3.1", path = "crates/taskers-runtime" }
taskers-shell = { version = "0.3.1", path = "crates/taskers-shell" }
taskers-shell-core = { version = "0.3.1", path = "crates/taskers-shell-core" }
80 changes: 67 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
# taskers
# Taskers

Taskers is a Linux-first terminal workspace for agent-heavy work. It provides
Niri-style top-level windows, local pane splits, tabs inside panes, and an
attention rail for active and completed work.
Taskers is a Linux-first terminal workspace for agent-heavy work. It combines:

- top-level workspace windows that behave like a tiling canvas
- panes inside each window
- tabs inside each pane
- an attention rail for unread, waiting, error, and completed work
- a local control CLI for notifications, agent state, browser automation, and debugging

The active product lives at the repo root. Archived pre-cutover GTK/AppKit code
is kept under `taskers-old/` for reference only.

## Try it
## Documentation

- [Daily usage](docs/usage.md)
- [Notifications and attention](docs/notifications.md)
- [Taskersctl operator guide](docs/taskersctl.md)
- [Release checklist](docs/release.md)

## Install

Linux (`x86_64-unknown-linux-gnu`):

Expand All @@ -16,12 +27,54 @@ cargo install taskers --locked
taskers
```

The first launch downloads the exact version-matched Linux bundle from the tagged
GitHub release. The Linux app requires GTK4/libadwaita plus the host WebKitGTK
6.0 runtime.
The first launch downloads the exact version-matched Linux bundle from the
tagged GitHub release. The Linux app requires GTK4/libadwaita plus the host
WebKitGTK 6.0 runtime.

Mainline macOS support is currently not shipped from this repo root.

## First 5 Minutes

Start Taskers:

```bash
taskers
```

Keep the workspace model straight:

- A workspace contains top-level workspace windows.
- A workspace window contains panes.
- A pane contains tabs.
- Scrolling/panning is a workspace-window concern. Splits and tabs stay local to the current window.

Open a terminal in Taskers and emit a test notification:

```bash
taskersctl notify --title "Taskers" --body "Hello from the current pane"
```

You should see:

- an unread badge in the sidebar
- a notification row in the attention rail
- a desktop banner unless the target is already visible and notification suppression is enabled

Try the built-in shell helpers from a Taskers terminal:

```bash
taskers_waiting "Need review"
taskers_done "Finished"
taskers_error "Build failed"
```

Open a browser pane from the pane controls, then inspect it from the same Taskers terminal:

```bash
taskersctl browser snapshot
taskersctl browser get title
```

## Develop

On Ubuntu 24.04, install the Linux UI dependencies first:
Expand All @@ -30,13 +83,14 @@ On Ubuntu 24.04, install the Linux UI dependencies first:
sudo apt-get install -y libgtk-4-dev libadwaita-1-dev libjavascriptcoregtk-6.0-dev libwebkitgtk-6.0-dev xvfb
```

Run the app directly:
Install the app into Cargo's bin directory, then run it from there:

```bash
cargo run -p taskers-gtk --bin taskers-gtk
cargo install --path crates/taskers-app --force
taskers-gtk
```

Point the desktop launcher at the repo-local dev build:
Point the desktop launcher at that Cargo-bin install:

```bash
bash scripts/install-dev-desktop-entry.sh
Expand All @@ -47,10 +101,10 @@ Run the headless baseline smoke:
```bash
TASKERS_TERMINAL_BACKEND=mock \
bash scripts/headless-smoke.sh \
./target/debug/taskers-gtk \
"$(command -v taskers-gtk)" \
--smoke-script baseline \
--diagnostic-log stderr \
--quit-after-ms 5000
```

Release checklist: [docs/release.md](docs/release.md)
For publishing and release prep, use [docs/release.md](docs/release.md).
2 changes: 1 addition & 1 deletion assets/taskers.desktop.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ Icon=taskers
Terminal=false
Categories=Development;
StartupNotify=true
StartupWMClass=taskers
StartupWMClass=dev.taskers.app
X-GNOME-UsesNotifications=true
7 changes: 7 additions & 0 deletions crates/taskers-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ publish = false
name = "taskers-gtk"
path = "src/main.rs"

[[bin]]
name = "taskersctl"
path = "src/bin/taskersctl.rs"

[dependencies]
adw.workspace = true
anyhow.workspace = true
Expand All @@ -21,6 +25,8 @@ clap.workspace = true
dioxus.workspace = true
dioxus-liveview.workspace = true
gtk.workspace = true
serde.workspace = true
serde_json.workspace = true
taskers-control.workspace = true
taskers-core.workspace = true
taskers-domain.workspace = true
Expand All @@ -30,5 +36,6 @@ taskers-paths.workspace = true
taskers-runtime.workspace = true
taskers-shell.workspace = true
taskers-shell-core.workspace = true
time.workspace = true
tokio.workspace = true
webkit6.workspace = true
50 changes: 50 additions & 0 deletions crates/taskers-app/assets/taskers-codex-notify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/sh
set -eu

payload=${1-}
message=
taskers_ctl=${TASKERS_CTL_PATH:-}

if [ -z "$taskers_ctl" ] && command -v taskersctl >/dev/null 2>&1; then
taskers_ctl=$(command -v taskersctl)
fi

if [ -n "$payload" ]; then
if command -v jq >/dev/null 2>&1; then
message=$(
printf '%s' "$payload" \
| jq -r '."last-assistant-message" // .message // .title // empty' 2>/dev/null \
| head -c 160
)
fi
fi

if [ -z "$message" ]; then
message="Turn complete"
fi

has_embedded_surface_context() {
[ -x "${taskers_ctl:-}" ] || return 1
[ -n "${TASKERS_WORKSPACE_ID:-}" ] || return 1
[ -n "${TASKERS_PANE_ID:-}" ] || return 1
[ -n "${TASKERS_SURFACE_ID:-}" ] || return 1
[ -n "${TASKERS_TTY_NAME:-}" ] || return 1

current_tty=$(tty 2>/dev/null || true)
case "$current_tty" in
/dev/*) ;;
*) return 1 ;;
esac

[ "$current_tty" = "$TASKERS_TTY_NAME" ] || return 1
}

if has_embedded_surface_context; then
"$taskers_ctl" agent-hook stop \
--workspace "$TASKERS_WORKSPACE_ID" \
--pane "$TASKERS_PANE_ID" \
--surface "$TASKERS_SURFACE_ID" \
--agent codex \
--title Codex \
--message "$message" >/dev/null 2>&1 || true
fi
Loading
Loading