README
¶
tools
seed-demo
Populates a throwaway Jira Cloud site with a realistic backlog: releases, components, issues, real transition history, comments, and issue links.
Used to produce the data behind gadak's screenshots and examples/demo.db, and
reusable by anyone who wants a demo Jira to point gadak at.
export JIRA_SITE=https://your-site.atlassian.net
export JIRA_EMAIL=you@example.com
export JIRA_TOKEN=... # id.atlassian.com/manage-profile/security/api-tokens
# Project it from the committed dataset (reproducible)
go run ./tools/seed-demo --data examples/demo-seed.json --projects NMB,NMA,NMS
# Or generate content procedurally (quick, more repetitive)
go run ./tools/seed-demo --projects NMB,NMA,NMS --issues 300
Flags: --dry-run, --skip-setup (versions and components already exist),
--no-history (skip transitions, comments, links), --assignees <id,id>,
--seed <int>.
Redistribute assignees across a pool of accounts (dataset issues follow their
assignee_slot; other issues keep their assigned/unassigned status but get spread
by key hash, so repeated runs are a no-op):
go run ./tools/seed-demo --data examples/demo-seed.json \
--repair-assignees --assignees "<accountId>,<accountId>,<accountId>"
Repair a site whose workflow states do not match the dataset — issues, comments, and links are left alone and only statuses are re-driven, matched by summary:
go run ./tools/seed-demo --data examples/demo-seed.json --repair-states
Requirements
- Projects must exist and be company-managed. Team-managed projects do not
expose
priority,components, orfixVersions, which leaves most of the UI's filter axes empty. - A user API token. Organization API keys from
admin.atlassian.com(prefixATCTT) authenticate only against organization admin APIs and will 401 against every product endpoint.
Gotchas encoded in the script
issue/createmetatranslates issue-type names into the account's display language and ignoresAccept-Language, so name matching breaks on non-English accounts. The script readsproject/{key}/statuses, which is not localized.- Jira assigns
createdat insert time with no way to backdate, so seeded issues share roughly one creation time. Realistic time spread is applied bygadak snapshot, not here. - Deleting issues needs the "Delete Issues" permission, which the default company-managed scheme does not grant. Plan runs so you do not need to undo them.
- Default workflows offer a direct
Backlog -> Doneedge. Taking it leaves a single changelog entry, which makes derived fields correct but the history timeline empty — so the script walks the status category ladder one rung at a time (new -> indeterminate -> done) instead, and only falls back to a direct jump when no stepwise path exists. - An admin cannot set a user's display name.
POST /rest/api/3/useracceptsdisplayNameand ignores it for accounts outside a verified domain — Jira uses the email local part until the account holder accepts the invitation and sets their own name. Demo personas created this way read asyou+aliceuntil then. - A
reopenedissue is driven to done and then back, because that is the only way to get a real done-to-not-done transition into the changelog. History cannot be backfilled after the fact: pushing an already-done issue backwards later would register as a reopen it was never supposed to have.
hosted-demo
Builds the zero-install hosted demo into dist/hosted/ (Vite with
VITE_HOSTED_DEMO=1 + gadak export-static over examples/demo.db). See
make hosted-demo and ADR 0004 addendum.
node tools/hosted-demo/build.mjs
# or: make hosted-demo && make hosted-demo-test
backlog-snapshot.sh / backlog-scrub-check.sh
Freeze the maintainer's GDK mirror into examples/backlog-snapshot/ — the
committed, whitelist-scrubbed data behind the public backlog page
(/gadak/backlog/, GDK-389). The snapshot script runs locally (CI never
holds Jira credentials); the check script asserts the scrub invariants (no
members, no people fields, empty descriptions/comments/attachments/history,
no emails, no concrete site URLs) and runs again in pages.yml on the
built artifact. Refresh is manual, release-time by default.
tools/backlog-snapshot.sh # default mirror: ~/.gadak/profiles/oss/gadak.db
tools/backlog-scrub-check.sh examples/backlog-snapshot
bench-fixture
Builds a deterministic synthetic gadak.db for latency work (T6.7 / G5). No
network — only internal/store.
go run ./tools/bench-fixture -out /tmp/bench.db -issues 10000
make bench # BenchmarkBootstrap10k + BenchmarkSearch10k
examples/demo-seed.json
The dataset the seeder projects onto Jira. Every issue has a unique summary and hand-authored body and comments; nothing is templated, and nothing derives from a real backlog.
{
"issues": [
{
"project": "NMB", "type": "Bug",
"summary": "...", "description": ["...", "..."],
"priority": "High", "components": ["Dashboard"], "fix_version": "2026.9.0",
"labels": ["regression"], "environment": "Chrome 141 / macOS 15.2",
"state": "inprogress", "reopened": false, "assignee_slot": 1,
"comments": ["..."], "links": [{"type": "Relates", "target": 42}]
}
]
}
stateis one ofbacklog,selected,inprogress,done; the seeder walks the real workflow to reach it, so the changelog is genuine.reopened: truemakes the seeder push the issue to done and then back, which is what produces a real reopen in the changelog.links[].targetis an index into the same array.assignee_slotis mapped to whatever accounts--assigneesprovides.
release-stats
Writes one JSON snapshot of GitHub release asset download_count and the
14-day traffic window (/traffic/clones, /traffic/views). Traffic is a
rolling window; a periodic snapshot is the only history. This talks to
GitHub's API from a workflow or a human — it is not product telemetry.
tools/release-stats.sh --out /tmp/stats
# writes /tmp/stats/<YYYY-MM-DD>.json (UTC stamp). Same-day reruns overwrite.
tools/release-stats.sh --out /tmp/stats --repo midagedev/gadak --stamp 2026-08-18
--repo defaults to midagedev/gadak. --stamp defaults to UTC today.
Requires gh and jq. A traffic 403 is recorded in errors[] and the rest
of the file is still written (exit 0); if every endpoint fails, exit 1 and
no file is written.
.github/workflows/stats.yml runs this weekly (Monday 06:00 UTC) and on
workflow_dispatch, and commits stats/<stamp>.json on the stats branch.
The files live only on that branch — they are not on main.
How to read. downloads_total is asset hits, not unique people.
checksums.txt / SHA256SUMS are a large share. Homebrew cask/formula
installs fetch release assets, so they are already in the count; the tap
has no analytics of its own. Clone uniques are inflated by Actions
runners. Prefer stars and 14-day view uniques as a people-shaped ceiling.
Do not put these numbers in the README lead.
git fetch origin stats
git show origin/stats:stats/2026-08-25.json \
| jq '{stamp, downloads_total, clones:.traffic.clones|{count,uniques}, views:.traffic.views|{count,uniques}, errors}'
# per-release cumulative (includes checksums)
git show origin/stats:stats/2026-08-25.json \
| jq -r '.releases[] | "\(.tag)\t\(.downloads_total)"'
# binaries only
git show origin/stats:stats/2026-08-25.json \
| jq '[.releases[].assets[] | select(.name | test("checksum|SHA256SUMS") | not) | .download_count] | add'
The weekly job's GITHUB_TOKEN 403s traffic/*. A human gh with
push access still reads those endpoints — run the script locally and
commit onto stats so the 14-day window is not lost. Stars, referrers,
and popular paths are not in the JSON yet; errors[] is the signal
that a window was dropped.
winsmoke.ps1
Manual / real-machine Windows startup gate (GDK-244). Not a CI job —
GitHub windows-latest has no interactive desktop, so a capture there is
black. Run it on a real Windows session (or schtasks /create /it).
Launches gadak-desktop.exe from a portable pack directory, waits for the
window, records hwnd/rect/style, counts WebView2 children, captures the
screen, asserts it is not black, closes the app, and checks GADAK_HOME
did not touch %USERPROFILE%\.gadak. Exit 0 / 1 / 64 / 69. The app has no
TCP listener by design; "no port open" is a pass.
The file is UTF-8 with BOM (Windows PowerShell 5.1 otherwise reads it as the system ANSI page).
# After desktop/build-windows.ps1 has written the portable directory:
tools/winsmoke.ps1 -BundleDir desktop\\build\\Gadak-<ver>-x64 -OutDir $env:TEMP\\gadak-winsmoke\\out
Directories
¶
| Path | Synopsis |
|---|---|
|
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). |
|
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. |
|
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. |