gadak

package module
v0.20.2 Latest Latest
Warning

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

Go to latest
Published: Sep 5, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

README

gadak gadak

Latest Release CI License

Follow the thread.

English · 한국어

A local SQLite file of your Jira — so "which epic is stuck?" is one query, not an unaskable one.

gadak mirrors Jira and Confluence — issues, comments, history, wiki pages — into one SQLite file on your machine, indexed together and searchable with no network. Triage it in the desktop app or a browser tab, or let a coding agent ask in plain SQL and point the same window at the answer. One binary, no gadak account.

The mirror is a cache you can throw away. If this project stops tomorrow, you delete a directory and have lost nothing: Jira stays the source of truth.

▶  Open the live demo  —  534 issues, in your browser, right now.
Changelog  —  what shipped.

Install

macOS app, CLI included:

brew install --cask midagedev/tap/gadak

CLI only — the same UI in a browser tab via gadak serve:

brew install midagedev/tap/gadak-cli

Connect to Jira, then open the address gadak serve prints (http://gadak.localhost:7777):

gadak init && gadak sync && gadak serve

A Jira site needs one API token; it covers Jira and Confluence on the same site. You pick what it mirrors: --projects for Jira, --spaces for the wiki, which stays off until you name them. No Atlassian account? gadak init --local starts a workspace on the built-in tracker, and gadak --workspace <new> migrate --from <old> later carries a synced mirror onto it — or into a Linear team with --to linear.

Windows: the desktop app is on the Microsoft Store — the Store signs it, so neither SmartScreen nor Smart App Control objects. For the CLI, take gadak_<version>_windows_amd64.zip (or arm64) from the latest release, unzip, put gadak.exe on PATH. The release's desktop zip (Gadak-<version>-windows-x64.zip) stays unsigned — a SmartScreen block is a missing signature, not a virus finding (why); if it blocks, install from the Store, and do not turn Smart App Control off.

The window is in English, Korean or Japanese — it follows the browser or OS language, and Settings switches it.

The signed dmg, the Linux tarball, pairing a second machine (gadak --workspace laptop init --pairing-code-stdin), Docker, upgrades: docs/INSTALL.md.

The point

gadak sql "select epic_key, count(*) from issues_full where resolved_at is null
           and epic_key <> '' group by epic_key order by 2 desc"

JQL has no GROUP BY. "Which epic is actually stuck?" is not a hard question — it is an unaskable one, until the data is a file. docs/RECIPES.md has the rest, and Datasette Lite runs this query on the demo snapshot in your browser with nothing installed.

Measured 2026-08-26 against a live Cloud site (3,296 issues; medians, CLI startup included):

Question REST API gadak
Simple filter, 100 issues 583 ms 19 ms 31×
One issue with its full history 710 ms 28 ms 25×
Free-text search 543 ms 41 ms 13×
Open issues per epic (GROUP BY) 4,761 ms — 8 API pages, aggregated client-side 22 ms — one query 214×
A count over the change history not expressible — ≈ 28 min of crawling 14 ms

Past a page size, JQL answers stop being slow and start being unaskable: the API hands you rows, never the aggregate. The method, the re-measurement history, and the rows where gadak loses — the first full sync, the watch tick on a quiet site, one sync interval of staleness — are in docs/BENCHMARKS.md.

▶ 20-second tour of the paper list (GIF)


The window, in twenty seconds. Generated from e2e/demo/web-demo.spec.ts against the demo snapshot.

Status: 0.20, still 0.x. Sync, read API, write-through, desktop, web, CLI, and MCP are verified against a live site. CHANGELOG.md.

For agents

This is half the reason gadak exists. Reference: docs/MIRROR.md; one paste per host: docs/AGENT_SETUP.md.

gadak skill install

Schema and query patterns, no extra process. For hosts without a shell (Claude Desktop), the same mirror is an MCP server:

gadak mcp install claude


The shell is in the window (⌘K → Terminal, or Ctrl+`). gadak claim binds it to the issue — the tab is named by the key — and a live Claude Code session started in it drives the board beside it: one Korean sentence becomes the list, the next one paints a dashboard. Nothing but the two prompts is scripted; the stretches where the agent is working are time-lapsed. Recorded from e2e/demo/terminal-claude-demo.spec.ts via record-terminal-claude.sh.

Two rules carry most of the value. Filter on status_category and priority_rank, never on a display name — Jira translates those per account, so priority = High is silently zero rows on a Korean-language site. And SQL answers while the window presents: gadak sql --no-header "…" | gadak views open --keys - puts an agent's answer on your screen, and gadak views open --jql '…' lands pasted JQL as chips. Writes — create, edit, comment, transition, claim, link, and the wiki's page verbs — go through the origin before the mirror refreshes, and every agent write carries the agent's name.

What agents have built on it — dashboards, a team theme, a launcher, a live MCP session — is a gallery of recordings: docs/SHOWCASE.md.

An agent that reads your mirror sends what it reads to whatever model it talks to. gadak itself sends nothing (SECURITY.md); scope the mirror to what the agent should see. Where gadak does touch the network — sync, writes, pairing — docs/NETWORK.md walks every connection and its off switch.

What's covered

Three origins, one set of verbs: Atlassian Cloud, Linear (a "linear" block in the workspace config and gadak sync --source linear), and the built-in tracker that travels with the app. Reads, writes, hierarchy, wiki, attachments, history and the board layout work on all three; what each origin refuses, with the code citation behind every cell, is one table: docs/SUPPORT_MATRIX.md. Three things appear on no origin at all: sprints as a UI, Jira dashboards, and Jira's notification inbox — those stay in Jira.

The rest

Good fit / bad fit. Daily search latency, an agent over tracker and wiki, offline reads — yes. Sprint planning, admin, a page editor in the UI, or a minute of staleness — stay in Jira. docs/CONCEPT.md.

How it works. One binary, one SQLite file; incremental sync plus a reconcile pass. docs/ARCHITECTURE.md. Why not an extension or Forge app: docs/decisions/0003-local-process.md.

How it compares. jira-cli talks to the live API per command. Rovo MCP searches both sources too, but it is hosted: no aggregate, no offline, and every call spends tokens. docs/FAQ.md.

Making it yours. Config, enrichments, SQL — two axes, no forking: docs/EXTENDING.md.

Documentation

Who makes this

One person, currently. Weigh that — and the other side: the mirror is a disposable cache of your own Jira, the 0.x contract is the three promises in data-model.md (issues_full and the RECIPES queries, gadak sql stdout, and gadak views open --keys -), the license is Apache-2.0, and the file is plain SQLite. Hard questions: docs/FAQ.md. What you do not have to take on trust, each with the command that checks it: PROMISES.md.

Contributing and feedback

CONTRIBUTING.md, and docs/project/GOOD_FIRST_ISSUES.md to start. Bug reports need your Jira deployment type (Cloud), the gadak commit, and the command you ran. Never paste real issue data, tokens, or site URLs into a public issue. Commit GDK-nnn keys resolve on the public backlog; to file something, open a GitHub issue and the maintainer mirrors it there. Using gadak with an agent and hitting friction? Open an issue with the question you asked and what the agent did.

License

Apache-2.0. See LICENSE and NOTICE.

Documentation

Overview

Vendor assets for agent-authored dashboards (GDK-792): the pinned chart library a dashboard may load from /api/v1/dashboards/vendor/ instead of a CDN. Embedding it keeps the dashboards CSP free of external hosts (no outbound rule change — the bytes ship inside the binary), and pinning the version once means every dashboard sees the same library instead of whatever a CDN serves that day.

[GDK-808] three.js no longer ships embedded (−750 KB): anything bigger or less universal than uPlot belongs in the user-managed lib cache (`gadak dashboards lib add <url>` — sha384-pinned at download, re-hashed at serve, see internal/dashboards/libs.go), not in every binary gadak ships. uPlot stays embedded: one chart library is the norm the example dashboard sets.

The HTTP whitelist is DashVendorFile's table, not the directory: the license is embedded for NOTICE/NPB purposes but is not served.

Package gadak embeds the built web UI so a release is one self-contained binary. `npm run build` writes web assets to dist/app before `go build`; without that step the embed carries only the committed placeholder and WebUI reports ok=false, which `gadak serve` turns into a helpful error.

It also embeds the Claude Code skill (skills/gadak/SKILL.md) so `gadak skill install` works for brew installs without a source checkout.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DashVendorFile added in v0.17.2

func DashVendorFile(name string) ([]byte, string, bool)

DashVendorFile returns the embedded bytes and content type for a whitelisted vendor filename. ok is false for anything not in the table — unknown names, subdirectories, license files — and the route answers 404 in that case. Callers must not modify the returned slice.

func SkillMarkdown

func SkillMarkdown() []byte

SkillMarkdown returns the embedded Claude Code skill body (skills/gadak/SKILL.md). Callers must not modify the returned slice.

func WebUI

func WebUI() (fs.FS, bool)

WebUI returns the embedded web assets rooted at the app directory. ok is false when the binary was built without a web build (placeholder only).

Types

This section is empty.

Directories

Path Synopsis
cmd
gadak command
export-static freezes the demo mirror into static JSON + attachment bytes for the zero-install hosted demo (GitHub Pages).
export-static freezes the demo mirror into static JSON + attachment bytes for the zero-install hosted demo (GitHub Pages).
contrib
raycast
Package raycastext embeds the Raycast extension source so the gadak binary can install it without a checkout (gadak raycast install).
Package raycastext embeds the Raycast extension source so the gadak binary can install it without a checkout (gadak raycast install).
internal
adf
Package adf inspects Atlassian Document Format (ADF) JSON without importing Jira types, so store, origin, and CLI can share it without crossing the store/jira firewall (docs/ARCHITECTURE.md).
Package adf inspects Atlassian Document Format (ADF) JSON without importing Jira types, so store, origin, and CLI can share it without crossing the store/jira firewall (docs/ARCHITECTURE.md).
applog
Package applog is the single owner of where process log output goes.
Package applog is the single owner of where process log output goes.
apprun
Package apprun is the single owner of the long-lived process boot sequence shared by `gadak serve` and gadak-desktop.
Package apprun is the single owner of the long-lived process boot sequence shared by `gadak serve` and gadak-desktop.
atlhttp
Package atlhttp is the shared HTTP transport for Atlassian Cloud clients (Jira, Confluence): path safety, Authorization host pinning, and the Do/DoRaw loop.
Package atlhttp is the shared HTTP transport for Atlassian Cloud clients (Jira, Confluence): path safety, Authorization host pinning, and the Do/DoRaw loop.
atomicfile
Package atomicfile is the one owner of stage-then-rename writes.
Package atomicfile is the one owner of stage-then-rename writes.
attachcache
Package attachcache stores attachment bytes on local disk.
Package attachcache stores attachment bytes on local disk.
calendar
Package calendar is the single owner of "which calendar day is this?".
Package calendar is the single owner of "which calendar day is this?".
claim
Package claim is the single owner of the gadak claim write (CLI today, REST later), the way internal/transition owns the transition write.
Package claim is the single owner of the gadak claim write (CLI today, REST later), the way internal/transition owns the transition write.
clitool
Package clitool installs the gadak binary onto PATH.
Package clitool installs the gadak binary onto PATH.
config
Package config loads and saves ~/.gadak/config.json.
Package config loads and saves ~/.gadak/config.json.
config/tokencheck
Dimension-token validation (dim-token chunk 1) — the sibling of the color side of this package.
Dimension-token validation (dim-token chunk 1) — the sibling of the color side of this package.
confluence
Package confluence is a thin REST client for Confluence Cloud: enough of the API to fill the page mirror, plus the user-initiated page writes that go through the origin (create / update).
Package confluence is a thin REST client for Confluence Cloud: enough of the API to fill the page mirror, plus the user-initiated page writes that go through the origin (create / update).
create
Package create is the single owner of project, issue-type, and priority resolution for gadak create (CLI and REST).
Package create is the single owner of project, issue-type, and priority resolution for gadak create (CLI and REST).
dashboards
Package dashboards owns the interpretation of dashboard rows: the config document (HTML + named datasources) and its validation rules, name→row resolution, and datasource execution into the {columns, rows, truncated, warning?} document the render iframe draws from (GDK-781).
Package dashboards owns the interpretation of dashboard rows: the config document (HTML + named datasources) and its validation rules, name→row resolution, and datasource execution into the {columns, rows, truncated, warning?} document the render iframe draws from (GDK-781).
deeplink
Package deeplink parses and builds the gadak:// URLs that hand a piece of gadak to someone — a link in chat or on a web page instead of a shell, a running serve, and a command with side effects.
Package deeplink parses and builds the gadak:// URLs that hand a piece of gadak to someone — a link in chat or on a web page instead of a shell, a running serve, and a command with side effects.
fields
Package fields holds source-neutral field helpers — coalesce, fill checks, slugs, and write-payload shaping — so internal/store can use them without importing Jira types.
Package fields holds source-neutral field helpers — coalesce, fill checks, slugs, and write-payload shaping — so internal/store can use them without importing Jira types.
fsperm
Package fsperm is the single owner of private-directory creation.
Package fsperm is the single owner of private-directory creation.
httppolicy
Package httppolicy is the host-neutral HTTP retry and usage policy shared by origin clients (Atlassian via atlhttp, Linear).
Package httppolicy is the host-neutral HTTP retry and usage policy shared by origin clients (Atlassian via atlhttp, Linear).
integrations
Package integrations is the desktop Settings catalog: which local agent/host tools gadak can install, how to detect them, and which gadak CLI argv installs each one.
Package integrations is the desktop Settings catalog: which local agent/host tools gadak can install, how to detect them, and which gadak CLI argv installs each one.
jira
Package jira is the Atlassian Cloud REST client: read paths plus user-initiated writes.
Package jira is the Atlassian Cloud REST client: read paths plus user-initiated writes.
jirafields
Package jirafields classifies and discovers Jira custom fields for the mirror.
Package jirafields classifies and discovers Jira custom fields for the mirror.
jql
Package jql translates a documented JQL subset to and from gadak's in-memory filter (the same shape the web UI serializes into the URL).
Package jql translates a documented JQL subset to and from gadak's in-memory filter (the same shape the web UI serializes into the URL).
linear
Package linear is the GraphQL client for a Linear workspace: viewer, teams, workflow states, cursor-paged issues with an updatedAt watermark filter, and — since GDK-360 — the three write verbs (create issue, update issue, comment) the origin.Writer adapter routes through.
Package linear is the GraphQL client for a Linear workspace: viewer, teams, workflow states, cursor-paged issues with an updatedAt watermark filter, and — since GDK-360 — the three write verbs (create issue, update issue, comment) the origin.Writer adapter routes through.
mcp
Package mcp implements a thin stdio MCP server over the local gadak mirror.
Package mcp implements a thin stdio MCP server over the local gadak mirror.
migrate
Package migrate exports a mirror into an issuetap fixture document — the seed a fresh local-origin workspace loads one-shot (origin/issuetap.yaml, GDK-1264).
Package migrate exports a mirror into an issuetap fixture document — the seed a fresh local-origin workspace loads one-shot (origin/issuetap.yaml, GDK-1264).
origin
Package origin is the single owner of "this workspace's origin clients".
Package origin is the single owner of "this workspace's origin clients".
originbind
Package originbind owns one invariant: a workspace is bound to one origin.
Package originbind owns one invariant: a workspace is bound to one origin.
pairflow
Package pairflow owns the device-pairing mint flow shared by the CLI (`gadak pairing`, GDK-433/450/797) and the desktop app's Devices tab (GDK-1047): endpoint resolution and validation, the scoped mint plus offer encode, the _home routing-token guard, list row shaping, and the two QR encodings (the terminal module matrix and the PNG a phone scans).
Package pairflow owns the device-pairing mint flow shared by the CLI (`gadak pairing`, GDK-433/450/797) and the desktop app's Devices tab (GDK-1047): endpoint resolution and validation, the scoped mint plus offer encode, the _home routing-token guard, list row shaping, and the two QR encodings (the terminal module matrix and the PNG a phone scans).
pairing
Package pairing owns the device tokens that gate a serve's origin passthrough once it is exposed beyond loopback (GDK-433), and — since GDK-797/GDK-883 — the mirror REST a paired phone companion reads.
Package pairing owns the device tokens that gate a serve's origin passthrough once it is exposed beyond loopback (GDK-433), and — since GDK-797/GDK-883 — the mirror REST a paired phone companion reads.
parenthint
Package parenthint is the single owner of parent-rejection detection and the mirror hierarchy hint that follows it (CLI create/edit and REST PUT parent / POST create).
Package parenthint is the single owner of parent-rejection detection and the mirror hierarchy hint that follows it (CLI create/edit and REST PUT parent / POST create).
secretscan
Package secretscan holds the credential-shaped string patterns that every outbound artifact is checked against before it is written.
Package secretscan holds the credential-shaped string patterns that every outbound artifact is checked against before it is written.
selfupdate
Package selfupdate answers one question — is a newer release published? — with one GitHub API call a day, cached on disk.
Package selfupdate answers one question — is a newer release published? — with one GitHub API call a day, cached on disk.
serveaddr
Package serveaddr owns the home-root run directory that a live `gadak serve` writes so other processes can find it without guessing ports.
Package serveaddr owns the home-root run directory that a live `gadak serve` writes so other processes can find it without guessing ports.
server
Package server is the loopback HTTP mux for the web UI and the API (specs/000-product/contracts/api.md).
Package server is the loopback HTTP mux for the web UI and the API (specs/000-product/contracts/api.md).
snapshot
Package snapshot builds shareable mirror copies for demos and benchmarks.
Package snapshot builds shareable mirror copies for demos and benchmarks.
sqlhint
Package sqlhint is the shared SQL-error help used by gadak sql and gadak_query (MCP), and the owner of SQL comment stripping (StripComments) used by the group-query and MCP SELECT gates.
Package sqlhint is the shared SQL-error help used by gadak sql and gadak_query (MCP), and the owner of SQL comment stripping (StripComments) used by the group-query and MCP SELECT gates.
statuscat
Package statuscat is the single owner of the status-category contract: the three tokens data-model.md documents (new | inprogress | done), their mapping from Jira's REST statusCategory keys, and the reverse.
Package statuscat is the single owner of the status-category contract: the three tokens data-model.md documents (new | inprogress | done), their mapping from Jira's REST statusCategory keys, and the reverse.
store
Package store owns the SQLite mirror: schema, migrations, transactions, full-text index and the derived fields the source does not provide.
Package store owns the SQLite mirror: schema, migrations, transactions, full-text index and the derived fields the source does not provide.
sync
Package sync fills the mirror from the configured sources (Jira, and Confluence when enabled).
Package sync fills the mirror from the configured sources (Jira, and Confluence when enabled).
teamconfig
Package teamconfig builds and applies team-shareable gadak configuration files (views, field maps, group rules, …) without credentials or personal machine prefs.
Package teamconfig builds and applies team-shareable gadak configuration files (views, field maps, group rules, …) without credentials or personal machine prefs.
term
Package term owns the PTY sessions `gadak serve` runs next to the mirror — one session core for all three surfaces (the web pane, the desktop app, and a phone over the paired network).
Package term owns the PTY sessions `gadak serve` runs next to the mirror — one session core for all three surfaces (the web pane, the desktop app, and a phone over the paired network).
transition
Package transition is the single owner of the gadak transition write (CLI, including `gadak close`, and REST).
Package transition is the single owner of the gadak transition write (CLI, including `gadak close`, and REST).
uifocus
Package uifocus is the handoff from the CLI to a running UI.
Package uifocus is the handoff from the CLI to a running UI.
views
Package views owns the interpretation of view names: how the Jira filters and saved views inside a store are listed, and how one name resolves to exactly one of them.
Package views owns the interpretation of view names: how the Jira filters and saved views inside a store are listed, and how one name resolves to exactly one of them.
workspace
Package workspace mounts additional gadak profiles under /w/<name>/ and lists them at GET /api/v1/workspaces.
Package workspace mounts additional gadak profiles under /w/<name>/ and lists them at GET /api/v1/workspaces.
tools
bench-fixture command
Command bench-fixture builds a deterministic synthetic gadak.db for latency benchmarks (T6.7 / G5).
Command bench-fixture builds a deterministic synthetic gadak.db for latency benchmarks (T6.7 / G5).
seed-demo command
Command seed-demo populates a throwaway Jira Cloud site with a realistic demo backlog for gadak screenshots and examples/demo.db.
Command seed-demo populates a throwaway Jira Cloud site with a realistic demo backlog for gadak screenshots and examples/demo.db.
term-leak-probe command
Command term-leak-probe measures whether a gadak PTY session leaves a SIGHUP-immune grandchild alive after Close.
Command term-leak-probe measures whether a gadak PTY session leaves a SIGHUP-immune grandchild alive after Close.

Jump to

Keyboard shortcuts

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