Raw JSON report machine-readable
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 2962,
"has_wiki": false,
"homepage": null,
"languages": {
"Go": 488276,
"Shell": 2376,
"Makefile": 1263
},
"pushed_at": "2026-07-24T21:51:28Z",
"created_at": "2026-05-08T19:23:28Z",
"owner_type": "User",
"updated_at": "2026-07-24T21:51:30Z",
"description": "Manage isolated Liftoff feature worktrees with a Bubble Tea TUI",
"is_archived": false,
"is_disabled": false,
"license_spdx": null,
"default_branch": "main",
"license_spdx_raw": "NOASSERTION",
"primary_language": "Go",
"significant_languages": [
"Go"
]
},
"owner": {
"blog": "https://andrei.bio/",
"name": "Andrei Stoica",
"type": "User",
"login": "andreicstoica",
"company": null,
"location": "NYC",
"followers": 13,
"avatar_url": "https://avatars.githubusercontent.com/u/68513477?v=4",
"created_at": "2020-07-19T18:06:06Z",
"is_verified": null,
"public_repos": 38,
"account_age_days": 2198
},
"license": {
"state": "custom",
"spdx_id": null,
"raw_spdx": "NOASSERTION",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v0.2.5",
"kind": "patch",
"published_at": "2026-06-09T15:53:54Z"
},
{
"tag": "v0.2.4",
"kind": "patch",
"published_at": "2026-06-05T18:14:27Z"
},
{
"tag": "v0.2.3",
"kind": "patch",
"published_at": "2026-06-05T17:28:59Z"
},
{
"tag": "v0.2.2",
"kind": "patch",
"published_at": "2026-06-05T17:01:16Z"
},
{
"tag": "v0.1.9",
"kind": "patch",
"published_at": "2026-06-03T17:53:53Z"
},
{
"tag": "v0.1.8.1",
"kind": "other",
"published_at": "2026-06-02T14:52:31Z"
},
{
"tag": "v0.1.8",
"kind": "patch",
"published_at": "2026-06-02T14:40:40Z"
},
{
"tag": "v0.1.6.1",
"kind": "other",
"published_at": "2026-05-29T15:17:54Z"
},
{
"tag": "v0.1.6",
"kind": "patch",
"published_at": "2026-05-29T15:05:08Z"
},
{
"tag": "v0.1.5",
"kind": "patch",
"published_at": "2026-05-27T20:02:04Z"
},
{
"tag": "v0.1.4",
"kind": "patch",
"published_at": "2026-05-27T16:07:05Z"
},
{
"tag": "v0.1.3",
"kind": "patch",
"published_at": "2026-05-27T13:16:45Z"
}
],
"recent_commits": [
{
"oid": "8bc26d12c7c9aea6b81ab422ff30a22a0268856b",
"body": "`kit open` went straight to Herdr, so opening a worktree just to read code\nmeant starting a Herdr session. It now offers the same editor picker the rest\nof Kit uses — Zed first, then Cursor, the Ghostty workspace, and the Herdr\nspace last — and launches the chosen editor rooted at the worktree's che\n[…]\nand any agent inside it) starts on the right project.\n\n--editor/-e and --herdr skip the picker; --herdr preserves the old behaviour.\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(open): pick an editor or the Herdr space",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-07-24T21:51:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6a92978668942355fb94bc0227ae2e48650835f4",
"body": "herdr 0.7.x returns `{\"id\":…,\"result\":{\"snapshot\":{…}}}`, but ReadHerdrState\nunmarshalled HerdrState from the top level. encoding/json ignores unknown\nfields, so it returned an empty state with no error — every workspace lookup\nmissed. Two visible symptoms:\n\n- `kit open`/`kit focus` reported \"Herdr \n[…]\nd\ntreats an envelope it cannot read as an error rather than an empty state so a\nfuture format change can't regress to a silent miss.\n\nCo-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(herdr): parse the enveloped `herdr api snapshot` response",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-07-24T21:44:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bb01ef5a0dca166431f959a8448cb9ffad801bf8",
"body": "…ecovery\n\nrestart: after StopService, kill whatever still holds the service's port. A\n`uvicorn --reload` / Vite worker re-execs out of its recorded pid's process\ngroup, so StopService skipped the group-kill and only dropped the pid file,\nleaving the port bound. RunPlay then saw the port up, reported\n[…]\nokup.\nFallbacks run only after the existing path checks fail, so the happy path is\nunchanged. Adds parseWorktreePorcelain + tests.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: restart reaps reloaded servers; editor cleanup + lost-worktree r…",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-07-24T18:21:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "114db37dbb2222888abff9b6abf426a0b3f3222b",
"body": "Use emoji and worktree names for Herdr root tabs.",
"is_bot": false,
"headline": "fix: match Herdr shell tab labels (#13)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-07-13T18:19:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f70e6df962bab0e2f541550e7fba1203c9a7fb8a",
"body": "Integrate persistent Herdr workspaces behind Kit and update CLI/docs.",
"is_bot": false,
"headline": "feat: make Kit own Herdr workspaces (#12)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-07-13T16:26:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "79fca69d49813bfc8dabbfa391f96fefefa79c4f",
"body": "RunSelect used a huh.Select that only supported arrows/enter, so the\nshort menus (root menu, Ghostty layout) behaved differently from the list\npickers — you couldn't press a number to choose. Replace it with a small\ninline bubbletea model matching listPicker: numbered option labels (1-9)\nplus 1-9 digit quick-pick, up/down/j/k, enter, esc/ctrl+c. Cancel still\nreturns huh.ErrUserAborted so callers' special-casing is unchanged.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(tui): numbered quick-pick in select menus",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-07-10T21:25:13Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5bbd06b534a7e79d2fbaadd2f1615d2462127c3f",
"body": "Three bugs in the play/pause path:\n\n- `kit play --only celery` started the worker but not beat (the celery/\n beat pairing was lost when --only overrode the toggle defaults). Now\n selecting celery always carries beat, matching the toggle UI.\n- `kit pause --only celery` stopped the worker but orphan\n[…]\nis stale but the port is still bound. PausePlan carries\n Ports for this.\n\nAlso dedupe parseServiceList so `--only app,app` can't double-start.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(play,pause): pair celery+beat, stop reloaded backends by port",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-07-10T21:25:06Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bf447cddafdbcff6cc074e3bc042877ff39f8e0c",
"body": "Upstream liftoff-app switched Python dependency installs from pip to uv\n(#7677) and replaced black/isort/flake8 with ruff (#7676). Update kit to\nmatch:\n\n- InstallBackend runs `uv pip install --python <venv> …` instead of the\n venv pip; the design step is now \"uv install backend\".\n- doctor gains a `\n[…]\n `ruff` check (CheckWarn — kit doesn't invoke it, but backend dev/CI do).\n- README/ONBOARDING updated (requirements, setup walk, design step).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(design,doctor): use uv for backend installs + add uv/ruff checks",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-07-10T21:24:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "274d8039ce96f6c2b476c3a3fa41af133c372a30",
"body": "Restart now rm -rf's a frontend's node_modules/.vite after stopping it\nand before re-spawning, so a stale dep-optimizer cache can't survive the\nbounce. That stale cache is the usual reason hot-module reload stays\nbroken — bouncing the process alone never cleared it. --keep-cache opts\nback into a pla\n[…]\nss\nworktrees; clearing it re-optimizes deps on the next dev start (and is\nwhy concurrent worktrees wedged HMR in the first place).\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(restart): clear frontend Vite cache before bounce (#11)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-25T13:14:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bd634eddbd0e0ac8982b5cf2b076fc3d5d480f7f",
"body": "Switch the default interactive diff viewer from lumen to hunk\n(github.com/modem-dev/hunk) — a desktop-style side-by-side viewer\nbuilt for agent-authored changesets.\n\n- diff: drive `hunk diff <ref>`, fall back to plain `git diff`\n- doctor: check for hunk (brew modem-dev/tap/hunk) in place of lumen\n- setup: offer to `brew uninstall lumen` when migrating\n- docs: update README references\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: use hunk instead of lumen for kit diff (#10)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-09T15:53:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "0313cc549f05475b983c1cb69b8b3032e261f533",
"body": "The Slack/README install steps weren't self-healing: `go install` puts\nkit in $(go env GOPATH)/bin, which isn't on PATH, so a bare `kit setup`\nhit \"command not found\" — and re-running the same steps looped, since\nnothing wired PATH. Add install.sh (curl | bash): installs Go + kit,\nappends the right \n[…]\nfix (and skipping\nconfig-write + workspace adoption). Track pending-restart fixes, print\na restart hint, and exclude them from the exit-1 gate.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(setup): one-line installer + don't fail on pending PATH fixes",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-05T18:13:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "04257956cc9b87e33460315a66a23e1862d678e6",
"body": "Setup hardcoded ~/.zshrc, so bash users (whose login shell reads\n~/.bash_profile) never got the brew shellenv line. Detect the login\nshell via $SHELL and write to the matching rc; honor $ZDOTDIR for zsh.\n\nAdd a kit-path doctor check + fix: kit installs to ~/.local/bin /\nGOPATH-bin via go install / m\n[…]\nas a Claude Code session. New AppOnly field on\nEditorCandidate models app-only launch explicitly instead of relying\non a fake PATH binary name.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(setup): shell-aware PATH wiring + Claude Code desktop editor",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-05T17:28:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "358a8a189048393d9b3651f072bb5620860a53b6",
"body": "Check alembic current after gt sync and upgrade when the liftoff DB is\nbehind head, not only when new migration files land in this sync. End\nkit sync with a one-line migration summary like the merged-wash check.\n\nCo-authored-by: Cursor <cursoragent@cursor.com>",
"is_bot": false,
"headline": "feat(sync): upgrade when DB behind, print status",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-05T16:59:48Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9d106e6d4cd345dce2f4990423d2f55fd8952130",
"body": "Amp-Thread-ID: https://ampcode.com/threads/T-019e9340-61e5-705b-b924-e2abd5c8675a\nCo-authored-by: Amp <amp@ampcode.com>",
"is_bot": false,
"headline": "fix(update): quiet annotated tag checkout",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-04T16:04:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a9a46686adcc009bf885043bd8227470f6534ab0",
"body": "Amp-Thread-ID: https://ampcode.com/threads/T-019e9340-61e5-705b-b924-e2abd5c8675a\nCo-authored-by: Amp <amp@ampcode.com>",
"is_bot": false,
"headline": "feat(tui): simplify workspace prompts",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-04T16:00:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "eac75694d5455f32854864e01b5c040f3f8c8b42",
"body": "Amp-Thread-ID: https://ampcode.com/threads/T-019e9340-61e5-705b-b924-e2abd5c8675a\nCo-authored-by: Amp <amp@ampcode.com>",
"is_bot": false,
"headline": "fix(sync): guard master alembic upgrade",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-04T15:37:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "59f1ddbb3ae9187d3efb176e4bdfe053a31fd2a5",
"body": "After `gt sync`, compare master HEAD before/after. If the\nfast-forward landed new Alembic version files\n(backend/api/migrations/versions), run `alembic upgrade head` in\nmaster's backend so the local master DB mirrors remote master and\nstays a clean base for worktree DB clones.\n\nDetection is a local \n[…]\n Alembic resolves via the existing venv (venvBin).\nAdd --no-migrate to skip; upgrade failure is surfaced without\naborting the merged-wash flow.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(sync): auto-run alembic upgrade head on new master migrations",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-04T15:27:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bd23a995077391be4514dfbe09d5913edfc4aa3a",
"body": "…tion (#9)\n\nOnboarding\n- Add ONBOARDING.md walking any Liftoff employee (eng, designer, etc.)\n through install -> kit setup -> doctor -> first kit design.\n- Add \"Open in Claude Code\" onboarding badge + pointer at top of README.\n\nDocs & help\n- Value-first README intro; document kit submit and kit sl\n[…]\nw anim.tape/anim.gif previewing the gallery (no worktree side effects).\n- Fix lineup.tape (kit formation -> kit lineup --tree); re-record gifs.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: onboarding guide + README/help refresh + harmonica anim unifica…",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-03T17:52:51Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "55b87d9867fa1d2a77dce364638d334fdaa9de9b",
"body": "…ed (#8)\n\nThe previous gate (branchPushed) assumed an unmerged branch was never\npushed, but a worktree pushed before its first commit sits exactly at\nthe main tip with all work still uncommitted. `git branch --merged`\nlists it (its tip is an ancestor of main) and it has an upstream, so\nwash offered \n[…]\nh and masked the bug.\nSwitch it to --no-ff (matching real merge-commit/squash PRs that leave\nmain ahead) and add a pushedEmpty regression case.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(wash): don't flag a pushed branch sitting at the main tip as merg…",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-02T14:50:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f9e5e20be2e65493ba819f60aba17a0fd7b4f7c9",
"body": "Replace the single penalty-kick \"orb\" with a pluggable Animation\ninterface over a shared fixed-size canvas (everything drawn into the\ngrid, so the box never changes dimensions — no layout shift). One of\nfive animations is picked at random per `kit design`:\n\n- soccer (polished): jumping crowd, ball s\n[…]\n't buried behind a focus-stealing window\n- stability test drives every animation through all phases, asserting\n constant box size and no panic\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(design): random animation per design run + preview gallery (#7)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-02T14:37:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7378d7e15848a0525d48ce3338f397cc00560462",
"body": "`git branch --merged` lists every branch whose tip is an ancestor of\nmain, including freshly created worktrees that never diverged — so\n`kit wash` treated a just-made, not-yet-pushed worktree as merged and\noffered to remove it. Gate the local heuristic on the branch having an\nupstream (branchPushed)\n[…]\n) and covers branchPushed,\nmergedBranches, FindMergedWorktrees (the regression), and the\nworktree-location helpers Name/IsMaster/ListWorktrees.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(wash): don't flag unpushed worktrees as merged (#6)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-02T14:36:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d245fa078d11ba6fefb079b31ea2334d6e19d6e5",
"body": "Master rides slot 0 by convention (master port defaults), but the\n`Slot == 0` guard read that as \"unallocated\" and rejected master with\n\"has no slot — run `kit play master` first\", so a running master could\nnever be bounced.\n\nExtract resolveSlot() which exempts master, and route restart + log\nensurePlaying through it. Add table tests covering master (incl. nil\ncfg), feature worktrees, slot-0, and unknown names.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: kit restart/log reject master worktree",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-06-01T20:19:38Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "49a56813ea07d73b99d6fde766ce0b306f1935a2",
"body": "The background update check compared the cached remote tag to the current\nversion with plain string inequality, so a build ahead of a stale cached tag\nprinted a backwards hint: \"kit v0.1.5 available (you have v0.1.6)\". It also\ncompared lexically, so v0.1.10 looked older than v0.1.9.\n\nAdd a field-by-\n[…]\nparseable versions stay silent. `kit update` itself was already correct\n(it sorts tags via git -v:refname); this only fixes the passive banner.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(update): only nudge when the remote tag is actually newer",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-29T15:17:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4ba5949196d39db4d29ae0f5a17b9bb5a80400f1",
"body": "`celery beat` writes its schedule shelve (celerybeat-schedule.{db,dir,bak})\ninto its working directory, which kit sets to the worktree's backend/. The\nfile then shows up as untracked junk in `git status` after `kit play`.\n\nPass `--schedule` pointing at the kit run dir (~/.config/kit/run/<name>/)\nso beat's state lives alongside the other per-worktree runtime files and\nnever touches the repo.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(play): keep celery beat's schedule file out of the worktree",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-29T14:51:04Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "8809ea4a1bb565ba9eecfda220df596a1fa54093",
"body": "main() called RenderMarkdownLongs() on every invocation, walking the whole\ncommand tree and spinning up a glamour renderer per command — wasted work on\nthe hot path (`kit play`, `kit log`, shell completion) where no help is shown.\nNow it's a no-op unless argv contains -h/--help/help, and a single gl\n[…]\nuses the shared RunConfirm (last\n standalone confirm that bypassed it).\n- Makefile build pins CGO_ENABLED=0 for a static, reproducible binary.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "perf: render help markdown only when help is requested",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-29T14:48:49Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "16654fda07af46f48d3b0d3ce3917878fb441164",
"body": "`kit guide` was a static glamour-rendered walkthrough that duplicated the\nREADME and per-command help. Drop it: delete cmd/guide.go, its menu entry,\nits first-run bypass entry, and the README section. glamour stays (help.go\nstill renders command help).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: remove the guide command",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-29T14:48:36Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "66be2dae7943f6bc4737c0e81c2fa06df623120c",
"body": "wash built its list with a hand-rolled delegate + title styling and its\nitems carried no emoji, so `kit wash` rendered worktrees noticeably\ndifferently from `kit play`/`pause`. Route it through the shared\nNewListDelegate + StyleList and add the worktree emoji, matching the\nidx → emoji → name layout \n[…]\ntab\ntags) since those differ by intent — but the list chrome, numbering, emoji,\nand keybindings are now identical across every worktree picker.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(tui): unify wash picker chrome with play/pause",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-29T14:41:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ae0d89ed449f13871b14e06cbc6db9d618a0c84d",
"body": "`wash` (aliases rm/remove/delete) tears down a kit but was missing from the\ninteractive `kit` menu, so it was undiscoverable without knowing the verb.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(menu): add wash (remove) to the root command menu",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-29T14:37:18Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a25c29fa3dd488f9b06bc6e86dbc6675013a701f",
"body": "Unify kit's interactive UI behind three shared primitives so the same kind\nof action looks and behaves identically across every command:\n\n- internal/tui/ui.go: central design-language tokens — shared list delegate,\n title style, and kit huh theme. One place to restyle every prompt.\n- internal/tui/p\n[…]\nAdds tests: list picker key handling, forms first-frame visibility, editor\nresolution/LoneEditor, workspace open routing, and orb layout width.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(tui): consolidate menus, selects, and workspace-open",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-29T14:10:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4d0b33a5c83ce089bcd904b1a3e406f85bd2e570",
"body": "Play / ports:\n- RunPlay skips services already listening instead of spawning a duplicate\n that can't bind the port (the cause of the hung `kit play`).\n- PortListening/portBindable now check both 127.0.0.1 and [::1]; Vite binds\n IPv6 [::1], so the IPv4-only check reported it dead and triggered the \n[…]\nibe suffixes compare by base tag.\n- Daily, cached, TTY-only \"update available\" nudge — silent in scripts,\n completion, and local dev builds.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(play,update): idempotent play, IPv6-aware ports, self-update",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-27T20:00:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8c1c9f11a641d6951773c1120b11f47328e79751",
"body": "Safety fixes:\n- StopService refuses to kill a recycled PID (start-time + group-leader\n guard) so a stale pid file can't nuke an unrelated process group.\n- All config.toml read-modify-writes go through WithConfigLock (flock),\n preventing slot-collision/clobber under concurrent kit processes.\n- kit \n[…]\n-w/--workspace (+ -d) replaces kit warmup; gtab now a swap alias.\n- prune internals renamed to merged (RunMergedWashTUI, MergedCandidate, …).\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(cli): harden services/config + consolidate commands",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-27T16:06:46Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8f3227853f359d5e3f236eca88343045d0c38385",
"body": "Wrap PickGtabLayout select in an explicit huh.Form with WithTheme so\ngroup.WithHeight(rawHeight()) fires at construction time. Without it the\ngroup viewport height stays 0 on the initial frame and options are\ninvisible until the first keypress.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(design): show layout options on first render",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-27T13:16:28Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "54450369c642245b87d8065da06faae4e2d82353",
"body": "Both demos showed in-progress Liftoff feature work that shouldn't\nbe public. Tapes stay so a coworker with the repo cloned can\nre-render locally if needed.",
"is_bot": false,
"headline": "docs: drop design.gif + lineup.gif",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T22:26:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "aefff18dba81b2d3df0f64ed94b784edcef18442",
"body": "Removed demo GIF from README.",
"is_bot": false,
"headline": "Remove demo GIF from README",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T22:24:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "38e7eccbbe7da27fa022368f16781260ad9eddb7",
"body": "NewPlayModel + buildPauseItems were calling WorktreePath/LegacyWorktreePath\ndirectly, which produce $ROOT/master and $ROOT/liftoff-master — neither\nactually exists. Master lives at layout.Master. Switched to the shared\nLayout.ResolveWorktreePath helper so `kit play master` and `kit pause\nmaster` work as expected.",
"is_bot": false,
"headline": "fix(play,pause): resolve master path correctly when passed as arg",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:55:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fa2c9b70ef7830639b06474cc8ffb77e5d4501b8",
"body": "Lineup view, tree view, play picker, and gtab tab title all rendered\nmaster with different emojis (🚀 hardcoded vs 🧊 from EmojiFor's\nhash). Centralized via liftoff.MasterEmoji + an early-return in\nEmojiFor(\"master\") so every surface agrees on 🧊.\n\nAlso dropped 🪲 from the random-fun hash pool. ew.",
"is_bot": false,
"headline": "fix(emoji): consistent 🧊 for master; drop 🪲 from hash pool",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:46:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7ffe456558e2345ab49642871ee1b41be4339feb",
"body": null,
"is_bot": false,
"headline": "fix(swap): give master the same gtab layout pick as worktrees",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:42:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "049f24af9092435a982dda0356ed781084210caa",
"body": "Ghostty launches gtab tabs with `bash --noprofile --norc`, which\nskips ~/.zshrc / .bashrc — so the user's `~/.local/bin` (or\n`$(go env GOPATH)/bin`) PATH addition never loads, and a bare\n\\`kit log <name> --wait\\` errors with \\\"kit: not found\\\".\n\nResolve the running binary via os.Executable() at temp\n[…]\nate-write\ntime and embed the absolute path in both the simple and detailed\ngtab templates. Falls back to bare \\`kit\\` if Executable() fails\n(better-than-nothing for users whose system PATH covers it).",
"is_bot": false,
"headline": "fix(gtab): use absolute kit path so logs tab finds the binary",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:30:34Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "16c08eb9b66d18fe075877a93a5e9d21c664433d",
"body": null,
"is_bot": false,
"headline": "ux(swap): label Ghostty option as '(pick layout next)'",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:28:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e0c82578e6890ff556c943133c08c7248d3e2ec0",
"body": "- Restore master in the play + pause pickers. Master has slot 0 by\n design (ports 3000/3001/9000/9001/9002); play special-cases name\n == \"master\" to skip the adopt prompt and use those ports directly.\n- Split resolveArgOrCwd master handling: play/pause skip master from\n cwd (so running from the m\n[…]\nvice .log files to tail.\n- README: added an ELI5 services table for designers — what each of\n app/admin frontend, app/admin backend, celery, beat, mcp actually\n is and which port pattern it runs on.",
"is_bot": false,
"headline": "feat(swap,play): master in play + gtab layout pick on swap→Ghostty",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:25:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a6cec3c3f435c458fe2e65fb8e708a0f63e8a1b8",
"body": null,
"is_bot": false,
"headline": "docs(vhs): re-render design.gif with full wizard + follow-up prompt",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:22:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2cf6b5933af56a5ed13915452d368d12a0750605",
"body": "A previous commit dropped master from collectPlayWtItems to keep it\nout of the play picker, but that helper is also the source for the\ngeneric worktree picker (swap, warmup, links, log) — so master\nsilently disappeared from every list.\n\nRestore the original semantics: collectPlayWtItems includes master\n(with the 🚀 emoji + \"master\" name). Play and pause now pass a\ndropMaster filter; the generic picker passes nil and gets master\nback.",
"is_bot": false,
"headline": "fix(pickers): keep master in swap/warmup/links/log lists",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:20:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "959d08bff32a3c03d3f6b8939ee603cf911e801d",
"body": "readme:\n- cheatsheet column-aligned to col 26; new `--detailed` warmup hint\n- design step list matches the current 4-prompt form (dropped the\n stale backend-deps / gtab prompts); names the follow-up flow\n- play output block adds the celery beat row that's emitted now\n- log keys promoted to an align\n[…]\nns with defaults), hides the\n long dress steps, then captures the simple/detailed/skip prompt\n + play prompt. Leaves a real `vhs-demo` worktree; comment notes\n the `kit wash vhs-demo` cleanup step.",
"is_bot": false,
"headline": "docs(readme,vhs): trim, realign, capture full design wizard",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:18:24Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b8666f48cb075de5d20eac4ceb1b8a3a7a2fa0c9",
"body": "Four call sites (diff, submit, swap, warmup) duplicated the same\nmaster/canonical/legacy fallback dance for resolving a kit name to\nits on-disk dir. Pulled into a single Layout method so the rules\nlive in one place and callers shrink to a one-liner.",
"is_bot": false,
"headline": "refactor(paths): extract Layout.ResolveWorktreePath",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:12:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7622aaa5e47c6065ae84450e70076e53e5d8f0cb",
"body": "- ensureRunDir now iterates liftoff.DisplayServices instead of a\n hardcoded literal that drifted from the canonical list.\n- offerNextSteps uses huh.NewSelect[liftoff.GtabLayout] directly\n with GtabSimple/GtabDetailed/\"\" instead of stringly-typed\n \"simple\"/\"detailed\"/\"skip\" + a re-translation step\n[…]\n can't drift.\n- Drop the dead `_ = time.Second` (and the now-unused time import)\n in washflow.\n- Refresh collectPlayWtItems doc comment to match current behavior\n (master is dropped, not folded in).",
"is_bot": false,
"headline": "chore: review fixups — dedupe service list, type the gtab choice",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:08:00Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7889978d5e6ff2d567417f513ae40ce41d6ea5c9",
"body": "The gtab logs tab was a bare `tail -F file1 file2 …` stream. That\nlost the color-coded service tags, search, follow toggle, and tag\nfilter that `kit log` provides. Wired it up to `kit log <name>\n--wait`:\n\n- log.go: new `--wait` flag skips the \"nothing playing\" guard and\n pre-creates the run dir + e\n[…]\nwhen it doesn't\n exist yet, so empty pre-touched files behave like real ones once\n play starts writing.\n- gtab.go: simple + detailed templates both invoke `kit log <name>\n --wait` for the logs tab.",
"is_bot": false,
"headline": "feat(log): --wait flag; gtab logs tab now runs the styled viewer",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T21:02:41Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "572df1ab03dc99eb67ab0c4269c2bcadcdbaa480",
"body": "design summary view:\n- skipped steps no longer render at all (was confusing — pending and\n skipped used very similar markers)\n- next: block removed (the post-success prompts run kit play / open\n ghostty for you)\n- footer reads \"press enter to continue\" instead of \"exit\" since the\n next prompt is \n[…]\nplaceholder rows entirely. If the DB\n doesn't exist or the gtab file is missing, those toggles don't\n appear. Cursor + toggle keys now map to the visible rows\n dynamically instead of hardcoded 0/1.",
"is_bot": false,
"headline": "ux(design,wash): hide skipped/unneeded rows, simple|detailed gtab prompt",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:56:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "aaff972262d3a2acb6a002feca20cd916175137d",
"body": "Default stays simple (shell + combined logs). `kit warmup --detailed`\nrestores the per-service tail panes for devs who want to watch each\nservice stream side-by-side, and tacks on a combined logs tab on top.\nREADME updated to describe both layouts.",
"is_bot": false,
"headline": "feat(warmup): --detailed flag for 5-tab gtab layout",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:53:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a45ff775c5d2c085ca6404e1acd557950ecccae6",
"body": "- warmup: always rewrite the .applescript instead of skipping when\n one exists. The old 4-tab layout was sticking around on existing\n worktrees and re-running `kit warmup` had no effect.\n- play picker: drop master from the kit list — master has no slot\n and isn't a valid play target.\n- viewRun: pull the trailing \\n out of StyleDim.Render so the\n \"replaced …'s celery\" line doesn't bleed wide-padding into the\n next row's marker.",
"is_bot": false,
"headline": "fix(warmup,play): regen gtab + drop master from picker + line fix",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:50:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "10e41342bf0a8383e614d6aacc94a64aa4f4fe4f",
"body": "`kit play` runs servers in the background and writes their stdout to\n.log files, so the old 4-tab Ghostty layout (root + frontend split +\nbackend split + celery) was just four separate `tail -F` panes. One\ncombined `tail -F` tab covers every service, and frees the root tab\nfor the real work (Claude, git, ad-hoc shells).",
"is_bot": false,
"headline": "refactor(gtab): collapse 4 service tabs into 1 combined log tab",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:47:32Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "477b7b44b519ff70c2352223cd627eb5db08a3f7",
"body": "design:\n- stopwatch now freezes at completion instead of running forever\n- drop `cd <path>` from the next: cheatsheet (not needed when the\n follow-up \"open ghostty?\" prompt opens the workspace for you)\n- ask both follow-up yes/no questions up front, then act — was\n opening ghostty between question\n[…]\npt\n feel like an interruption\n\nplay/pause/wash: passing `master` as an explicit arg now errors\nwith \"master isn't a kit — pick a worktree instead\" instead of\nthe cryptic \"Worktree not found: master\".",
"is_bot": false,
"headline": "ux(design,play): stop timer, batch follow-ups, reject master arg",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:45:27Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2e71dae78df50cdb7f5990276f67c6db29431807",
"body": null,
"is_bot": false,
"headline": "feat(menu): add formation to root picker",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:42:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2dd80aa26bbd38770f73693c34ddfc46c0da0dc9",
"body": null,
"is_bot": false,
"headline": "chore: trim verbose comments",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:38:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d678e1c8f62f68b9f2ae138a827e114e9cecca84",
"body": "`kit play` from inside the master dir was resolving cwd to `master`\nand then failing in the play TUI (master has no slot, no isolated\nservices). Same trap on `kit pause` and `kit wash` — master is never\na valid target for any of them. Added a non-master cwd resolver and\nwired play/pause/wash to it s\n[…]\nter now\nfalls through to the picker.\n\n`kit log` used to open the viewer even when no services were alive,\nshowing stale lines that never updated. Now blocks with a hint to\nrun `kit play <name>` first.",
"is_bot": false,
"headline": "fix(play,log): skip master from cwd; block log when nothing playing",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:37:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "13bcab337ce98d513fdc29c9a46249abf815f27a",
"body": "- log viewer: \"follow\" → \"auto-scroll\", \"services\" panel → \"filter\n services\", celery vs beat now render as distinct rows (\"celery\n worker\" / \"celery beat\") so it's not two `[celery]` entries.\n- service Label(): full \"frontend\"/\"backend\" everywhere (was\n `app_front`/`admin_back`). Affects play picker, allocated URL\n grid, formation tree, pause picker. Bumped padding to fit.\n- README: updated service-name examples + port table.",
"is_bot": false,
"headline": "refactor(ui): clearer log/service labels for designers",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:31:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a3bedcc26fac2d2412e1a30bde6f4050cb45d33a",
"body": "README cheatsheet, subcommands, and roadmap now reference\n`kit formation` (alias `tree`) instead of the deprecated\n`kit lineup --tree` flag. lineup.tape demo updated. New\ndesign.tape captures the wizard intro (aborts before creating\na real worktree).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(readme,vhs): rename --tree → `kit formation`, add design demo",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:26:41Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "170b1f2dc8267f6c7e42a04613591691375b8bf8",
"body": "The post-design huh.MultiSelect was confusing and at least some\noptions didn't fire the way the user expected. Replaced with two\nsequential huh.NewConfirm prompts: \"Open the Ghostty workspace?\"\nthen \"Start dev servers?\". Each defaults Yes. Esc skips remaining\nprompts. Browser-open option dropped — open in the new Ghostty\ntabs or via `kit links` later.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ux(design): sequential yes/no follow-ups instead of multi-select",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:24:01Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2956fe7cd21e88f8c5abb0f72c44bafe1b38f8d3",
"body": "`kit lineup --tree` was hidden behind a flag. Promotes the tree to a\nfirst-class command with a soccer-themed verb (formation = how the\nteam lines up positionally) plus a plain `tree` alias for muscle\nmemory. `kit lineup` drops the --tree flag.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: `kit formation` (alias `tree`) — tree view as its own command",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:23:01Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "cbf178322f9923223c66f3b34fd4fcdb550b0074",
"body": "`t` opens the services-filter overlay, but tagOrder was only\npopulated as log lines streamed in. If a service had no recent\noutput (or kit log was opened before any lines arrived), the panel\nshowed an empty list. Now seeds the panel from the run dir's\n`.log` filenames at startup so every known service appears\nimmediately, all default-on.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(log): pre-populate tag panel from existing .log files",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:20:47Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f099727a5edd88cd424437982015fd6fceabbf0d",
"body": " db shared (liftoff) → shared from master\n frontend real node_modules → own copy\n frontend symlinked from master → symlinked to master\n\nReads as a relationship to master rather than as kit jargon.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ui(tree): friendlier labels for db / frontend rows",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:19:48Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7d667c035ea406ad861bbde5f4e4be15e1f02316",
"body": "`uvicorn --reload` re-execs into a fresh process when a Python file\nchanges, killing the PID kit recorded at startup. lineup's running\ncount was stuck at 3/5 because api + admin_be both showed \"dead PID\"\neven though the backends were healthy on :9010 / :9011.\n\nIsServiceAlive now treats port-listenin\n[…]\n PID\nliveness only fronts for celery/beat (no ports). Recorded PIDs\nremain useful for `kit pause` to know which process to signal.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(lineup): port-listening = truth for service liveness",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:18:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c8ee4964301d9e6db1b895fb5d4e95fafa905f77",
"body": "Tree view now shows two extra signals per worktree that previously\nrequired running psql / ls -la to discover:\n\n setup\n ├── ● db liftoff_google_agent (has its own DB)\n └── ● frontend symlinked from master (or `◇ real node_modules`)\n\nAlso fixes liftoff.HasDB — psql needed `-d postgres` to connect when\nthe user's $USER database doesn't exist; that's why the DB column\nwas silently always-false.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(lineup-tree): \"setup\" sub-node — DB ownership + node_modules wiring",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:16:54Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "479ac429d49e0fe6164dbcb9dd01b518f9ba3794",
"body": "After a successful kit design, multi-select prompt offers the three\nfollow-ups people usually run next:\n\n [ ] Open Ghostty workspace (kit warmup)\n [ ] Start dev servers (kit play)\n [ ] Open frontend URLs in browser\n\nEsc / empty selection skips. Gtab runs first so the workspace is\nopen when servers boot. Browser launches frontend/app + frontend/admin\nURLs from the new slot.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(design): post-success \"anything else?\" prompt",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:13:44Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "35efefa44cd5851df779f1ffc36572edfb4a6da2",
"body": "Score was appended to row 0, jutting out next to the goal frame and\ncramping the right edge. Moved it under the grid + centered to the\ngrid width, like the bottom-of-screen scoreboard in old arcade\npenalty kick games.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ui(orb): center the score under the shooter (arcade style)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:08:58Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f60e4659566a8078d052adc9570ee2dcb25e687f",
"body": "- pip install was failing because exec.Command(\"pip\", …) hit $PATH\n and kit's shell doesn't have the venv activated. Now resolves to\n $KIT_PY_VENV/bin/pip (falls back to bare \"pip\" when the venv path\n isn't present, so non-Liftoff invocations still work).\n- Orb panel Padding(0,1) → Padding(1,2) so the goal posts breathe\n inside the rounded border.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix: pip via venv path + orb panel padding",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:07:27Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "53db544e536c493ae12a98211991f3a5ed148d0c",
"body": "- FetchMain now `git fetch origin <main>` (no refspec). AddWorktree\n branches off `origin/<main>` rather than the local main ref. Old\n refspec form failed with exit 128 when local master was checked\n out (master worktree on a feature branch, etc.).\n- Orb panel width bumped from 30 to 38 (height 14 → 16) so the\n GOAL!/SAVE! flash next to the grid has room.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(design): robust master fetch + roomier orb",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T20:05:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e367a6fecda96ae0989b459961dca21858f6818e",
"body": "huh's NewForm groups questions; one group = one screen. Each\nconfirm now lives in its own group so designers see prompts one at\na time instead of a wall of pink/grey buttons.\n\nDefaults:\n- Clone DB: No by default (heavy disk use; opt-in)\n- Backend deps: no longer prompted — always installed automatically\n- Symlink node_modules: Yes (unchanged)\n- Track in graphite: Yes (unchanged)\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ux(design): one prompt per screen + saner defaults",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T19:59:54Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "58b7598781d0af2e2735775e4169912987aef892",
"body": "Source-available license that allows internal business use while\nbarring third-party redistribution / commercial use. Better fit\nthan MIT for a tool meant to stay close to the Liftoff team.\n\nFull text inline; README pointer updated.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(license): switch from MIT to PolyForm Internal Use 1.0.0",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T19:55:25Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e05187415401266344e35a03eef94777ed105a4e",
"body": "…kit setup`\n\nCoworkers without Go on their machine were stuck — now the install\nsection spells out the brew install, PATH export, then `go install`\n+ `kit setup` as the canonical path. Clone-and-make-install stays\nas the contributor alternative.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(readme): lead with `brew install go` + `go install …@latest` + `…",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T19:45:57Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "def0737e2c655205151486cfd6c889499d1b970f",
"body": "Corrected punctuation and formatting in README.",
"is_bot": false,
"headline": "Fix formatting in README.md for clarity",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T19:45:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "db59cf81f81bea02fe595f4d5ca013e725e16175",
"body": "Updated README to clarify command usage and improve wording.",
"is_bot": false,
"headline": "Revise README for clarity and command updates",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T19:42:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "05d6787c6b6efef22df420f954affc2d82ee2c55",
"body": "…lf-test (#5)\n\nFour polish features for v0.1.0:\n\n- **Dynamic tab completion** on every name-arg command. Cobra\n ValidArgsFunction reads config.Worktrees + git worktree list and\n returns matching names. Adopt completes only unmanaged candidates.\n- **`kit submit [name]`** wraps `gt submit` in the wo\n[…]\n,\n PortsBindable(99), ListWorktrees, run-dir write. Catches \"kit\n installed but env broken\" issues that the static audit misses.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: dynamic completion, kit submit, kit slots renumber, doctor --se…",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T19:39:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "dca668b0d2b93611e8185932c0601759e82687fa",
"body": "* refactor: state.toml → config.toml + Settings block\n\n- Renames internal/liftoff/state.go → config.go. `State` kept as a\n type alias for backwards compat.\n- Adds Settings struct (Root, MasterDir, GtabDir, MainBranch, PyVenv,\n Editor, LiftoffRepo) — written by `kit setup`, hand-editable.\n- Worktre\n[…]\none-liners where the meaning was\nalready obvious.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: config.toml + kit adopt + bulk-adopt in setup (#4)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T19:30:08Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "fe3dad31da4e9a3f15293039e28697a0e0337485",
"body": "…olveTarget everywhere (#3)\n\n* fix(wash): delete the actual branch, not the kit name\n\nWashPlan kept only the kit-normalized name (e.g. \"voice-agent\") and\npassed it to DeleteBranch. Worktrees on branches like\n\"acs/voice-agent-cleanup\" silently no-op'd or deleted the wrong\nbranch.\n\n- Add Branch field \n[…]\n\n`kit links` likewise gains arg + picker support.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix+refactor: wash branch bug, doctor read-only, design name arg, res…",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T17:03:16Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b43405b54b760b83a268fca74824f7bf4632aed1",
"body": "* chore(naming): rename `kit dress` → `kit design` in user-facing strings\n\nThe cobra command is `kit design`, but four error/empty-state strings\nstill said `kit dress`. New users following the README would hit\n\"unknown command 'dress'\". Internal DressPlan struct kept as-is with a\ncomment to flag the\n[…]\ntree): unbold current branch, keep Liftoff purple\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat: kit doctor + kit setup (onboarding bootstrap) (#2)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T16:52:06Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "0dd4e25652c938d314f2508e82c1f3ee1a9c733e",
"body": "* feat(swap): include master in kit picker\n\n`kit swap` picker now shows master (the main repo) as a first-class\nentry so users can `kit swap` → master → editor without remembering\nthe special path.\n\n- shown as 🏠 master (special emoji, always first row)\n- path resolves to layout.Master\n- TouchLastUse\n[…]\nyIdx field on playWtItem (missed in prior commit)\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(swap): include master in kit picker (#1)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T15:52:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "947b44f57970239d0f7d9f8afc8fe311a5713f07",
"body": "Squash of today's 4 commits:\n- single-arg `kit swap zed` reads as editor when cwd is a worktree\n- ldflags inject `git describe` into `kit -v`\n- drop second positional, use `-e/--editor` flag, always pickers when\n arg/flag absent (per clig.dev + johnlindquist/worktree-cli)\n- cache appBundleExists results, delete dead worktreeFromCwd\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(swap): rework arg shape, ldflags version, app-bundle detection",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-11T13:57:52Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f1f7c5658beb21b692de9e46a51d481423170b5d",
"body": "`code` on PATH is commonly a shim from another tool (e.g. Cursor),\nnot VS Code itself, so detecting \"VS Code installed\" via PATH alone\nis misleading. Same risk for `zed`. Switch detection to: known\neditors require the .app bundle in /Applications; if both bundle and\nbinary exist, prefer the binary (\n[…]\npresent but `zed` binary missing → was hidden.\nFixes: VS Code.app absent but `code` shim present → was shown as\ninstalled VS Code.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(swap): require .app bundle for known editor detection",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T22:32:35Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f4d60ab7f0f61843dc1974de2cb418b26c2bbf66",
"body": "`kit swap` (zero args) now opens two pickers:\n1. pick a kit (from worktrees)\n2. pick an editor (from zed/cursor/code that are actually installed)\n\nIf only one editor is installed, the editor picker is skipped.\n1+ args fall back to today's behavior (auto-pick editor or use the\npositional one).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(swap): two-step picker for no-arg flow (worktree → editor)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T22:29:41Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "0ee59ea925df0479494c25c1a5fcb572a6d38a2b",
"body": "\"pick a kit to put on\" reads as a wardrobe action, matching the\noverall design (`kit dress`, `wash`, `tear`).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ux(play): retitle picker to fit kit metaphor",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T22:26:34Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7e4c04978922d51b0eb3ab1c71778ecaa3f75ec4",
"body": "`kit swap` with zero args now opens a Bubble Tea picker listing every\nworktree (sorted by last-used). Pick → opens in default editor.\n\nArgument forms:\n- `kit swap` picker → default editor\n- `kit swap <name>` default editor\n- `kit swap <name> <editor>` forces the editor\n\nAdds tui.PickWorktree() helper for reuse by future commands that want\nthe same picker UX.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(swap): no-arg opens picker",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T22:26:11Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3cab0a41eefd8a42c83f293912af322faf600ee3",
"body": "Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ux(design): clarify name-field hint wording",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T22:24:21Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "2728c699f3943c26ffffd330b1211514f57aa431",
"body": "The \"liftoff- prefix is stripped\" detail is implementation trivia; users\ncare more about what the name is actually *used* for downstream.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "ux(design): swap name-field hint to something more useful",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T22:23:35Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "80baaebe1a0f70f42e1db252787738bb321e2e85",
"body": "- Requirements table: required vs optional tools so teammates can\n audit before install. Optional ones auto-disable when missing.\n- Drop verbose zsh completion subsection; one-liner pointer to\n `kit completion --help` is enough.\n- Renames §\"What kit dress does\" → §\"What kit design does\" to match\n the renamed command.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add Requirements section, mention kit completion",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T21:46:27Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5bd2856cf87b839a2838183a72b96f432aa06079",
"body": "Captures the matrix of required vs optional tools so teammates can\naudit their machine before installing. Optional tools are documented\nas auto-disabling — kit shouldn't crash when pg_dump or gt isn't\ninstalled.\n\nRenames §\"What kit dress does\" → §\"What kit design does\" to match\nthe renamed command.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add Requirements section + zsh completion setup",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T21:44:46Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a77288c1483bc7a27b129d21e1461e082c093939",
"body": "- TrimSpace glamour body before printing; eliminates double blank\n line between cmd.Short and rendered markdown\n- raise wrap cap to 120 so paragraphs don't break on every other\n word at the right edge of wide terminals\n- skip the post-Short blank line when Long is present (glamour adds\n its own leading padding)\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(help): tighter section spacing + wrap cap 100→120",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T21:41:02Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "03eac90b96e222891552799aa3b74c3585f1bda4",
"body": "- WithStandardStyle(\"auto\") was falling back to ascii on Ghostty,\n leaving \"##\" literal in headers; switch to WithAutoStyle() which\n detects light/dark terminal background properly\n- WordWrap was 0 (no wrap); now uses term.GetSize - 2, capped 40-100\n- add blank line between Long body and Usage section so they don't\n visually run together\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(help): glamour auto-style + width-aware wrap + section spacing",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T21:35:04Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "aa27a41b864914d34d63379823f63d839a3cc746",
"body": "- swap \"dress time\" → \"design time\" everywhere\n- emoji pool count tightened from ~95 → ~90\n- note lineup column order (NAME · SLOT · RUNNING · BRANCH · STATUS)\n and rationale for SLOT-RUNNING adjacency\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(plan): refresh narrative for design rename + lineup columns",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T21:21:08Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "954e8088099ea4ce00cb4b74942cf8dfdb2e3492",
"body": "- columns now NAME · SLOT · RUNNING · BRANCH · STATUS\n slot + running adjacent since both describe port-allocation lifecycle\n (slot = ports reserved, running = ports actually serving)\n- LAST USED column removed; meta.LastUsed still drives row sort order\n- delete unused realnow.go + relativeTime helper\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor(lineup): reorder columns, drop LAST USED",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T21:15:13Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1a7919d70e82af5aee7933d82efd572a32da676f",
"body": "- export tui.Color* for cmd/ packages; drop hex literals from\n cmd/help.go, cmd/root.go, internal/tui/logflow.go\n- log viewer: append to strings.Builder per line, rebuild only on\n ring trim (was strings.Join over 5000 lines per incoming line)\n- log: drop redundant pre-flight stat; RunLogTUI's Read\n[…]\nquit\n- docs/PLAN.md: living design doc — port slots, runtime env injection,\n charm component map, roadmap, verification checklist\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "refactor: dedup colors, streamline log buffer, expand emoji pool",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T21:13:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "eb8b3c6169f57af9e0ca1dc32f41c15450326291",
"body": "User-visible:\n- Drop `dress` from design aliases (only `new` remains)\n- Rename `prune` → `tear` (alias `prune` kept). \"Tear up the field.\"\n- `kit swap <name> [editor]` — positional editor override (e.g. `kit swap notebook cursor`)\n- `kit play` (no arg) auto-detects cwd inside a worktree and uses tha\n[…]\n-flight: errors before entering TUI when no run dir\n- orb bounds clip: clampInt prevents out-of-bounds writes if spring overshoots\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Polish + critical fixes from audit",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T21:00:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1fbb7abd048baddb55c387637dd1ed73a31313ad",
"body": "Side panel during `kit design` now shows a penalty kick at goal:\n- ball flies from penalty spot to a random corner (harmonica spring)\n- goalie dives left or right (separate spring), 45% chance to match\n- judge phase: SAVE if goalie within 2.5 cells of ball, GOAL otherwise\n- score tally in top-right (saves vs goals)\n- ~3s loop with pre-shoot/shoot/result phases\n\nSame `Orb` type name kept for back-compat with designflow.go.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Replace orb panel with animated penalty kick",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T20:47:55Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ebc90a265c22b3d9bbd930c9c367d2e235097676",
"body": "- Rename `dress` → `design` (aliases: `dress`, `new`)\n- huh forms replace manual toggle screens in design wizard\n- Animated orb panel during design (harmonica spring physics + 3-dot orbit)\n- bubbles/progress overall progress bar + bubbles/stopwatch elapsed timer\n in design and play run screens\n- bu\n[…]\n`)\n- Cobra root Long rewritten in markdown for glamour rendering\n- New cmd/help.go with custom `prettyHelp` template using glamour\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Adopt huh, glamour, charm/log + bubbles components",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T20:44:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "11c23f0355f776d4ddc22d560c7e214efe094b84",
"body": "- Replace fixed-width fmt.Sprintf padding with lipgloss/table for proper\n ANSI/emoji-aware column alignment\n- Drop GTAB column (always auto-managed) and SERVICES dot column\n (replaced by simpler N/6 RUNNING count, blank when zero)\n- Adaptive color palette via lipgloss.AdaptiveColor for both light\n\n[…]\no worktrees made by the old zshrc script work with\n `kit warmup` etc\n- Remove gtab toggle from `kit dress` wizard — always create\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Polish lineup table + adaptive colors + legacy gtab compat",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T20:32:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1a8ec93940674860b2d40863f43ab8cb56efe678",
"body": "Each worktree now gets a deterministic 5-port slot at `kit dress` time\n(state.toml). New `kit play` wizard spawns frontend/app + frontend/admin\n(Vite) + backend/api + backend/admin (uvicorn --reload) + celery worker +\nbeat as detached processes, with port-aware env injection at runtime\n(env files st\n[…]\nkit swap` bumps last_used so picker keeps recent kits on top\n- New env vars: KIT_STATE_DIR, KIT_RUN_DIR, KIT_PY_VENV, KIT_NO_EMOJI\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Add port wiring + service runner (play/pause/log/prune)",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T20:24:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9f16fe9545ee57144150f356d37e592ccb32ce84",
"body": "Bubble Tea TUI wrapping git worktree + env copy + DB clone +\ndep install + graphite tracking + ghostty workspace generation.\n\nSubcommands: dress (new), lineup (ls), wash (rm), warmup (gtab), swap (open).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"is_bot": false,
"headline": "Initial commit: kit CLI for Liftoff feature worktrees",
"author_name": "Andrei Stoica",
"author_login": "andreicstoica",
"committed_at": "2026-05-08T19:21:07Z",
"body_truncated": false,
"is_coding_agent": true
}
],
"releases_count": 12,
"commits_last_year": 96,
"latest_release_at": "2026-06-09T15:53:54Z",
"latest_release_tag": "v0.2.5",
"releases_from_tags": false,
"days_since_last_push": 2,
"active_weeks_last_year": 9,
"days_since_latest_release": 47,
"mean_days_between_releases": 1.4
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 42,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "github.com/andreicstoica/kit",
"exists": true,
"license": null,
"keywords": [],
"ecosystem": "go",
"matches_repo": true,
"registry_url": "https://pkg.go.dev/github.com/andreicstoica/kit",
"is_deprecated": false,
"latest_version": "v0.3.3",
"repository_url": "https://github.com/andreicstoica/kit",
"versions_count": 21,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-24T21:51:14Z",
"latest_version_yanked": null,
"days_since_latest_publish": 2
}
]
},
"popularity": {
"forks": 0,
"stars": 1,
"watchers": 0,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": null,
"open_issues_and_prs": 1
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [
"Makefile"
],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"go.mod"
],
"largest_source_bytes": 22092,
"source_files_sampled": 120,
"oversized_source_files": 0,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"go.mod"
],
"advisories": {
"error": null,
"scope": null,
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"go"
],
"dependencies": [
{
"name": "github.com/BurntSushi/toml",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.6.0"
},
{
"name": "github.com/charmbracelet/bubbles",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.0.0"
},
{
"name": "github.com/charmbracelet/bubbletea",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.3.10"
},
{
"name": "github.com/charmbracelet/fang",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.0.0"
},
{
"name": "github.com/charmbracelet/glamour",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.0.0"
},
{
"name": "github.com/charmbracelet/harmonica",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.2.0"
},
{
"name": "github.com/charmbracelet/huh",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.0.0"
},
{
"name": "github.com/charmbracelet/lipgloss",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.1.1-0.20250404203927-76690c660834"
},
{
"name": "github.com/spf13/cobra",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v1.10.2"
},
{
"name": "golang.org/x/term",
"manifest": "go.mod",
"ecosystem": "go",
"version_constraint": "v0.43.0"
}
],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 1,
"merged_prs": 13,
"open_issues": 0,
"closed_ratio": null,
"closed_issues": 0,
"closed_unmerged_prs": 0
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "andreicstoica",
"commits": 96,
"avatar_url": "https://avatars.githubusercontent.com/u/68513477?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": false,
"has_tests": true,
"ci_workflows": [],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"go.sum"
],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 0,
"reason": "0 out of 8 merged PRs checked by a CI test -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 0,
"reason": "project has 0 contributing companies or organizations -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": null,
"reason": "no workflows found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 9,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 0,
"reason": "project was created within the last 90 days. Please review its contents carefully",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": null,
"reason": "packaging workflow not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": null,
"reason": "No tokens found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 0,
"reason": "12 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "8bc26d12c7c9aea6b81ab422ff30a22a0268856b",
"ran_at": "2026-07-26T22:42:34Z",
"aggregate_score": 1.3,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-24T21:51:27Z",
"oldest_open_prs": [
{
"number": 14,
"created_at": "2026-07-13T21:24:32Z",
"last_comment_at": null,
"last_comment_author": null
}
],
"last_merged_pr_at": "2026-07-13T18:19:15Z",
"ci_last_conclusion": null,
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/andreicstoica/kit",
"host": "github.com",
"name": "kit",
"owner": "andreicstoica"
},
"metrics": {
"overall": {
"key": "overall",
"band": "at_risk",
"name": "Overall health",
"note": null,
"notes": [],
"value": 44,
"inputs": {
"security": 13,
"vitality": 76,
"community": 21,
"governance": 54,
"engineering": 40
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 76,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"commits_last_year": 96,
"human_commit_share": 1,
"days_since_last_push": 2,
"active_weeks_last_year": 9
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 2 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 2
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "9/52 weeks with commits",
"points": 6.2,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 9
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "96 commits in the last year",
"points": 17.8,
"status": "partial",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 96
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 100,
"inputs": {
"releases_count": 12,
"latest_release_tag": "v0.2.5",
"releases_from_tags": false,
"days_since_latest_release": 47,
"mean_days_between_releases": 1.4
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "12 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 12
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 47 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 47
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~1.4 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 1.4
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "critical",
"name": "Community & Adoption",
"value": 21,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 0,
"stars": 1,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "1 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 1
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "at_risk",
"name": "Community health",
"note": null,
"notes": [],
"value": 44,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "license file present, not a recognized license",
"points": 16.9,
"status": "partial",
"details": [
{
"code": "license_custom",
"params": {}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 54,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 10,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 1,
"top_contributor_share": 1
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 100% of commits",
"points": 0,
"status": "missed",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "1 contributors",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 1
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"issue_resolution"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 72,
"inputs": {
"merged_prs": 13,
"open_issues": 0,
"closed_issues": 0,
"issue_closed_ratio": null,
"closed_unmerged_prs": 0
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "no issues or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_issues_or_data",
"params": {}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "13/13 decided PRs merged",
"points": 38.2,
"status": "met",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 13,
"decided": 13
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 52,
"inputs": {
"followers": 13,
"owner_type": "User",
"is_verified": null,
"owner_login": "andreicstoica",
"public_repos": 38,
"account_age_days": 2198
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "personal (user) account",
"points": 10,
"status": "partial",
"details": [
{
"code": "owner_personal",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": "not applicable to user accounts",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_applicable_to_user_accounts",
"params": {}
}
],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "13 followers of andreicstoica",
"points": 8.2,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 13,
"login": "andreicstoica"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "38 public repos, account ~6 yr old",
"points": 23.6,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 38
}
},
{
"code": "account_age_years",
"params": {
"years": 6
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"github.com/andreicstoica/kit"
],
"ecosystems": "go",
"any_deprecated": false,
"min_days_since_publish": 2
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on go",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "go"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 2 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 2
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "21 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 21
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "at_risk",
"name": "Engineering Quality",
"value": 40,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "critical",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 24,
"inputs": {
"has_ci": false,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "0 out of 8 merged PRs checked by a CI test -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 65,
"inputs": {
"topics": [],
"has_wiki": false,
"homepage": null,
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "critical",
"name": "Security",
"value": 13,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "critical",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Dangerous-Workflow, Packaging, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"dangerous_workflow",
"packaging",
"signed_releases",
"token_permissions"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 13,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 14,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 4,
"scorecard_aggregate": 1.3
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "0 out of 8 merged PRs checked by a CI test -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no workflows found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow not detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "No tokens found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "12 existing vulnerabilities detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 2
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "moderate",
"name": "AI Readiness",
"value": 65,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.969,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "93 of 96 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 93,
"sampled": 96
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "good",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 71,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"go.sum"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [
"Makefile"
],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0.688,
"toolchain_manifests": [
"go.mod"
],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "Makefile",
"points": 18,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Makefile"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "Go (statically typed)",
"points": 11,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Go"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "66 of the last 96 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 66,
"sampled": 96
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "Go",
"largest_source_bytes": 22092,
"source_files_sampled": 120,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Go (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Go"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "0/120 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 120,
"oversized": 0
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-26T22:42:41.730231Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/andreicstoica/kit.svg",
"full_name": "andreicstoica/kit",
"license_state": "custom",
"license_spdx": null
}