Öffentliches Register
Software-GesundheitsberichtSchema 0.27.0 · Metriken 1.13.0 · 2026-07-26 22:42 UTC

andreicstoica / kit

Manage isolated Liftoff feature worktrees with a Bubble Tea TUI

GoEigene Lizenz★ 1 Stern⑂ 0 Forksseit Mai 2026Auf GitHub ansehen ↗

andreicstoica/kit erreicht einen Gesundheitsindex von 44 von 100 und liegt damit im Bereich Gefährdet. Am stärksten schneidet es bei Vitality (76/100) ab, am schwächsten bei Security (13/100). Zuletzt vor 2 Tagen aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

44
gesamt / 100
Gefährdet

Software-Gesundheitsindex

Metriken werden auf einer Skala von 1–100 in gewichtete Kategorien gruppiert. Der Gesamtwert beginnt als ihr Mittel; sobald öffentliche Evidenz die Richtlinie für Hochrisikojurisdiktionen auslöst, wird die Bewertung angepasst und erhält die Obergrenze 49 (Gefährdet). AI Readiness liegt außerhalb.

44
Exzellent85-100Vorbildlich; erfüllt im Wesentlichen alle geprüften Kriterien
Gut70-84Gesund; geringfügige Lücken
Mittel50-69Akzeptabel mit deutlichen Lücken; Überprüfung empfohlen
Gefährdet30-49Erhebliche Schwächen; eine Übernahme erfordert Vorsicht
Kritisch1-29Schwerwiegende Probleme (aufgegeben, nur ein Maintainer, keine Hygiene)
VitalitätCommunity &VerbreitungNachhaltigkeit &GovernanceEngineering-QualitätSicherheitAI Readiness

Bewertungsprofil

Jede Achse ist eine Kategorie. Die Form zählt mehr als der Durchschnitt — ein gesundes Projekt füllt die gesamte Fläche, während ein Profil aus Spitzen und Kratern bedeutet, dass Stärke in einer Dimension Risiken in einer anderen verdeckt.

Eigentümerschaft

Andrei StoicaPersönliches Konto
13 Follower38 öffentliche Reposseit Juli 2020

Dieses Repository gehört einem persönlichen Konto. Ein Projekt mit nur einem Eigentümer trägt ein höheres Kontinuitätsrisiko als ein organisationsgetragenes.

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlicht
Gogithub.com/andreicstoica/kitv0.3.3-21vor 2 Tagen

Metriken nach Kategorie

Vitalität

Lebt das Projekt — wird Code geschrieben und werden Releases ausgeliefert?

76Gut · 22 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 2 Tagen
6.2/36Commit-Rhythmus — 9/52 Wochen mit Commits
17.8/18Commit-Volumen — 96 Commits im letzten Jahr
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Verwendete Eingangsdaten
commits_last_year96
human_commit_share1
days_since_last_push2
active_weeks_last_year9

Release-Disziplin

100Exzellent
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 12 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 47 Tagen
27/27Release-Rhythmus — ein Release etwa alle 1,4 Tage
0/10OpenSSF Scorecard: Signed-Releases — keine Daten
Verwendete Eingangsdaten
releases_count12
latest_release_tagv0.2.5
releases_from_tagsnein
days_since_latest_release47
mean_days_between_releases1,4
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: Signed-Releases. Die verbleibenden Gewichte wurden renormalisiert.

Community & Verbreitung

Hat das Projekt Nutzer, Downloads, Aufmerksamkeit und ein einladendes Umfeld für Beitragende?

21Kritisch · 18 % des Gesamtindex
Wie die Bewertung erfolgt
0/60Stars — 1 Stars
0/25Forks — 0 Forks
0/15Watcher — 0 Watcher
Verwendete Eingangsdaten
forks0
stars1
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
16.9/22.5Lizenz — Lizenzdatei vorhanden, keine anerkannte Lizenz
0/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
has_contributingnein
has_issue_templatenein
has_code_of_conductnein
has_pull_request_templatenein

Nachhaltigkeit & Governance

Überdauert das Projekt die Menschen, die es tragen — Bus-Faktor, Reaktionsfähigkeit, Trägerschaft und Paketpflege?

54Mittel · 24 % des Gesamtindex
Wie die Bewertung erfolgt
9/54Bus-Faktor — 1 Beitragende decken die Hälfte aller Commits ab
0/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 100 % der Commits
1.4/13.5Breite der Beitragenden — 1 Beitragende
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Verwendete Eingangsdaten
bus_factor1
contributors_sampled1
top_contributor_share1
Wie die Bewertung erfolgt
0/46.8Issue-Lösungsquote — keine Issues oder keine Daten
38.2/38.3PR-Annahme — 13/13 entschiedene PRs gemergt
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs13
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Issue-Lösungsquote. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
10/30Organisatorische Trägerschaft — persönliches (Nutzer-)Konto
0/20Verifizierte Domain — für Nutzerkonten nicht anwendbar
8.2/25Reichweite des Inhabers — 13 Follower von andreicstoica
23.6/25Kontohistorie — 38 öffentliche Repos, Kontoalter ca. 6 Jahre
Verwendete Eingangsdaten
followers13
owner_typeUser
is_verified
owner_loginandreicstoica
public_repos38
account_age_days2.198
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Verifizierte Domain. Die verbleibenden Gewichte wurden renormalisiert.

Paketpflege

100Exzellent
Wie die Bewertung erfolgt
25/25Veröffentlicht & auflösbar — 1 Paket(e) auf go
35/35Veröffentlichungsaktualität — letzte Veröffentlichung vor 2 Tagen
20/20Versionshistorie — 21 veröffentlichte Versionen
20/20Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen
Verwendete Eingangsdaten
packagesgithub.com/andreicstoica/kit
ecosystemsgo
any_deprecatednein
min_days_since_publish2

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

40Gefährdet · 20 % des Gesamtindex
Wie die Bewertung erfolgt
0/24CI-Workflows
24/24Tests vorhanden
0/16Linter-Konfiguration
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — 0 out of 8 merged PRs checked by a CI test -- score normalized to 0
Verwendete Eingangsdaten
has_cinein
has_testsja
has_editorconfignein
has_linter_confignein
has_precommit_confignein
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
10/10Repository-Beschreibung
0/10Topics
0/10Wiki
Verwendete Eingangsdaten
topics
has_wikinein
homepage
has_readmeja
has_docs_dirja
has_descriptionja

Sicherheit

Sind die sichtbaren Sicherheits- und Lieferkettenpraktiken belastbar, ohne ungeklärte Exposition gegenüber Hochrisikojurisdiktionen?

13Kritisch · 16 % des Gesamtindex

Sicherheitslage

13Kritisch
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 0 out of 8 merged PRs checked by a CI test -- score normalized to 0
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
0/10Dangerous-Workflow — keine Daten
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.2/2.5Lizenz — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — keine Daten
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — keine Daten
0/7.5Token-Permissions — keine Daten
0/7.5Vulnerabilities — 12 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated14
scorecard_versionv5.5.0
checks_inconclusive4
scorecard_aggregate1,3
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): dangerous_workflow, packaging, signed_releases, token_permissions. Die verbleibenden Gewichte wurden renormalisiert.

AI Readiness

Wie gut ist das Repository dafür ausgestattet, mit KI-Coding-Agenten entwickelt und gepflegt zu werden? Ein unabhängiges, experimentelles Badge — Gewicht 0,0, es wird eigenständig ausgewiesen und verändert den Gesamt-Gesundheitswert nicht.

65Mittel · 0 % des Gesamtindex
Wie die Bewertung erfolgt
0/45Agentenanweisungen — keine CLAUDE.md / AGENTS.md / Editor-Regeln
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 93 von 96 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share0,969
agent_instruction_files
agent_instruction_max_bytes
Wie die Bewertung erfolgt
18/18Bootstrap mit einem Befehl — Makefile
22/22Automatisierte Tests
0/11Lint-/Format-Konfiguration
11/11Statische Typprüfung — Go (statisch typisiert)
10/10Reproduzierbare Umgebung — lockfile
10/10Belegte Agentenpraxis — 66 der letzten 96 Commits von Agenten verfasst oder ihnen zugeschrieben
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfilesgo.sum
has_dockerfilenein
typed_languageja
bootstrap_filesMakefile
has_devcontainernein
has_linter_confignein
typecheck_configs
agent_commit_share0,688
toolchain_manifestsgo.mod
dependency_bot_commit_share0
Wie die Bewertung erfolgt
45/45Typprüfbarer Code — Go (statisch typisiert)
55/55Handhabbare Dateigrößen — 0/120 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageGo
largest_source_bytes22.092
source_files_sampled120
oversized_source_files0

Eckdaten

1GitHub-Sterne
1Mitwirkende
96Commits, letzte 12 Monate
2Tage seit letztem Push
12Releases
1Bus-Faktor
0offene Issues
GoPaket-Ökosysteme

Warnungen zur Datenerhebung

  • 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

Weitere Details

OpenSSF Scorecard 1.3 / 10
1.3Gesamtwert

Unabhängige, werkzeugneutrale Sicherheitsbewertung durch das quelloffene OpenSSF Scorecard. Jede Prüfung honoriert eine Sicherheits-Praxis, nicht das Werkzeug eines bestimmten Anbieters. Prüfungen, die Scorecard nicht ermitteln konnte, sind mit k. A. markiert und vom Sicherheitswert ausgeschlossen (nie als null gezählt).Scorecard v5.5.0 · 2026-07-26 22:42 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
0CI-Tests0 out of 8 merged PRs checked by a CI test -- score normalized to 0
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
k. A.Dangerous-Workflowno workflows found
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
9Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
k. A.Packagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
k. A.Signed-Releasesno releases found
k. A.Token-PermissionsNo tokens found
0Vulnerabilities12 existing vulnerabilities detected
Direkte Abhängigkeiten 10
RegistryPaketVersionsvorgabeManifest
Gogithub.com/BurntSushi/tomlv1.6.0go.mod
Gogithub.com/charmbracelet/bubblesv1.0.0go.mod
Gogithub.com/charmbracelet/bubbleteav1.3.10go.mod
Gogithub.com/charmbracelet/fangv1.0.0go.mod
Gogithub.com/charmbracelet/glamourv1.0.0go.mod
Gogithub.com/charmbracelet/harmonicav0.2.0go.mod
Gogithub.com/charmbracelet/huhv1.0.0go.mod
Gogithub.com/charmbracelet/lipglossv1.1.1-0.20250404203927-76690c660834go.mod
Gogithub.com/spf13/cobrav1.10.2go.mod
Gogolang.org/x/termv0.43.0go.mod
Alle Abhängigkeiten nicht erhoben

Der aufgelöste Abhängigkeitssatz konnte für diesen Bericht nicht erhoben werden: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

JSON-Rohbericht maschinenlesbar
{
  "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
}

Bewertungen sind Signale, keine Garantien. Sie spiegeln öffentlich sichtbare Praxis auf GitHub wider — kein Code-Audit und keine Sicherheitsgarantie.

Fehlende Daten werden ausgeschlossen und die Gewichte neu normiert, nie als null bewertet. Die Methodik ist versioniert und offen: Metriken v1.13.0, Schema v0.27.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte StatistikenGo.