Skip to content

API Integrations

kasl talks to three kinds of external service: GitLab (through a plugin) and Jira supply candidate tasks, Jira also hears when you start and finish an issue, and a corporate reporting API receives the finished day. All three are optional - kasl records the workday without any of them.

Service Direction What it is for
GitLab (plugin) reads, writes Today’s commits become candidate tasks in kasl task find; assigned issues and merge requests feed kasl inbox; inbox start, close and comment move and annotate them
Jira reads, writes Resolved issues become candidates; assigned open issues feed kasl inbox; inbox start, close and comment move and annotate issues
SiServer writes kasl report --send and kasl report --month file the day and the month

Jira and SiServer are configured through the kasl setup wizard; GitLab is set up with kasl plugin setup gitlab. Logins and URLs go to config.json; passwords and the GitLab token go to the OS keyring.

GitLab is not built into kasl. It is a plugin, kasl-plugin-gitlab, that ships in the box: the release archive, the installers, the npm package and kasl self-update put it beside the kasl binary. kasl looks for plugins in its plugins directory, then beside its own executable, then on PATH. A copy installed with cargo install kasl-cli has no plugin, because crates.io carries only the binary - download kasl-plugin-gitlab from the plugin’s releases and put it in kasl’s plugins directory.

The plugin does two things. It is an inbox source: your open issues, the open merge requests assigned to you and the ones you are asked to review, keyed by GitLab’s full references (group/app#14, group/app!31). And it answers find_tasks, so kasl task find offers the commits you pushed today.

  1. In GitLab, open User Settings → Access Tokens and create a personal access token. The api scope lets kasl start, close and comment; read_api only reads.
  2. Run kasl plugin setup gitlab and enter the settings: url (the instance root, for example https://gitlab.com) and token. start_label is optional - the label that marks work as started.

The token is a secret: it goes to the OS keyring as plugin.gitlab.token, never to config.json. The address is kept under plugins.gitlab.settings.url. The full walk-through is in Working with the GitLab inbox; the plugin protocol is in the plugin reference.

A config written by an older kasl may still have a gitlab block. It is moved automatically on the first read: the token goes to the keyring, the address becomes plugins.gitlab.settings.url, and the file is saved without the block.

When you run kasl task find, kasl asks the plugin what it found in the day. The plugin offers the commits you pushed, with the first line of the commit message and the short SHA beside it. Commits already logged as tasks are filtered out, so each piece of work is offered once.

Terminal window
kasl task find

Two separate features read from Jira: task find offers issues you resolved today as completed tasks, and the inbox polls issues assigned to you that are still open.

Three things, each only when you ask for it:

  • A move into progress - kasl inbox start, or every take when inbox.start_on_take is on.
  • A move into done - kasl inbox close, or the question after a task taken from an issue reaches 100%.
  • A comment - kasl inbox comment, or close --comment.

Moves go through Jira’s own transitions, chosen by the target status’s category (in progress, done) rather than its name, so a localized or custom workflow needs no mapping. When several transitions fit, kasl asks on a terminal and does nothing unattended. The requests:

Request What for
GET rest/api/2/issue/{key}?fields=status,resolution Where the issue stands; also why a taken issue left the inbox
GET rest/api/2/issue/{key}/transitions?expand=transitions.fields The ways out of its status, and whether closing needs a resolution
POST rest/api/2/issue/{key}/transitions The move itself, with a resolution when the screen requires one
POST rest/api/2/issue/{key}/comment The comment

Every request gives up after 30 seconds, so a Jira that does not answer cannot hold the watcher.

  1. Have your Jira login (the username, which is not always the email address) and the instance URL at hand.
  2. Run kasl setup and follow the Jira prompts. The password is asked for once and stored in the keyring.
config.json
{
"jira": {
"login": "john.doe",
"api_url": "https://jira.company.com"
}
}

Inbox polling has its own block - see Configuration for inbox.

kasl authenticates once and caches the resulting session id in the data directory as .jira_session_id. Subsequent runs reuse it; when the server rejects it the file is dropped and the login repeats. The password itself is never written to disk.

Submits the daily report and the monthly summary to a corporate reporting system. This integration is specific to the deployment kasl was originally written for; the endpoint paths come from your organization and are configured, not hard-coded into the docs.

Run kasl setup and answer the SiServer prompts: login, authentication URL and API URL. The password goes to the keyring.

config.json
{
"si": {
"login": "john.doe@company.com",
"auth_url": "https://auth.company.example",
"api_url": "https://api.company.example"
}
}
Terminal window
kasl report --send
kasl report --month

Authentication is two-staged: kasl signs in against the LDAP endpoint, exchanges the result for a bearer token, and caches the session id as .si_session_id. The same session also supplies the company’s rest days, which is why kasl sum can tell a holiday from a day you did not work.

Since 1.0, the passwords you type at a prompt live in the operating system keyring:

  • Windows - Credential Manager
  • macOS - Keychain
  • Linux - Secret Service (GNOME Keyring, KWallet, and compatible)

Nothing is encrypted with a key compiled into the binary any more - that scheme was removed rather than improved, because a key shipped inside a public release protects nothing. Installations that predate 1.0 still carry the old AES files next to the config; they are read once, migrated into the keyring and left alone afterwards. See ADR 0001.

The GitLab plugin’s token is a secret too and goes to the keyring as plugin.gitlab.token. One value is not a password and stays in config.json as written: the reporting server’s auth_token.

The data directory holds the database, the config and the cached session ids:

  • Windows: %LOCALAPPDATA%\lacodda\kasl\
  • macOS: ~/Library/Application Support/lacodda/kasl/
  • Linux: ~/.local/share/lacodda/kasl/

Session ids are .jira_session_id and .si_session_id. The GitLab plugin has none - it authenticates with its token on every request.

A wrong password is re-prompted up to three times before kasl gives up; a rejected session id is discarded and the login is retried once. Neither is a network backoff - a server that is down fails the command rather than being retried in a loop.

To force a fresh login, delete the cached session id:

Terminal window
# Linux and macOS
rm ~/.local/share/lacodda/kasl/.jira_session_id

To replace a stored password, run kasl setup again; to replace the GitLab token, run kasl plugin setup gitlab.

Terminal window
RUST_LOG=kasl=debug kasl task find

Debug logging names the requests kasl makes and the decisions it takes on the responses. It does not print credentials.

  • task - task find is where Jira and GitLab plugin candidates appear
  • Working with the GitLab inbox - setting up the GitLab plugin and using its inbox
  • plugin - installing, listing and setting up plugins
  • inbox - the inbox, its sources and its polling
  • Writing a plugin - an integration of your own, as a plugin
  • report - filing the day with --send
  • Configuration - every configuration block in one place