Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 1.13.0 · 2026-07-26 22:42 UTC

andreicstoica / kit

Manage isolated Liftoff feature worktrees with a Bubble Tea TUI

GoLicencia propia★ 1 estrella⑂ 0 forksdesde may 2026Ver en GitHub ↗

andreicstoica/kit tiene un índice de salud de 44 sobre 100, lo que lo sitúa en la banda En riesgo. Su puntuación más alta es Vitality (76/100) y la más baja, Security (13/100). Se actualizó por última vez hace 2 días. Una sola persona concentra la mayor parte del trabajo reciente.

44
global / 100
En riesgo

Índice de salud del software

Las métricas se agrupan en categorías ponderadas sobre una escala de 1 a 100. El resultado global parte de su media; cuando la evidencia pública activa la Política de Jurisdicciones de Alto Riesgo, la calificación se ajusta y recibe el límite 49 (En riesgo). Preparación para IA queda fuera.

44
Excelente85-100Ejemplar; cumple prácticamente todos los criterios evaluados
Bueno70-84Saludable; carencias menores
Moderado50-69Aceptable con carencias notables; se recomienda revisión
En riesgo30-49Debilidades significativas; su adopción exige cautela
Crítico1-29Problemas graves (proyecto abandonado, un solo mantenedor, sin higiene)
VitalidadComunidad yAdopciónSostenibilidady GobernanzaCalidad deIngenieríaSeguridadPreparaciónpara IA

Perfil de puntuación

Cada eje es una categoría. La forma importa más que la media: un proyecto sano llena toda la figura, mientras que un perfil de picos y cráteres indica que la fortaleza en una dimensión enmascara el riesgo en otra.

Titularidad

Andrei StoicaCuenta personal
13 seguidores38 repositorios públicosdesde jul 2020

Este repositorio pertenece a una cuenta personal. Un proyecto con un único propietario conlleva más riesgo de continuidad que uno respaldado por una organización.

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicación
Gogithub.com/andreicstoica/kitv0.3.3-21hace 2 días

Métricas por categoría

Vitalidad

¿Está vivo el proyecto: se escribe código y se publican versiones?

76Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 2 días
6.2/36Cadencia de commits — 9/52 semanas con commits
17.8/18Volumen de commits — 96 commits en el último año
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Datos de entrada utilizados
commits_last_year96
human_commit_share1
days_since_last_push2
active_weeks_last_year9
Cómo se puntúa
27/27Publica versiones — 12 versiones publicadas
36/36Recencia de las versiones — última versión hace 47 días
27/27Cadencia de publicación — una versión cada ~1,4 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count12
latest_release_tagv0.2.5
releases_from_tagsno
days_since_latest_release47
mean_days_between_releases1,4
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

¿Tiene el proyecto usuarios, descargas, atención y unas condiciones acogedoras para quienes contribuyen?

21Crítico · 18% del índice global
Cómo se puntúa
0/60Estrellas — 1 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars1
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
16.9/22.5Licencia — archivo de licencia presente, no es una licencia reconocida
0/18Guía CONTRIBUTING
0/13.5Código de conducta
0/7.2Plantilla de issues
0/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno

Sostenibilidad y Gobernanza

¿Sobrevivirá el proyecto a sus personas: factor bus, capacidad de respuesta, quién lo respalda y mantenimiento del paquete?

54Moderado · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
0/22.5Distribución de commits — el principal contribuyente firma el 100% de los commits
1.4/13.5Amplitud de contribuyentes — 1 contribuyentes
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Datos de entrada utilizados
bus_factor1
contributors_sampled1
top_contributor_share1
Cómo se puntúa
0/46.8Resolución de issues — sin issues o sin datos
38.2/38.3Aceptación de PR — 13/13 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs13
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Excluidos de la puntuación (sin datos o no aplicable): Resolución de issues. Los pesos restantes se han renormalizado.
Cómo se puntúa
10/30Respaldo de la propiedad — cuenta personal (usuario)
0/20Dominio verificado — no aplicable a cuentas de usuario
8.2/25Alcance del propietario — 13 seguidores de andreicstoica
23.6/25Trayectoria — 38 repos públicos, cuenta de ~6 años
Datos de entrada utilizados
followers13
owner_typeUser
is_verified
owner_loginandreicstoica
public_repos38
account_age_days2198
Excluidos de la puntuación (sin datos o no aplicable): Dominio verificado. Los pesos restantes se han renormalizado.
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en go
35/35Recencia de publicación — última publicación hace 2 días
20/20Historial de versiones — 21 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packagesgithub.com/andreicstoica/kit
ecosystemsgo
any_deprecatedno
min_days_since_publish2

Calidad de Ingeniería

¿Existen unas prácticas mínimas de ingeniería y documentación?

40En riesgo · 20% del índice global
Cómo se puntúa
0/24Flujos de trabajo de CI
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-commit
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — 0 out of 8 merged PRs checked by a CI test -- score normalized to 0
Datos de entrada utilizados
has_cino
has_tests
has_editorconfigno
has_linter_configno
has_precommit_configno

Documentación

65Moderado
Cómo se puntúa
30/30README
25/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
0/10Topics
0/10Wiki
Datos de entrada utilizados
topics
has_wikino
homepage
has_readme
has_docs_dir
has_description

Seguridad

¿Son sólidas las prácticas visibles de seguridad y de cadena de suministro, sin exposición jurisdiccional de alto riesgo sin resolver?

13Crítico · 16% del índice global
Cómo se puntúa
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 — sin datos
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.2/2.5Licencia — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — sin datos
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 — sin datos
0/7.5Token-Permissions — sin datos
0/7.5Vulnerabilities — 12 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated14
scorecard_versionv5.5.0
checks_inconclusive4
scorecard_aggregate1,3
Excluidos de la puntuación (sin datos o no aplicable): dangerous_workflow, packaging, signed_releases, token_permissions. Los pesos restantes se han renormalizado.

Preparación para IA

¿Hasta qué punto está el repositorio preparado para desarrollarse y mantenerse con agentes de codificación de IA? Es una insignia independiente y experimental — peso 0,0, de modo que se presenta por separado y no afecta a la puntuación de salud global.

65Moderado · 0% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 93 de 96 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,969
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
18/18Arranque con un solo comando — Makefile
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — Go (tipado estático)
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 66 de los últimos 96 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Datos de entrada utilizados
has_nixno
has_tests
lockfilesgo.sum
has_dockerfileno
typed_language
bootstrap_filesMakefile
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0,688
toolchain_manifestsgo.mod
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — Go (tipado estático)
55/55Tamaños de archivo manejables — 0/120 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageGo
largest_source_bytes22.092
source_files_sampled120
oversized_source_files0

Datos clave

1estrellas de GitHub
1contribuidores
96commits en los últimos 12 meses
2días desde el último push
12versiones publicadas
1factor bus
0issues abiertas
Goecosistemas de paquetes

Advertencias de recopilación de datos

  • 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

Más detalle

OpenSSF Scorecard 1.3 / 10
1.3agregado

Evaluación de seguridad independiente y agnóstica en cuanto a herramientas, procedente del proyecto de código abierto OpenSSF Scorecard. Cada comprobación premia una práctica de seguridad, no la herramienta de un proveedor concreto. Las comprobaciones que Scorecard no pudo determinar se marcan como n/d y se excluyen de la puntuación de seguridad (nunca se cuentan como cero).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
n/dDangerous-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
n/dPackagingpackaging 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
n/dSigned-Releasesno releases found
n/dToken-PermissionsNo tokens found
0Vulnerabilities12 existing vulnerabilities detected
Dependencias directas 10
RegistroPaqueteRestricción de versiónManifiesto
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
Todas las dependencias no recopilado

No fue posible recopilar el conjunto de dependencias resuelto para este informe: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Informe JSON sin procesar legible por máquina
{
  "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
}

Las puntuaciones son señales, no garantías. Reflejan prácticas públicamente visibles en GitHub; no son una auditoría de código ni una garantía de seguridad.

Los datos ausentes se excluyen y los pesos se renormalizan; nunca se puntúan como cero. La metodología es versionada y abierta: métricas v1.13.0, esquema v0.27.0 — metodología completa · wiki de métricas.

Cómo se sitúa un resultado dentro del registro general: estadísticas agregadasGo.