task-ui

command module
v0.0.0-...-284f467 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

README

Task UI

Run what your source trees declare, from the browser, and watch it run. Task UI looks at each folder under a root, detects the conventions it follows, and lists their targets as jobs: atkins pipelines, Taskfiles, Makefile targets, package.json and composer.json scripts, and a scripts/ folder. A job runs as a session on the server: a process on a terminal that anyone allowed can attach to, from any window, for as long as it runs.

Projects live in workspaces: a directory with a home, the checkout of shared tooling that the workspace's runs get as HOME, its checkouts side by side under src, its own secrets and SSH keys, and an export that moves it, keys and all, to another instance. A project's Files panel browses its checkout like a file manager: a file opens in a preview window. Every folder and directory has the git state of its checkout and one Jobs table of what runs there: its targets, the files that run, the jobs of each atkins skill that applies, and, for an admin, a shell and Claude Code in a terminal in that directory.

Claude works beside the jobs. A prompt asks Claude Code in a folder, a directory, about a run, from the header on any page, or at the end of a workflow, and Claude's reply lands under the question. |> Summarize runs a job and has Claude summarise the run. The Notes board takes messages and replies, and a note naming a user with @name is an instruction to that user: to the agent, which works on it at once, or to an agent elsewhere over MCP. The MCP server at /api/mcp serves an agent the same jobs, runs, notes and prompts, as a user with a token of its own. Permissions decide, per role and per user, what each may view, edit, delete and run. The inventory lists the hosts Beszel watches and runs a command on every one at once.

The usage guide shows how to use it, a chapter per section of the sidebar: the dashboard, the inventory, workflows, runs, artifacts, schedules, notes, the projects and their jobs, the workspaces that hold projects, the recents, the modules, the settings, and MCP, for an agent that runs jobs. This README links to the rest.

A module is a plugin written in PHP, run inside the binary by phpscript and served at /m/<vendor>/<name> as an ordinary page: the layout is the instance's, the body is the module's, and nothing loads in an iframe. A directory with a modinfo.php in it is a module. titpetric/refinement ships with it: a thread of comments, each one a Claude run that writes artifacts and the README.md that indexes them.

The look follows oida: hairlines, one amber accent, dark and light from prefers-color-scheme. The type is a dashboard pair, Inter for the words and JetBrains Mono for the data, both vendored under frontend/view/assets/fonts/ with their licenses. The binary embeds all assets, and the front end makes no external requests.

Documents

Document What is in it
Usage guide The screen, a chapter per sidebar section, and MCP
Running the server The Docker image, the environment, users, roles and the server commands
API The JSON endpoints and the MCP server
Security The threat model, identity and roles, keys, secrets, terminals and agents, and the review's findings
Development The packages, the lint and test bar, the prose gate and the screenshots
Modules Writing a plugin in PHP: the directory, the bindings, and what the runtime refuses
Corrections Where the PHP runtime lacks what the module system needs, and what the code does instead
Testing Unit tests by default, integration tests behind a build tag

A quick start, with the compose file in Running the server:

task docker:run

Development

The packages, the lint and test bar and the screenshots are in docs/development.md. The tasks:

task: Available tasks for this project:

  • default: Run everything
  • fix: Fix code
  • install: Install task-ui
  • lint: Lint with splint, rulelint and vale, zero findings is the bar
  • run: Run task-ui over the demo projects
  • test: Run the unit tests
  • docker:build: Build task-ui docker image
  • docker:gen: Generate an ssh key for the key folder, ./keys
  • docker:run: Run task-ui in docker env
  • docs:shots: Regenerate the README screenshots
  • lint:docs: Report the prose findings of the markdown, Go, PHP, JavaScript and CSS
  • test:cover: Report unit test coverage per package
  • test:duplicate: Report the coverage two tests share
  • test:integration: Run the integration tests: processes, databases and the network
  • test:scope: Run the tests of what changed, inside the 1s per test budget

task: default

Run everything

commands:

  • Task: fix- Task: lint- Task: install- Task: test

task: test

Run the unit tests

commands:

  • go test ./...

task: test:scope

The packages a change touched and the packages that import them, from git and go list, with every test held to a second. Takes the flags of scripts/test.sh: task test:scope -- --all

commands:

  • scripts/test.sh

task: test:duplicate

Report the coverage two tests share

commands:

  • scripts/test-duplicate.sh

task: test:integration

One go test per package, batched by test name, under a memory cap, so a package that holds more than the cap fits cannot take the suite down. Takes a package pattern: task test:integration -- ./storage/...

commands:

  • scripts/test-integration.sh

task: test:cover

Report unit test coverage per package

commands:

  • go test -cover ./...

task: run

Run task-ui over the demo projects

commands:

  • go run .

task: docs:shots

Regenerate the README screenshots

commands:

  • scripts/demo.sh

task: lint

Lint with splint, rulelint and vale, zero findings is the bar

commands:

  • splint ./...- go run ./internal/cmd/rulelint

task: lint:docs

Report the prose findings of the markdown, Go, PHP, JavaScript and CSS

commands:

  • git ls-files --cached --others --exclude-standard | grep -E '\.(md|go|php|js|css)$' | xargs -r vale

task: install

Install task-ui

commands:

  • CGO_ENABLED=0 go install .

task: fix

Fix code

dependencies:

  • deps:splint commands:
  • splint fix ./...- go vet ./...- go mod tidy- ./README.md.sh > README.md

Documentation

Overview

Command task-ui serves a web console for the jobs of a directory tree: pipelines, Makefiles, package scripts and shell scripts, run in a terminal everyone can watch.

Directories

Path Synopsis
Package access is who may do what: the passwords users sign in with and the sessions they carry.
Package access is who may do what: the passwords users sign in with and the sessions they carry.
Package agent holds task-ui's host commands, the commands of the Claude built-ins every folder has: Claude Code on a note from the Notes board, @claude-note, on a prompt, @claude-prompt, and in a terminal, @claude.
Package agent holds task-ui's host commands, the commands of the Claude built-ins every folder has: Claude Code on a note from the Notes board, @claude-note, on a prompt, @claude-prompt, and in a terminal, @claude.
Package api implements the JSON endpoints of task-ui: the folders and their jobs, runs and their frames, artifacts, schedules, projects, workspaces, users and secrets, and the websocket a window attaches to a run with.
Package api implements the JSON endpoints of task-ui: the folders and their jobs, runs and their frames, artifacts, schedules, projects, workspaces, users and secrets, and the websocket a window attaches to a run with.
Package app is the composition root: it reads the configuration, opens the database, builds the runner, the scheduler, the API and the front end, and serves them.
Package app is the composition root: it reads the configuration, opens the database, builds the runner, the scheduler, the API and the front end, and serves them.
Package argv reads the arguments a user types for a job into a list, the way a shell splits words and nothing more: quotes and backslashes group, and no variable, glob, pipe or command substitution expands.
Package argv reads the arguments a user types for a job into a list, the way a shell splits words and nothing more: quotes and backslashes group, and no variable, glob, pipe or command substitution expands.
Package artifactstore keeps the files runs leave behind as one tree: the latest version of every path any run wrote, with the earlier versions in the history of a git repository around it.
Package artifactstore keeps the files runs leave behind as one tree: the latest version of every path any run wrote, with the earlier versions in the history of a git repository around it.
Package beszel reads the systems of a Beszel hub, which watches the hosts, for task-ui's host inventory.
Package beszel reads the systems of a Beszel hub, which watches the hosts, for task-ui's host inventory.
Package channel is `task-ui channel`: a stdio MCP server that pushes the notes naming the token's user into an open Claude Code session, as a Claude Code channel.
Package channel is `task-ui channel`: a stdio MCP server that pushes the notes naming the token's user into an open Claude Code session, as a Claude Code channel.
Package claude runs Claude Code for task-ui's own uses, such as the summary of a command's output on the inventory's hosts.
Package claude runs Claude Code for task-ui's own uses, such as the summary of a command's output on the inventory's hosts.
Package config holds the configuration task-ui embeds: the rules of permissions.yml, which every permission check names, and context.md, what task-ui is, for an agent.
Package config holds the configuration task-ui embeds: the rules of permissions.yml, which every permission check names, and context.md, what task-ui is, for an agent.
Package detector reads the conventions a folder follows: a pipeline file, a Makefile, package scripts, a scripts directory.
Package detector reads the conventions a folder follows: a pipeline file, a Makefile, package scripts, a scripts directory.
Package diskusage measures how much space a directory takes, split into its files and the git history beside them in .git.
Package diskusage measures how much space a directory takes, split into its files and the git history beside them in .git.
Package dotenv writes KEY=VALUE lines the way atkins and Taskfiles read them.
Package dotenv writes KEY=VALUE lines the way atkins and Taskfiles read them.
Package envfile keeps the dotenv files of older instances: a workspace bundle carries them, and an import writes them into the folder.
Package envfile keeps the dotenv files of older instances: a workspace bundle carries them, and an import writes them into the folder.
Package event is the bus the pages follow: a publisher names a topic and an event, and every subscriber of the topic gets it.
Package event is the bus the pages follow: a publisher names a topic and an event, and every subscriber of the topic gets it.
Package folder is the catalogue: a folder is a working directory and the targets found in it, and a job is one of those targets with an identity inside the folder.
Package folder is the catalogue: a folder is a working directory and the targets found in it, and a job is one of those targets with an identity inside the folder.
Package forgejo syncs a Forgejo instance into task-ui: each organisation the token's user belongs to, and each user whose repositories the token reads, is a workspace, the repository named like the owner is its home, every other repository a project cloned into its src, and a push hook on each the token administers keeps the checkouts fresh.
Package forgejo syncs a Forgejo instance into task-ui: each organisation the token's user belongs to, and each user whose repositories the token reads, is a workspace, the repository named like the owner is its home, every other repository a project cloned into its src, and a push hook on each the token administers keeps the checkouts fresh.
Package frontend serves the pages of task-ui: the sign in screen, the dashboard, the folders and their jobs, the runs, the artifacts, the schedules and the settings.
Package frontend serves the pages of task-ui: the sign in screen, the dashboard, the folders and their jobs, the runs, the artifacts, the schedules and the settings.
view
Package view renders the pages of task-ui: the templates, the page model they bind to and the embedded assets.
Package view renders the pages of task-ui: the templates, the page model they bind to and the embedded assets.
Package highlight draws the files a folder's pipeline reads as coloured HTML: YAML pipelines and Taskfiles, Makefiles, and anything else as escaped text.
Package highlight draws the files a folder's pipeline reads as coloured HTML: YAML pipelines and Taskfiles, Makefiles, and anything else as escaped text.
Package hostinfo reads what a host of the inventory holds beyond what Beszel reports: its filesystems and its containers' sizes, over the ssh login task-ui has to it, and puts the two sources together for the Inventory page: the containers of a host, its durable filesystems and the pools of the cluster.
Package hostinfo reads what a host of the inventory holds beyond what Beszel reports: its filesystems and its containers' sizes, over the ssh login task-ui has to it, and puts the two sources together for the Inventory page: the containers of a host, its durable filesystems and the pools of the cluster.
Package hostpath maps the paths of the container task-ui runs in to the paths of its host: a job's `docker run -v $PWD:/src` goes to the host's docker daemon, which resolves the path on the host.
Package hostpath maps the paths of the container task-ui runs in to the paths of its host: a job's `docker run -v $PWD:/src` goes to the host's docker daemon, which resolves the path on the host.
Package hostrun starts the runs of @host:<host>: a command on hosts of the inventory, over the ssh login task-ui has to each, as ordinary runs of the root's host jobs, one per host, so each has a row, a recording, a place in the recents and the run history, and can run again.
Package hostrun starts the runs of @host:<host>: a command on hosts of the inventory, over the ssh login task-ui has to each, as ordinary runs of the root's host jobs, one per host, so each has a row, a recording, a place in the recents and the run history, and can run again.
Package hours decides when a job may run: the rules an admin writes for a folder, such as "mon-fri 9-17" and "fri 9-13", and whether a moment falls inside them.
Package hours decides when a job may run: the rules an admin writes for a folder, such as "mon-fri 9-17" and "fri 9-13", and whether a moment falls inside them.
Package integration keeps the settings of the services task-ui talks to, such as Claude Code and Beszel: API keys, tokens, addresses.
Package integration keeps the settings of the services task-ui talks to, such as Claude Code and Beszel: API keys, tokens, addresses.
internal
assert
Package assert is a minimalistic drop-in replacement for testify/assert.
Package assert is a minimalistic drop-in replacement for testify/assert.
cmd/fakehub command
Command fakehub is a Beszel hub for the inventory's screenshots: three hosts, one with an extra disk and one down, their latest minute, their containers, and a month of eight hour records drawn from smooth curves, a gap of two days in one host's and the down host's ending when it went down.
Command fakehub is a Beszel hub for the inventory's screenshots: three hosts, one with an extra disk and one down, their latest minute, their containers, and a month of eight hour records drawn from smooth curves, a gap of two days in one host's and the down host's ending when it went down.
cmd/rulelint command
Command rulelint matches the permission checks of task-ui against the embedded `config/permissions.yml` and prints each mismatch: a check of a rule the configuration does not hold, and a rule nothing checks.
Command rulelint matches the permission checks of task-ui against the embedded `config/permissions.yml` and prints each mismatch: a check of a rule the configuration does not hold, and a rule nothing checks.
rulelint
Package rulelint matches the permission checks of the code against `config/permissions.yml`: every rule a check names is one the configuration holds, and a check names every rule the configuration holds.
Package rulelint matches the permission checks of the code against `config/permissions.yml`: every rule a check names is one the configuration holds, and a check names every rule the configuration holds.
testdb
Package testdb hands a test a migrated database without migrating one.
Package testdb hands a test a migrated database without migrating one.
testkey
Package testkey hands a test key material without generating any.
Package testkey hands a test key material without generating any.
Package keystore keeps every key of the instance in one folder, flat: <name>.key, the private key, and <name>.pub, beside known_hosts.
Package keystore keeps every key of the instance in one folder, flat: <name>.key, the private key, and <name>.pub, beside known_hosts.
Package layout maps folder IDs to directories under the root.
Package layout maps folder IDs to directories under the root.
Package markdown renders the markdown files runs leave, and the notes and answers people and Claude write, as HTML, with blackfriday, the renderer the blog on incubator.to uses.
Package markdown renders the markdown files runs leave, and the notes and answers people and Claude write, as HTML, with blackfriday, the renderer the blog on incubator.to uses.
Package mcp serves task-ui to MCP clients, such as an agent that runs jobs: JSON-RPC over the streamable HTTP transport, at /api/mcp.
Package mcp serves task-ui to MCP clients, such as an agent that runs jobs: JSON-RPC over the streamable HTTP transport, at /api/mcp.
Package note is the notes board: messages users leave for each other, the replies to them, and the notes that hand someone an instruction.
Package note is the notes board: messages users leave for each other, the replies to them, and the notes that hand someone an instruction.
Package permission decides what a user may do, from the rules of `config/permissions.yml` and the policies of the user and the user's role.
Package permission decides what a user may do, from the rules of `config/permissions.yml` and the policies of the user and the user's role.
Package phpscript is the plugin boundary: a module is a directory with a modinfo.php in it, run by the phpscript interpreter the binary holds, served at /m/<vendor>/<name> as the body of an ordinary task-ui page.
Package phpscript is the plugin boundary: a module is a directory with a modinfo.php in it, run by the phpscript interpreter the binary holds, served at /m/<vendor>/<name> as the body of an ordinary task-ui page.
Package phpscripts holds the modules that ship with the instance, as a PHP source tree embedded in the binary.
Package phpscripts holds the modules that ship with the instance, as a PHP source tree embedded in the binary.
Package recording writes the terminal output of a run as an asciicast v2 file, which the run dialog plays back.
Package recording writes the terminal output of a run as an asciicast v2 file, which the run dialog plays back.
Package retention keeps what task-ui records within the rules of the Data retention settings: a table with one row per area of data, the recordings and the rows of runs, prompt threads, workflow runs, the history of the artifact tree and the secret read log, each kept for an age and, where items have a size, within a size, the oldest going first.
Package retention keeps what task-ui records within the rules of the Data retention settings: a table with one row per area of data, the recordings and the rows of runs, prompt threads, workflow runs, the history of the artifact tree and the secret read log, each kept for an age and, where items have a size, within a size, the oldest going first.
Package runner runs jobs and keeps them running: a session per run, detached from any window, with a terminal emulator behind it that holds the screen at every moment, windows that attach and detach, a lock that allows one run per job across the instance, and the artifacts a run leaves behind.
Package runner runs jobs and keeps them running: a session per run, detached from any window, with a terminal emulator behind it that holds the screen at every moment, windows that attach and detach, a lock that allows one run per job across the instance, and the artifacts a run leaves behind.
Package scheduler starts jobs on their own: cron expressions, when they fire next, and the loop that starts the due ones as detached runs.
Package scheduler starts jobs on their own: cron expressions, when they fire next, and the loop that starts the due ones as detached runs.
Package schema holds the SQL migrations of task-ui.
Package schema holds the SQL migrations of task-ui.
Package secret keeps the secrets encrypted at rest with age, to ed25519 or RSA keys kept for nothing else: the instance's one encryption key for every secret, the workspaces' and the services'.
Package secret keeps the secrets encrypted at rest with age, to ed25519 or RSA keys kept for nothing else: the instance's one encryption key for every secret, the workspaces' and the services'.
Package skills asks atkins what runs in a directory: its pipeline and the skills of the .atkins/skills folders above it whose condition holds there, each with the directory its jobs run in.
Package skills asks atkins what runs in a directory: its pipeline and the skills of the .atkins/skills folders above it whose condition holds there, each with the directory its jobs run in.
skillstest
Package skillstest is a stand-in atkins for the tests of the packages that probe skills: it lists a git skill in the nearest checkout and a compose skill beside a compose.yml, as the workspace skills do.
Package skillstest is a stand-in atkins for the tests of the packages that probe skills: it lists a git skill in the nearest checkout and a compose skill beside a compose.yml, as the workspace skills do.
Package sshagent serves the private keys of a directory to ssh, as an agent on a socket of its own: a checkout's .ssh/ folder, loaded for the runs of that checkout.
Package sshagent serves the private keys of a directory to ssh, as an agent on a socket of its own: a checkout's .ssh/ folder, loaded for the runs of that checkout.
Package sshkey manages the key pairs in the instance SSH folder: the identities jobs and git use to reach other hosts.
Package sshkey manages the key pairs in the instance SSH folder: the identities jobs and git use to reach other hosts.
Package sshprobe finds who task-ui can sign in to a host as over ssh: the first of a list of users whose login works with the instance keys, tried in batch mode, so a host that only takes a password counts as closed.
Package sshprobe finds who task-ui can sign in to a host as over ssh: the first of a list of users whose login works with the instance keys, tried in batch mode, so a host that only takes a password counts as closed.
Package storage owns the SQL of task-ui.
Package storage owns the SQL of task-ui.
Package toolenv detects the tools of the environment task-ui starts in: the runtimes, the tooling and the instance's own tools, each with its version, its path and what it is used for.
Package toolenv detects the tools of the environment task-ui starts in: the runtimes, the tooling and the instance's own tools, each with its version, its path and what it is used for.
Package tooling asks atkins what a checkout has been running.
Package tooling asks atkins what a checkout has been running.
Package workflow runs workflows: named chains of jobs from any folders, started one after another as ordinary runs.
Package workflow runs workflows: named chains of jobs from any folders, started one after another as ordinary runs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL