Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 1.13.0 · 2026-07-29 02:40 UTC

juzcn / slife

Silicon-based life based on LLM

PythonMIT★ 0 estrellas⑂ 0 forksdesde jul 2026Ver en GitHub ↗

juzcn/slife tiene un índice de salud de 47 sobre 100, lo que lo sitúa en la banda En riesgo. Su puntuación más alta es Vitality (69/100) y la más baja, Security (30/100). Se actualizó por última vez hoy. Una sola persona concentra la mayor parte del trabajo reciente.

47
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.

47
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

juzcnCuenta personal
0 seguidores4 repositorios públicosdesde abr 2015

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
PyPIslife0.3.20204426hace 0 días
PyPIcredstore0.3.202776hace 0 días

Métricas por categoría

Vitalidad

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

69Moderado · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 0 días
2.1/36Cadencia de commits — 3/52 semanas con commits
18/18Volumen de commits — 348 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_year348
human_commit_share1
days_since_last_push0
active_weeks_last_year3
Cómo se puntúa
16.2/27Publica versiones — 20 etiquetas de versión (sin releases de GitHub)
36/36Recencia de las versiones — última versión hace 0 días
27/27Cadencia de publicación — una versión cada ~0,3 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count20
latest_release_tagv0.3.20
releases_from_tags
days_since_latest_release0
mean_days_between_releases0,3
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?

32En riesgo · 18% del índice global
Cómo se puntúa
0/60Estrellas — 0 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (MIT)
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
Cómo se puntúa
44.9/80Descargas mensuales — 2321 descargas/mes en pypi
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packagesslife, credstore
dependents
ecosystemspypi
total_downloads
monthly_downloads2321
Excluidos de la puntuación (sin datos o no aplicable): Dependientes en el registro. Los pesos restantes se han renormalizado.

Sostenibilidad y Gobernanza

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

32En riesgo · 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
0/38.3Aceptación de PR — sin PR decididos o sin datos
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Excluidos de la puntuación (sin datos o no aplicable): Resolución de issues, Aceptación de PR. 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
0/25Alcance del propietario — 0 seguidores de juzcn
17.1/25Trayectoria — 4 repos públicos, cuenta de ~11 años
Datos de entrada utilizados
followers0
owner_typeUser
is_verified
owner_loginjuzcn
public_repos4
account_age_days4127
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 — 2 paquete(s) en pypi
35/35Recencia de publicación — última publicación hace 0 días
20/20Historial de versiones — 26 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packagesslife, credstore
ecosystemspypi
any_deprecatedno
min_days_since_publish0

Calidad de Ingeniería

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

66Moderado · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 2 flujo(s) de trabajo
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-commit
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — sin datos
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_configno
has_precommit_configno
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: CI-Tests. Los pesos restantes se han renormalizado.
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
10/10Wiki
Datos de entrada utilizados
topics
has_wiki
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?

30En riesgo · 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 — sin datos
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
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/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 — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
6.8/7.5Vulnerabilities — 1 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated15
scorecard_versionv5.5.0
checks_inconclusive3
scorecard_aggregate3
Excluidos de la puntuación (sin datos o no aplicable): ci_tests, packaging, signed_releases. 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.

40En riesgo · 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 — 99 de 100 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,99
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
0/11Configuración de lint / formato
0/11Verificación estática de tipos
10/10Entorno reproducible — lockfile
10/10Práctica demostrada con agentes — 93 de los últimos 100 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
lockfilesuv.lock
has_dockerfileno
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0,93
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
0/45Código verificable por tipos — Python sin configuración de verificación de tipos
55/55Tamaños de archivo manejables — 0/144 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languagePython
largest_source_bytes52.062
source_files_sampled144
oversized_source_files0
Cómo se puntúa
0/40Esquema de API (OpenAPI/GraphQL/proto)
20/20Servidor MCP
0/40Ejemplos ejecutables
Datos de entrada utilizados
example_dirs
has_mcp_signal
api_schema_files

Datos clave

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

Advertencias de recopilación de datos

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index pypi:slife@0.3.20; advisories assessed against the repository dependency graph instead

Más detalle

OpenSSF Scorecard 3.0 / 10
3.0agregado

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-29 02:40 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
n/dCI-Testsno pull request found
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
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense 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
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
9Vulnerabilities1 existing vulnerabilities detected
Dependencias directas 18
RegistroPaqueteRestricción de versiónManifiesto
PyPIkeyring>=25.0.0credstore/pyproject.toml
PyPIkeyrings-cryptfile>=1.3.0credstore/pyproject.toml
PyPItextual>=1.0.0pyproject.toml
PyPIopenai>=1.0.0pyproject.toml
PyPIhttpx>=0.27.0pyproject.toml
PyPIjson5>=0.15.0pyproject.toml
PyPIjinja2>=3.1.0pyproject.toml
PyPIfastmcp>=2.0.0pyproject.toml
PyPIaiosqlite>=0.22.1pyproject.toml
PyPIsqlite-vec>=0.1.9pyproject.toml
PyPIaiohttp>=3.14.1pyproject.toml
PyPIqrcode>=8.0pyproject.toml
PyPIPillow>=11.0pyproject.toml
PyPIkeyring>=25.0.0pyproject.toml
PyPIkeyrings-cryptfile>=1.3.0pyproject.toml
PyPIpaho-mqtt>=2.0.0pyproject.toml
PyPIrequests>=2.31.0pyproject.toml
PyPIcredstorepyproject.toml
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": 1529,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Jinja": 814,
        "Shell": 18349,
        "Python": 1485232,
        "PowerShell": 23327
      },
      "pushed_at": "2026-07-29T02:38:05Z",
      "created_at": "2026-07-08T00:52:27Z",
      "owner_type": "User",
      "updated_at": "2026-07-29T02:38:06Z",
      "description": "Silicon-based life based on LLM",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "User",
      "login": "juzcn",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/11883152?v=4",
      "created_at": "2015-04-10T07:08:51Z",
      "is_verified": null,
      "public_repos": 4,
      "account_age_days": 4127
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.3.20",
          "kind": "patch",
          "published_at": "2026-07-29T02:37:57Z"
        },
        {
          "tag": "v0.3.19",
          "kind": "patch",
          "published_at": "2026-07-29T02:14:16Z"
        },
        {
          "tag": "v0.3.18",
          "kind": "patch",
          "published_at": "2026-07-29T01:59:57Z"
        },
        {
          "tag": "v0.3.17",
          "kind": "patch",
          "published_at": "2026-07-29T01:38:06Z"
        },
        {
          "tag": "v0.3.16",
          "kind": "patch",
          "published_at": "2026-07-26T03:17:56Z"
        },
        {
          "tag": "v0.3.15",
          "kind": "patch",
          "published_at": "2026-07-26T03:15:54Z"
        },
        {
          "tag": "v0.3.14",
          "kind": "patch",
          "published_at": "2026-07-26T03:08:19Z"
        },
        {
          "tag": "v0.3.13",
          "kind": "patch",
          "published_at": "2026-07-26T03:05:40Z"
        },
        {
          "tag": "v0.3.12",
          "kind": "patch",
          "published_at": "2026-07-26T03:01:14Z"
        },
        {
          "tag": "v0.3.11",
          "kind": "patch",
          "published_at": "2026-07-26T02:57:10Z"
        },
        {
          "tag": "v0.3.10",
          "kind": "patch",
          "published_at": "2026-07-26T02:46:02Z"
        },
        {
          "tag": "v0.3.7",
          "kind": "patch",
          "published_at": "2026-07-19T08:01:29Z"
        },
        {
          "tag": "v0.3.4",
          "kind": "patch",
          "published_at": "2026-07-19T03:05:32Z"
        },
        {
          "tag": "v0.3.3",
          "kind": "patch",
          "published_at": "2026-07-19T02:56:01Z"
        },
        {
          "tag": "v0.3.2",
          "kind": "patch",
          "published_at": "2026-07-19T02:49:25Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2026-07-19T02:29:49Z"
        },
        {
          "tag": "v0.2.3",
          "kind": "patch",
          "published_at": "2026-07-19T00:21:18Z"
        },
        {
          "tag": "v0.2.2",
          "kind": "patch",
          "published_at": "2026-07-19T00:03:16Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-07-18T23:45:17Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-07-18T23:40:11Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "f9e15f0bb994e279cc1b662a31bc22eabb535205",
          "body": "fix: use uv pip install for gguf wheel, not uv tool install --reinstall\n\nuv tool install --with \"...\" slife --reinstall reinstalls slife from PyPI,\noverwriting the install script version and potentially changing the Python\ninterpreter. This caused plugin discovery (pkgutil.iter_modules) to fail.\n\nInstead, use uv pip install --python <venv-python> to add the wheel directly\ninto the existing venv without touching slife itself.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-29T02:37:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c324208463b7a55ba870a159adb13f5c5efd4701",
          "body": "debug: add __path__ logging to discover_plugins\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-29T02:33:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d2907ff2656beb12f4d1ab84ee7911deb5ef14d1",
          "body": "chore: bump to 0.3.19, simplify gguf install to single command\n\nUse uv tool install --with \"llama-cpp-python @ wheel-url\" slife --reinstall\ninstead of three separate commands (install + extract venv + pip install).\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-29T02:14:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "04db27c8d2a270f5760695de045736c6006fd216",
          "body": "chore: bump to 0.3.18, fix install extras hints for Windows\n\n- install.ps1: show correct pre-built wheel commands for gguf extra\n  (Windows has no C++ compiler — direct install fails)\n- install.sh: keep simple command (Linux/macOS builds from source)\n- README.md / README.zh-CN.md: clarify gguf install instructions\n  with platform-specific decision table\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-29T01:59:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5bc4c97451897983f787d7d909148c9cfb04f25f",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump credstore version to 0.3.17",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-29T01:38:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "05f63cb5f8baf9d24a7f984f6d2d0b37205a3c12",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.3.17",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-29T01:36:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e472918ec5c97c141c218dfcd8b6db296c160766",
          "body": "docs: rewrite README, DESIGN, credstore README; optimize install/uninstall scripts\n\nREADME.md (655→228 lines): concise user manual — install, quick start,\nfeatures overview, shortcuts. Points to DESIGN.md for architecture.\n\nDESIGN.md (1260→352 lines): architecture reference — philosophy, agent loop,\n[…]\nified ✓ output.\n\ninstall.sh: simplify extra-index-url parsing (30→4 lines).\n\nuninstall.ps1 / uninstall.sh: unified ✓/✗ output, better error reporting.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-29T01:24:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d0b13e747d1c1c41bd749bd07c72d3618805dd4d",
          "body": "Save full freeze alongside name-only list, print each extra package\nwith its version/URL from the old installation during re-add.",
          "is_bot": false,
          "headline": "feat(install.sh): show extra packages with versions before re-adding",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T15:43:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bc465c211fb0e07b9c652265f7d849e8fdb499b5",
          "body": "Save full freeze (with versions) alongside name-only list.  When\nre-adding, print each extra package with its version/URL from the\nold installation so the user can see what is being preserved.",
          "is_bot": false,
          "headline": "feat(install): show extra packages with versions before re-adding",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T15:42:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d09465719321bf17a7e1211125473b31f02f2d82",
          "body": "The TOML array format \"extra-index-url = [\\n  \"url\",\\n]\" requires\nreading multiple lines.  Fix both install.ps1 (PowerShell loop with\nstate machine) and install.sh (collect lines until closing bracket).",
          "is_bot": false,
          "headline": "fix(install): handle multi-line extra-index-url in pyproject.toml",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T15:35:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b0cf1204420e1bb797b2d6ff7fb5c3ac6d8f688a",
          "body": "Add-Content appends to existing file, causing stale entries from\nprevious install runs to accumulate.  Add Set-Content at the start\nto clear the file before detecting packages.",
          "is_bot": false,
          "headline": "fix(install): clear preserved reqs file before appending",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T15:31:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "34567635fbc083691c48bea0552103402a6eecda",
          "body": null,
          "is_bot": false,
          "headline": "fix(install): handle name-at-url and -e path freeze formats",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T15:26:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b5d61a46e0681cb9da26c53e9183d5701a685660",
          "body": "Instead of trying to re-add all 105 frozen packages (mostly transitive\ndeps already provided by base slife), freeze the new venv after base\ninstall and only re-add packages whose names are NOT in the new freeze.\nThis avoids version conflicts and makes uv pip install much faster.\n\nAlso: save requirements file outside temp dir, show error details on\nfailure.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(install): diff old/new freeze to only re-add truly extra packages",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T15:22:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c8a8ce17259c443a1fb5c9468bf6348a0d7c5223",
          "body": "…igured\n\nWhen _reindex_impl returns complete=True, _background_reindex exits\nand never retries.  If the embedder is configured but not yet ready\n(e.g. llama-cpp-python being installed), return complete=False so the\nbackground task keeps retrying.  Only return complete=True when\nembedding was never configured at all.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(memory): return complete=False when embedder unavailable but conf…",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T15:16:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5824214cc99f7e29283d1ca25b6c91edf8a63022",
          "body": "asyncio.create_task() return value was discarded, so the task could\nbe garbage-collected before execution.  Store the Task reference in a\nmodule-level _reindex_task variable (with global declaration) and\ncancel any previous task before starting a new one.\n\nAdd background_reindex_started log for observability.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(memory): track background reindex task to prevent GC",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T15:13:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ef6a225f16fd8e5af9ee8e66109d65e2d903d84e",
          "body": "mcp-server-fetch imports McpError which was renamed to MCPError in\nnewer mcp versions.  Pin mcp>=1.0,<1.29 via --with in the fetch\nserver config so uvx resolves a compatible mcp version.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(template): pin mcp<1.29 for fetch MCP server McpError compat",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T14:46:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "51b975c39fba453e912261f821430fca44d9174b",
          "body": "Replace manual per-package detection (llama-cpp-python, sentence-\ntransformers) with uv pip freeze on the old venv.  This captures all\nuser-installed packages — extras, --with, pip install, direct URLs —\nand re-adds them in a single uv pip install -r command.\n\nSimpler, more robust, and handles any package the user may have added.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(install): use uv pip freeze to capture all user packages",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T14:36:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ab08b25163ba9b8ebedde01db1d4cab7b2cd4c57",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(uninstall): list ~/.credstore/ in remaining data, keep it untouched",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T14:31:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2e20a129709cd3aa6f5004f13fb380ebb682be8c",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(uninstall): clean up slife.exe/credstore.exe wrapper binaries",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T14:30:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "018e94550a0e12b2b970b27060644a49ee9378bf",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(readme): fix Windows uninstall to use irm|iex one-liner",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T14:29:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "119c1e8f35522c3566223aa29eb64c275f709f65",
          "body": "- Add Update/Reinstall section: install preserves optional packages\n- Add Uninstall section with script commands and full reset flow\n- Update Windows embedding wheel command: uv pip install into tool venv\n- Document that slife + credstore share the same isolated venv\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(readme): add uninstall scripts, update reinstall/embedding sections",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T14:28:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8a290b4e0e39c9ed5acc0d75ced604d114b64828",
          "body": "uninstall: removes slife (+ credstore, same venv) via uv tool\nuninstall, then lists remaining user data files for manual cleanup.\n\ninstall: always preserves previously installed optional packages.\nFor a clean reinstall, run uninstall first, then install.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add uninstall scripts, remove -Reset flag from install",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T14:26:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9e6a541b0d5182b41bedc48516ffcfa6f0f38523",
          "body": "-Fresh skips package preservation detection and removes ~/.slife/\nuser data directory, giving a completely clean install.  Without\nthe flag, the installer preserves previously installed optional\npackages (llama-cpp-python, sentence-transformers) as before.\n\nUsage:\n  .\\install.ps1 -Fresh          (Windows)\n  curl .../install.sh | bash -s -- --fresh   (Linux/macOS)\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(install): add -Fresh/--fresh flag for clean reset install",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T14:18:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e0afceae6debb3ef9c723b83feb23f49874fdcbb",
          "body": "When re-adding preserved packages, read [tool.uv] extra-index-url from\nthe project pyproject.toml and pass it to uv pip install.  This lets\npackages like llama-cpp-python resolve pre-built wheels from the CPU\nwheel registry.  Falls back gracefully when the setting is absent.\n\nAlso fix the end summary to distinguish succeeded vs failed packages\ninstead of blindly printing [OK] for all.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(install): pass extra-index-url from pyproject.toml to uv pip install",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T14:14:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2a394841223b5c8a7beda7039d5bc4b92850792e",
          "body": "Replace || true with proper $? check so the user sees whether\nuv pip install actually succeeded or failed for each preserved\npackage.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(install.sh): check exit code instead of blindly printing ✓",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T13:58:26Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "909f0033042870e1b09e060ebcfbc2d9ec26e452",
          "body": "PowerShell 5.1 treats stderr from native commands as errors even with\n*>> redirection.  Use 2>&1 | Out-File -Append to merge streams and\navoid spurious NativeCommandError display.  Also re-set\nErrorActionPreference for the pip install section since it was\nrestored to Stop after the uv tool install block.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(install): use 2>&1 instead of *>> to avoid NativeCommandError",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T13:57:11Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "862800cb5fc3cf8e1bc00f7d74028a2bc4e4db7c",
          "body": "Add check_mcp_servers to the system_health orchestrator.  It finds the\nmcp_list_servers proxy tool via the registry and calls it, then formats\nthe result as health entries.  _run_checks now supports both sync and\nasync check functions.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(system_health): call mcp_list_servers to report MCP status",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T13:52:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6175611482ecd8897ced2420d55b876a9391d2ab",
          "body": "Before uninstall, scan the old venv for optional packages.  Check\ndirect_url.json in each dist-info to determine the original install\nmethod: replay the URL if present, otherwise uv pip install <name>.\n\nThis is more faithful than assuming slife[gguf] extras -- the user\nmay have installed via pip, a specific wheel URL, or compiled from\nsource.  Replaying the same method preserves their intent.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: detect original install method, replay with uv pip install",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T13:40:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6ad50c8b8611bdb7a03c20081ba0d2e4117c7831",
          "body": "Using --with llama-cpp-python causes uv to build from source (fails on\nWindows without CMake/C++ compiler).  Switch to slife[gguf,transformer]\nextras in the package spec so uv resolves dependencies through\npyproject.toml extra-index-url and picks up pre-built wheels.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: use slife[gguf]/slife[transformer] extras syntax for wheel installs",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T13:37:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "91978c8f1406c0a81171e9430d315f3084d61996",
          "body": "fix: preserve embedding extras across reinstall, use uv pip install in hints\n\ninstall.ps1 / install.sh: before uv tool uninstall, detect\nllama-cpp-python / sentence-transformers in the old venv and re-apply\nthem via --with on the new install.  Without this, reinstalling slife\nsilently drops optional\n[…]\nsystem.  Stays as a simple one-liner that works while\nslife is running (unlike uv tool install --with which cannot run when\nthe executable is locked).\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T13:32:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "88b0f34dc00a8553765f7df763da8d5b525ad291",
          "body": "… warnings\n\n- Extract PluginLifecycle from AgentService (1327→1150 lines)\n  - Replace setattr/getattr dynamism with typed PluginLifecycle container\n  - Eliminate 6x repeated create_proxy_tools lazy imports\n  - Simplify _stop_plugin, _spawn_and_register_plugin, _connect_plugin_http\n\n- Unify 3 secret \n[…]\n Add __slots__ to conftest mock classes\n- Add pytest_configure hook to conftest\n- Add [tool.coverage] config\n- Add docstrings to empty __init__.py files\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "@ refactor: extract PluginLifecycle, unify config helpers, fix 5 test…",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T13:18:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ad8b48c753667d517447506287f0c8254b130cf6",
          "body": "…dy, consolidate duplicates",
          "is_bot": false,
          "headline": "docs(credstore): rewrite README — remove nonexistent is_cryptfile_rea…",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T08:42:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4ed2a1c2acc3e36587720503a375a7d777dc1557",
          "body": "Source changes:\n- Fix __version__ to read from importlib.metadata (was hardcoded 0.3.6)\n- Move inline imports to module level in _store.py (use _be. prefix)\n- Move shell imports to module level in __main__.py\n- Extract _read_old_cryptfile_data / _re_encrypt_old_data from _cmd_set_password\n- Replace \n[…]\nnject shell tests and Mask tests\n- Fix fragile builtins.__import__ override in test_backend.py\n- Add TestReadCryptfileEntry coverage (2 tests)\n- Add unit/integration/slow test markers\n\n234 tests pass.",
          "is_bot": false,
          "headline": "refactor(credstore): optimize source structure and pytest suite",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T08:36:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "410414f023aa5e3e54e81d1fb697dcc0e3daf8ed",
          "body": "fix: redirect all streams on uv tool uninstall\n\nPS 5.1 treats native-command informational output to stderr as errors\nwith $ErrorActionPreference=Stop. Use *>$null + try/catch to suppress\nall streams unconditionally.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T07:49:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a7746b0ade6f439a9526845ca23c4939d46740c0",
          "body": "fix: avoid PS 5.1 ErrorRecord wrapping on \"uv tool uninstall\"\n\nPowerShell 5.1 wraps native-command stderr lines in ErrorRecord objects\nwhen using 2>&1, triggering $ErrorActionPreference=Stop and aborting\nthe install script.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T07:45:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "55e437f9a94de399fc6f82084c7611a50ef1e6ff",
          "body": "fix: uninstall slife before reinstalling in install scripts\n\nPrevious broken installations (e.g. from \"uv tool install --with\nslife[gguf] slife\" run by the LLM mid-session) can leave the tool\nvenv in a corrupted state.  \"uv tool install\" sees the tool already\nexists and may skip essential setup, resulting in \"failed to locate\npyvenv.cfg\" at runtime.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T07:41:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "11322ce7311a2079915af1a8623c050f7385700f",
          "body": "refactor: simplify embedding tool descriptions\n\n- memory_set_embedding: remove inaccurate model sizes, fix wrong\n  reference (memory_disable_embedding -> memory_set_enabled),\n  add parameter docstrings for backend/model/gguf_path/dim/device\n- memory_set_enabled / memory_check_embedding: trim redundant text\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T07:35:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "24e2876fc6f125e9051542048c79dff07c8b3c67",
          "body": "fix: cancel stream immediately + safe env_hint for production\n\n- _process_stream: pass cancel_event to chat_stream so cancellation\n  closes the HTTP stream immediately instead of silently consuming it\n- chat_stream: accept optional cancel_event, close stream when set,\n  with a finally block as safet\n[…]\n LLM-executable command — use \"uv pip install\" instead\n  and forbid killing the slife process\n- get_venv_python(): new helper returning sys.executable\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T07:31:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1578fa6ab486791f0d91f58c136d6162aa6724de",
          "body": "Skills must be bundled in the wheel so they can be copied to\n~/.slife/skills/ on first run. The force-include places them in\nthe package at build time; get_skills_dir() always returns the\ndata_dir copy at runtime.\n\nWithout this, pkg_skills.is_dir() returns False and seeding\nnever happens.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: restore skills force-include — needed as seed source",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T06:57:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c60f055d83698519f2ecc50bd5cc4617d311448d",
          "body": "- README: Python is managed by uv, not installer; updated requirements\n  table; added skills row to dev/production table; updated descriptions\n- DESIGN: updated install script dependency list (uv manages Python)\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: update README and DESIGN for uv tool install + skills location",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T06:52:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "600ce51d5c7aa9247980a715902f09ea980975f2",
          "body": "…tion\n\n- skill.py: update CheckSkillsDirTool and _resolve_skills_dir docstrings\n- platform.py: update _resolve_skill_script docstring\n- All reference the new data_dir/skills layout, not the package bundle\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: update skill-related docstrings to reflect ~/.slife/skills loca…",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T06:49:20Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b14bdf2402fa72881213aa56594f9493572752f2",
          "body": "Skills are now seeded from the package to ~/.slife/skills/ on first\nrun, like slife.json5. Users can edit and add their own skills;\nuv tool install upgrades won't overwrite them.\n\n- paths.py: get_skills_dir() simplified to get_data_dir()/skills\n- __init__.py: seed skills from package on first run (like config)\n- pyproject.toml: remove skills from force-include (no longer\n  bundled in the wheel)\n- test_paths.py: updated for new single-source logic\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: move skills to data directory (~/.slife/skills)",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T06:47:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9a57fa7cab368b8addeb467b9b10f81c3b034522",
          "body": "pip is not standard in uv tool install environments. Package\ninstallation is handled by:\n- slife's install_python_package tool (uses uv pip install)\n- uv tool install --with 'slife[gguf]' slife for extras\n\nAlso remove the PATH prepend in __init__.py that was added to\nexpose pip — no longer needed.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: remove --with pip — use standard uv tool install",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T06:18:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bbbdfb1b8af73fab6547c9e7967602542ae6191c",
          "body": "Remove ~90 lines of manual Python detection and installation per\nscript.  uv's --python 3.13 flag auto-downloads and manages the\ncorrect Python version — no more winget/apt/brew/dnf/pacman\nPython install logic, no more PATH hunting, no more Windows Store\nalias removal.\n\ninstall.ps1:  6 steps → 5 steps,  375 → 228 lines\ninstall.sh:   6 steps → 5 steps,  274 → 209 lines\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: standard uv tool install — let uv manage Python",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T06:17:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "80a3629c8e5fbdb2f77bfd8429a898e86e58bb15",
          "body": "- _config.py: simplify is_slife_dev to a plain function (no try/except\n  import override — both implementations do the same thing)\n- test_config.py: use getattr() to bypass Pylance's inability to\n  statically resolve conditionally-defined module attributes\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: resolve Pylance LSP errors in credstore test_config",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T06:10:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "648fa5fb31d414e6e860c4eb91479d1c851695c3",
          "body": "Single source of truth for dev/production environment hints,\nshared by system_prompt.j2 and check_workspace. No more\nduplicated text to maintain.\n\n- paths.py: add get_environment_info() → dict with mode + hint\n- system_prompt.py: pass env_hint to template instead of bare is_dev\n- system_prompt.j2: render env_hint directly, drop if/else block\n- system.py check_workspace: use get_environment_info()\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: unify environment description in paths.get_environment_info()",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T06:02:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "186e5f315731a56a64e019ded787274333648388",
          "body": "- system.py check_workspace: replace duplicated dev detection with\n  paths.is_dev(), split into clear sections (slife environment vs\n  user's CWD project)\n- Dev hint: 'uv managed project (editable workspace)'\n- Production hint: 'uv tool install (isolated venv). User data: ~/.slife/'\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: use paths.is_dev() in check_workspace, improve env hints",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T05:59:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a8311066aee2061abcec3448302cce5e28070e50",
          "body": "- paths.py: rename _is_dev to public is_dev, update all references\n- system_prompt.j2: show 'uv managed project' in dev mode, 'uv tool\n  install' instructions in production mode\n- system_prompt.py: pass is_dev flag to template\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: differentiate dev vs production in system prompt",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T05:57:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "be05cb94f209db2e4c867a9e8f6d8577425085da",
          "body": "…urces\n\n- system_prompt.j2: add concise uv tool install notes so LLMs know\n  how to install extras (gguf/transformer) and repair a broken env\n- pyproject.toml: add [tool.uv.sources] credstore = { workspace = true }\n  so uv resolves credstore from the local workspace, never PyPI\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add uv tool install context to system prompt + fix workspace so…",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T05:54:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d053bbfa4135644ae651c03bfdaca16ecb4e04aa",
          "body": "- install.ps1 / install.sh: add --with pip so pip is installed in the\n  uv-managed venv\n- slife/__init__.py: prepend venv Scripts/bin to PATH at startup so\n  subprocesses find pip directly (\"pip install xxx\" just works,\n  no need for \"python -m pip\")\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: ensure pip is available in slife's environment",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T05:26:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "aa85630873db76874d5be7b22c90c8a916110f8d",
          "body": "Replace ~60 lines of manual venv management, pip install, .cmd/.sh\nwrapper generation, and PATH manipulation with a single command:\n\n    uv tool install --from <source> --python <python> slife\n\nKey changes:\n- pyproject.toml: add credstore as workspace dependency so uv\n  resolves it from the local so\n[…]\nvenv — it is purely a user data directory\n  managed by the app, not touched by the installer\n- Old venv artifacts in ~/.slife/ are cleaned up on upgrade\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: use uv tool install instead of manual venv + pip + wrappers",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T05:13:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "163131a935bb4ba86fd7572f72c16a8e0c864b74",
          "body": "The extra double-quote before %* in the generated .cmd files caused\ncmd.exe to treat it as an escaped quote within the path string,\nmaking the command name literally contain a trailing quote character\n(e.g. credstore.exe\") which doesn't match any file on disk.\n\nBefore: @\"C:\\...\\credstore.exe\"\" %*\nAfter:  @\"C:\\...\\credstore.exe\" %*\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: remove stray quote in .cmd wrapper generation",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-28T04:53:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c16f821e3a220b530b929bee1ddb010d8e5e5a7f",
          "body": "fix: tolerate winget \"already installed\" exit code in install.ps1\n\nwinget install exits non-zero when the package is already present\nand no upgrade is available. Before this fix the installer treated\nany non-zero exit as a fatal error, even when Python 3.13 was\nactually on disk.\n\n- Check known insta\n[…]\nt as advisory, not fatal — verify the\n  expected install path on disk before giving up\n- Refresh PATH as a last resort if the expected path is missing\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T05:46:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "310a8affcda12183e1ba16312ec907117c74a226",
          "body": "fix: find Python in default winget path, not registry PATH\n\nwinget upgrades may lag registry PATH updates.  Look up the default\ninstallation directory (%LOCALAPPDATA%\\Programs\\Python\\Python313\\)\ndirectly instead of relying on Get-Command.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T05:38:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "15e4b8a6e13774240d59b0fc8a78604488f5ed9b",
          "body": "install: drop uv python fallback — use system package manager or manual install\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T05:29:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "53c1cd910b10bd81809561dbd7b7f42cac8a5601",
          "body": "install: use system package managers for Python (winget/apt/brew/dnf/pacman)\n\nSystem-level Python should come from the OS package manager, not uv.\nuv python install is only a fallback when no package manager is available.\n\n- Windows: winget install Python.Python.3.13 → python.exe + pip.exe on PATH\n-\n[…]\ninux:   apt-get / dnf / pacman install python3.13\n- Fallback: uv python install 3.13\n- Cleanup stale python.cmd / pip.cmd shims from previous installs\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T05:28:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8513bd89a2f37f0c81ceb50e43a4036b7371af31",
          "body": "refactor: remove cmd shims — venv entry points are self-contained\n\n- Drop python.cmd / pip.cmd shims — python3.13 is the user-facing name\n- Drop VIRTUAL_ENV in slife.cmd — .exe shebang handles it\n- Clean separation: we install system tools, we dont rename them\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T05:18:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "98ffa1171a03d03d17bcff70dc96ecdc050cc738",
          "body": "refactor: only touch system PATH/python/pip when WE install Python\n\nIf Python >= 3.13 already exists → use it, dont touch anything.\nIf not → uv python install 3.13 → set up PATH + python.cmd + pip.cmd.\n\nClean separation: the users system is respected, never polluted.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T05:17:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9fb47f76c1d77bca5bc34945b8cb9576e6a68fbc",
          "body": "install: Python is a system-level tool — persistent PATH + python shim\n\n- Python directory now persisted in user/system PATH, not just session\n- Versioned executables (python3.13/python3) get a \"python\" shim/symlink\n- Same behavior on Windows (.cmd shim) and Unix (symlink)\n\nDesign principle: python, uvx, npx are system tools slife depends on —\nnot slime private tools. The user should be able to use them for\nany purpose after installation.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T05:00:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ef73160798553328aae408543ad82e9571840f2d",
          "body": "fix: sqlite-vec rejects GROUP BY in KNN — dedup in Python instead\n\nsqlite3.OperationalError: Only a single ORDER BY distance clause\nis allowed on vec0 KNN queries, not on other columns.\n\nFetch 2x-4x results and deduplicate by diary_rowid in Python,\nkeeping the best (lowest distance) chunk per turn.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T04:38:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "698db8d09b5c957318b000fbb76224879d520f4c",
          "body": "fix: clean up stale slife.exe in ~/.local/bin before creating .cmd wrapper\n\nPATHEXT has .EXE before .CMD — an old .exe shim (from uv tool install\nor pre-Step-6-rework) would shadow our .cmd wrapper, causing\n\"ModuleNotFoundError: No module named slife\".\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T04:30:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "88b06ae390e1ed6f1617094ec71cad965567a67b",
          "body": "fix: use venv pip path for extras install, not system pip\n\nSince Step 6 no longer adds ~/.slife/Scripts to PATH, plain \"pip\"\nresolves to the system pip — installing to the wrong environment.\nUse the absolute path to the venv pip.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T04:12:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "957752598030839a6252d9fdf45d37aa7ac9e8a4",
          "body": "fix: install verification — check exe exists instead of running --help\n\nslife --help triggers full startup (config load, MCP connect, keyring…).\nOn some systems this hangs, blocking the installer indefinitely.\nSwitch to Test-Path / [ -x ] — the Python import check already\nverifies functionality.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:44:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "411c000db2d6caa412196dcaafaff0369ae45e48",
          "body": "install: add --extra-index-url for llama-cpp-python pre-built wheels\n\nWindows lacks a C++ compiler; pip install slife[gguf] fails with\n\"CMAKE_C_COMPILER not set\" when building llama-cpp-python from source.\nThe abetlen index provides pre-built wheels for all platforms.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:40:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1ed09d30d68711fb3296e7b6ef4a802cbc0b78cb",
          "body": "docs: sync README/DESIGN with memory/embedding changes\n\n- README: add transformer backend, memory_set_enabled, chunking, auto-reindex\n- README.zh-CN: 同步中文版,加工具表 + 分段嵌入说明\n- DESIGN: 更新 embedding 工具列表 (7 LLM-visible tools)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:35:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2e7bfce0a6e8ad014dea25856e4a089b2277836e",
          "body": "chore: update uv.lock for gguf/transformer extras split\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:33:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "62a18e35011b680e80d11dd644551d2adea99283",
          "body": "fix: RuntimeWarning — mock _log_stderr directly instead of patching create_task\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:32:42Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2782e21ae4919b9080af834f9a9f7991668e3645",
          "body": "test: fix test_memory_store for chunked embedding + new upsert signature\n\n- save_turn: embed_one → embed (batch chunks), overflow → chunk test\n- upsert_embedding: rowid → diary_rowid + chunk_index\n- has_embedding: rowid → diary_rowid\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:31:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1e5f84618c34b84b0a96442cd23409d5f6270489",
          "body": "refactor: merge memory_enable/disable into memory_set_enabled(enabled: bool)\n\n单一开关,语义清晰无歧义。\nset_embedding 负责配置模型,set_enabled 负责开关。\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:28:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fdd0e76003b2dd623a9c86ec7d54f4836f0994e2",
          "body": "feat: split enable/disable, set/config/restart are separate concerns\n\nmemory_set_embedding     → config + enable (always sets enabled: true)\nmemory_enable_embedding  → re-enable after disable (no params, uses existing config)\nmemory_disable_embedding → disable but keep config + data (sets enabled: f\n[…]\n:\n- from_config() reads memory.embedding.enabled from slife.json5\n- enabled=false → _available=False, skip backend detection\n- 状态持久化: 重启后 disable 状态保留\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:27:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8ae223da982e6ebfdaa48aba07964a64a2b2cba6",
          "body": "docs: update embedding_config module docstring to match renamed tool\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:23:44Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ed4d0c02320f03b4a81699ea287c6de9eb1576b3",
          "body": "rename: memory_remove_embedding → memory_disable_embedding\n\nremove 暗示永久删除数据,实际只是关闭配置。\ndisable 明确表示可逆 — 配置和已有嵌入数据均保留,\nmemory_set_embedding 重新启用同模型时无需重建索引。\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:23:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8a2f3c114601d6b0dd5e3d05b03df6c2d01e9c98",
          "body": "docs: update memory_remove_embedding schema — clarify preserved data\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:20:58Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c0fbe7bb455aacf54d9de7af861b56d007a7e7e5",
          "body": "docs: update memory_set/check_embedding schemas\n\n- memory_set_embedding: 详细描述三种后端 + 自动后台 reindex 行为\n- memory_check_embedding: 新增 unembedded 字段, 报告 reindex 进度\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:19:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fc9edcb48e0e624e1c3762c899afc90e3a89c948",
          "body": "refactor: memory_reindex 改为 harness-only, memory_set_embedding 自动触发\n\n- memory_reindex: 标记为 harness-only(description 含 \"harness-only\"),LLM 不可见\n- 提取 _reindex_impl: 核心逻辑复用,memory_reindex 和 _background_reindex 共享\n- _background_reindex: 每批 5 条,间隔 500ms,静默后台跑直到 complete\n- memory_set_embedding: 成功后 asyncio.create_task 触发后台 reindex,\n  状态中返回 reindex 提示(N 条待处理)\n- 删掉旧 DB 重新开始即可,不向后兼容\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:15:20Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4796a074410d00b82bab366190b617eb0762cb09",
          "body": "feat: memory_reindex — 对未嵌入的 turn 重建语义索引\n\n新增 memory_reindex 工具:\n- 配置/更换 embedding 后调用,批量对新旧 turn 生成嵌入\n- reset=true 清除全部旧嵌入,从头重建(换模型/维度时使用)\n- 分批处理 (batch_limit=20),返回 {total, indexed, remaining, complete}\n- complete=false 时再次调用继续,直到 complete=true\n\nstore.py 新增:\n- get_unembedded_turns(limit) — 查询 diary_semantic 中缺失的 turn\n- count_unembedded() — 统计待索引数量\n- clear_all_embeddings() — 更换模型时清空旧嵌入\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:10:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "daa5fa9a5d61b9e7683a64fe853283d5f810995b",
          "body": "feat: 长 turn 分段 embedding — 按段落边界切片,不再因超长跳过\n\n之前: turn 文本超过模型 token 上限→直接跳过,semantic search 找不到。\n现在: 按 \\n 段落边界切成 ~2000 字符的 chunk(含 1 段重叠),\n     每个 chunk 独立嵌入,搜索时按 diary_rowid 去重取最佳匹配。\n\n- schema.sql: diary_semantic 新增 diary_rowid + chunk_index 辅助列\n- store.py: 新增 _chunk_text() + _clear_chunks(), save_t\n[…]\n嵌入,\n  upsert_embedding() 支持多 chunk, search_semantic() GROUP BY 去重\n- server.py: memory_summarize 适配新签名 (diary_rowid + chunk_index)\n- 不需迁移: 删旧 DB 重新开始即可\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T03:06:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f33220750a90ce076d045c4403ee5ef3c2fee98e",
          "body": "docs: fix zh-CN dev setup missing --all-extras\n\nuv sync 不带参数只装核心依赖,llama-cpp-python 在 gguf extras\n组中,不会被安装。与英文 README 对齐,改为 --all-extras。\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T02:55:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "02f21b9fd52e0e4b5caff84beff0525e990bfb34",
          "body": "fix: type-narrow gguf_path before passing to Llama()\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T02:53:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "150d4a68d7a6a3747e1ab8af3ec9707c4a42323e",
          "body": "chore: split embeddings extra into gguf + transformer\n\n之前 slife[embeddings] 同时安装 llama-cpp-python 和 sentence-transformers,\n后者依赖 PyTorch(~2 GB)。只用 GGUF 本地模型的用户不需要下载 PyTorch。\n\n现在:\n- slife[gguf]         → 仅 llama-cpp-python (~30 MB)\n- slife[transformer]  → 仅 sentence-transformers (~2 GB)\n- slife[embeddings]   → 两者都装 (向后兼容)\n\n文档和安装脚本同步更新,推荐默认使用 slife[gguf]。\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T02:52:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f56c876a0ce79baf694c41ec99c74b79ae1ceae0",
          "body": "fix: hybrid search 在生产环境总是降级为 FTS5\n\n根因: from_config() 在无 embedding 配置时回退到 API 后端检测,\n读取 models.providers 中的 api_key: \"${DEEPSEEK_API_KEY}\"——${VAR}\n占位符被当作真实 API key(非空字符串),导致 _available=True。\n但后续 API 调用时 OpenSearch 收到字面量 \"${...}\" 返回 401,\nembed_one() 返回 None,semantic_available 始终为 False。\n\n修复:\n1. embeddings.py: from_config() 跳过 ${VAR} 占位符 API key\n2. server.py: memory_search hybrid 降级时返回诊断 hint,\n   指明原因(未安装 llama-cpp / GGUF 缺失 / API key 占位符等)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T02:45:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5a848290bffedac82fb54af0418b606431f83b3d",
          "body": "slife.template.json5: 移除 execute_shell 和 run_python_script 的 tools 覆盖\n\n保留 install_python_package 的 disabled 配置。\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T02:39:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "46a04544a609f8ac7ba5c6a3f96428dd792b9565",
          "body": "install: Step 6 改用入口脚本替代 venv PATH 注入\n\n之前 Step 6 把 ~/.slife/Scripts(或 bin/)整个目录加入系统 PATH,导致\nvenv 内的 python、pip 等被全局暴露。用户执行 python/pip 时无意中使用了\nslife 的 venv,卸载 slife 后这些命令也随之消失。\n\n改为在 ~/.local/bin/ 下创建仅暴露 slife + credstore 的入口:\n- Windows: slife.cmd / credstore.cmd 包装脚本 → venv 内的 .exe\n- Unix: slife / credstore 符号链接 → venv 内的入口点\n- 同时清理旧版安装残留的 ~/.slife/Scripts PATH 条目\n\nvenv 的 python/pip 保持私有,不污染用户全局环境。\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T02:39:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a4c5cc4c5fe2291e8e9507e69dc72a000f8d28cf",
          "body": "docs: sync README/DESIGN with install script changes\n\n- README: uv→uvx, npx 标记为必需(列出 6 个依赖 MCP),新增 Mosquitto 可选说明\n- README.zh-CN: 同步中文版,Node.js 从\"可选\"改为\"必需\"\n- DESIGN.md: External Dependencies 表格更新,反映当前 install script 检测项\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T02:07:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7e06abb2630afbf2add94f646e469296a5a4f56c",
          "body": "install: 检测 uvx/npx 替代 uv/node,npx 升级为硬依赖,新增 Mosquitto 可选安装\n\n- Step 1: 检测入口从 uv 改为 uvx(uvx 随 uv 一起安装,逻辑不变)\n- Step 3: npx 从 optional 升级为 required,缺失时列出受影响的 MCP 服务器并 exit 1\n- 新增 [optional] Mosquitto 检测与交互式安装(winget/apt/brew/dnf/pacman)\n  管道执行时自动跳过,安装后不自动启动,仅打印启动命令\n- Pre-flight summary 同步更新\n\nCo-Authored-By: Claude <noreply@anthropic.com>\n@",
          "is_bot": false,
          "headline": "@",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T02:06:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a2011ac4e23a0f951be7e7d246ef08ca537b1782",
          "body": "ax-local-tools (npm) proved unreliable on Windows: npx EPERM cache\nissues, internal bug (class-vs-instance method calls), and Node.js\nv25 ESM compatibility problems.\n\niflow-mcp re-enabled for its file tools (read/write/edit/grep).\nComment notes that run_command may timeout on Windows —\nuse the built-in execute_shell for shell commands instead.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "mcp: remove ax-local-tools, re-enable iflow-mcp by default",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-27T01:44:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ae55e877b5cb1929017887d93e5f7026e556080c",
          "body": "npx cache cleanup on Windows hits EPERM when files are locked\n(Windows Defender / Search Indexer), causing the MCP server to\nfail at startup with \"closed connection\".\n\nSwitch to globally-installed bin command to bypass npx cache.\nPreinstall: npm install -g ax-local-operations-mcp --ignore-scripts\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "mcp: use global bin for ax-local-tools instead of npx",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T08:31:37Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "adc161dc28a24f9d8bcf7e6379e57433924b96f7",
          "body": "iflow-mcp (Python port) has a known issue on Windows:\nprocess.communicate() discards all partial stdout/stderr on timeout,\ncausing LLM to see \"timed out\" instead of actual error messages.\n\nax-local-tools (Node.js) uses event-driven child_process.spawn() with\nincremental stdout/stderr accumulation, preserving partial output\neven when killed on timeout. Uses pwsh instead of cmd.exe.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "mcp: disable iflow-mcp by default, add ax-local-tools as built-in",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T08:18:11Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "152bcf61efab14a9a7e6a6d64e208be5760cbe6c",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "静默 uv pip install 包列表输出,失败时显示最后20行日志",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T06:37:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1d465d3cd8bb1e49d9f25e79aabbdcecc3540c2e",
          "body": "- 磁盘空间检查移到下载之前,不够直接报错退出\n- uv pip install 输出实时显示,不再隐藏到日志文件\n- uv venv --seed 一步安装 pip,省去单独的 pip install 步骤\n- [1/6]~[6/6] 步骤计数器,用户知道当前进度\n- 安装前显示摘要(目录/Python/Node.js/空间需求)\n- 安装后验证 slife+credstore 包以及两个 CLI 入口点\n- install.sh: 移除 curl | sudo bash 模式,改用系统包管理器\n- install.sh: 修复升级时 dotfiles 丢失(.* glob + dotglob)\n- 错误信息添加 Help URL 链接\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "优化一键安装脚本: 磁盘检查前置、实时进度、--seed pip、步骤计数器、slife+credstore 双重验证",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T06:23:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "879d798fc506afdcd54cb7f3108ae66ba772c0df",
          "body": "Revert to e97ed60 stash/restore approach that has worked reliably:\nmove user data aside, wipe dir, create venv, restore user data.\n\nKeep only two safe improvements from the experiment:\n- GetFullPath for Python path (uv python find returns relative)\n- SilentlyContinue on Move-Item (locked files from crashes)\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "revert: restore proven stash/restore install logic",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T06:08:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d74c1fd46bc95de7f5ff3a514d3d8428cd74fa1e",
          "body": "UV_VENV_CLEAR=1 clears the entire install directory including\nslife.json5, slife.db, logs/.  Revert to targeted removal of only\nvenv artifacts.  If files are locked, fail with a clear message\ninstead of silently destroying user data.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: NEVER use UV_VENV_CLEAR — it wipes all user data",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T06:01:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ae47c9ea098dd6d4ff9005cf1032a47b31b15417",
          "body": "- Resolve-Path on all python paths (uv python find returns relative)\n- Remove fragile Remove-Item logic; UV_VENV_CLEAR handles all cases\n- Check uv venv exit code and report clear error on failure\n- Consolidate pipLog definition\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: resolve python path to absolute, add uv venv error checking",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T05:56:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c106a10161bb9ecc3c137051c8d5f0fd65a03250",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: use UV_VENV_CLEAR=1 for installs where old venv files are locked",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T05:51:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8157056c57856e59ba21581ba0d9b3f90c8b7030",
          "body": "…r data\n\nRemove the first-install vs upgrade distinction.  The script now\nalways cleans old venv artifacts (Scripts/Lib/Include/pyvenv.cfg)\nthen recreates the venv — works correctly regardless of state.\nslife.json5 and logs/ are handled by the app at runtime.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: always clean venv artifacts before install, never touch use…",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T05:49:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "aa6a550ddda22cca5fc645ff3c61141f6d2d110e",
          "body": "…ser data\n\nInstead of stash/restore, just remove the four venv artifacts (Scripts,\nLib, Include, pyvenv.cfg) and recreate.  User data (logs, slife.json5,\n*.db) stays in place — no locked-file issues, no stash dirs.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: simplify install upgrade — only replace venv, never touch u…",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T05:45:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "139e8f3261090c4186bd9b0d2972260547142363",
          "body": "Co-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: preserve logs across reinstalls — treat as user data",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T05:42:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4977602cf3d84381efda5d297739be706df62488",
          "body": "Logs are ephemeral and may be locked by a crashed session.  Skip them\nwhen stashing user data, and if the old dir still exists after removal\nattempt, use UV_VENV_CLEAR=1 so uv reuses it.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: skip logs dir during install upgrade, use UV_VENV_CLEAR as fallback",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T05:40:59Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f92387a0c229b37df41fcaae15a2d698e3838875",
          "body": "- Use UV_VENV_CLEAR=1 so venv creation works even when old dir\n  could not be fully removed (locked log files from crash)\n- Use Copy-Item instead of Move-Item for restoring user data so\n  directory merging works without collisions\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: handle locked files gracefully during install upgrade",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T05:39:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fabab8c6c9dc9c966e43ce8714a89c5ce64a49e9",
          "body": "When a previous slife session crashes, log files may still be held\nby lingering subprocess transports.  Move-Item now uses\n-ErrorAction SilentlyContinue so locked files are skipped rather\nthan aborting the upgrade.\n\nCo-Authored-By: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: skip locked files during install upgrade instead of failing",
          "author_name": "juzcn",
          "author_login": "juzcn",
          "committed_at": "2026-07-26T05:34:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        }
      ],
      "releases_count": 20,
      "commits_last_year": 348,
      "latest_release_at": "2026-07-29T02:37:57Z",
      "latest_release_tag": "v0.3.20",
      "releases_from_tags": true,
      "days_since_last_push": 0,
      "active_weeks_last_year": 3,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 0.3
    },
    "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": "slife",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "Development Status :: 3 - Alpha",
            "Environment :: Console",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: MIT License",
            "Operating System :: OS Independent",
            "Programming Language :: Python :: 3 :: Only",
            "Programming Language :: Python :: 3.13",
            "Topic :: Terminals"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/slife/",
          "is_deprecated": false,
          "latest_version": "0.3.20",
          "repository_url": "https://github.com/juzcn/slife",
          "versions_count": 26,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 2044,
          "first_published_at": "2026-07-10T11:58:06.716661Z",
          "latest_published_at": "2026-07-29T02:38:27.846615Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        },
        {
          "name": "credstore",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "Development Status :: 4 - Beta",
            "Environment :: Console",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: MIT License",
            "Operating System :: OS Independent",
            "Programming Language :: Python :: 3.10",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Programming Language :: Python :: 3.13",
            "Topic :: Security",
            "Topic :: System :: Systems Administration"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/credstore/",
          "is_deprecated": false,
          "latest_version": "0.3.20",
          "repository_url": "https://github.com/juzcn/slife",
          "versions_count": 6,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 277,
          "first_published_at": "2026-07-20T00:31:11.833347Z",
          "latest_published_at": "2026-07-29T02:38:31.602451Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 52062,
      "source_files_sampled": 144,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "credstore/pyproject.toml",
        "pyproject.toml"
      ],
      "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": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "keyring",
          "manifest": "credstore/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=25.0.0"
        },
        {
          "name": "keyrings-cryptfile",
          "manifest": "credstore/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.3.0"
        },
        {
          "name": "textual",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.0.0"
        },
        {
          "name": "openai",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.0.0"
        },
        {
          "name": "httpx",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.27.0"
        },
        {
          "name": "json5",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.15.0"
        },
        {
          "name": "jinja2",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=3.1.0"
        },
        {
          "name": "fastmcp",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.0.0"
        },
        {
          "name": "aiosqlite",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.22.1"
        },
        {
          "name": "sqlite-vec",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.1.9"
        },
        {
          "name": "aiohttp",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=3.14.1"
        },
        {
          "name": "qrcode",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=8.0"
        },
        {
          "name": "Pillow",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=11.0"
        },
        {
          "name": "keyring",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=25.0.0"
        },
        {
          "name": "keyrings-cryptfile",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.3.0"
        },
        {
          "name": "paho-mqtt",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.0.0"
        },
        {
          "name": "requests",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.31.0"
        },
        {
          "name": "credstore",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        }
      ],
      "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": 0,
        "merged_prs": 0,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "juzcn",
          "commits": 355,
          "avatar_url": "https://avatars.githubusercontent.com/u/11883152?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "publish.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "uv.lock"
      ],
      "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": null,
            "reason": "no pull request found",
            "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": 10,
            "reason": "no dangerous workflow patterns detected",
            "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": 10,
            "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": "no SAST tool detected",
            "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": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 9,
            "reason": "1 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "f9e15f0bb994e279cc1b662a31bc22eabb535205",
        "ran_at": "2026-07-29T02:40:38Z",
        "aggregate_score": 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-29T02:38:35Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": null,
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/juzcn/slife",
    "host": "github.com",
    "name": "slife",
    "owner": "juzcn"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 47,
      "inputs": {
        "security": 30,
        "vitality": 69,
        "community": 32,
        "governance": 32,
        "engineering": 66
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 69,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 56,
            "inputs": {
              "commits_last_year": 348,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 3
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "3/52 weeks with commits",
                "points": 2.1,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 3
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "348 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 348
                    }
                  }
                ],
                "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": 88,
            "inputs": {
              "releases_count": 20,
              "latest_release_tag": "v0.3.20",
              "releases_from_tags": true,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 0.3
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "20 version tags (no GitHub releases)",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "version_tags_no_releases",
                    "params": {
                      "count": 20
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.3 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.3
                    }
                  }
                ],
                "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": "at_risk",
        "name": "Community & Adoption",
        "value": 32,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "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": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "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": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "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
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 56,
            "inputs": {
              "packages": [
                "slife",
                "credstore"
              ],
              "dependents": null,
              "ecosystems": "pypi",
              "total_downloads": null,
              "monthly_downloads": 2321
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,321 downloads/month across pypi",
                "points": 44.9,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2321,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 32,
        "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": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution, PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution",
                    "pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "merged_prs": 0,
              "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": "no decided pull requests or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_decided_prs_or_data",
                    "params": {}
                  }
                ],
                "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": "at_risk",
            "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": 34,
            "inputs": {
              "followers": 0,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "juzcn",
              "public_repos": 4,
              "account_age_days": 4127
            },
            "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": "0 followers of juzcn",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "juzcn"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "4 public repos, account ~11 yr old",
                "points": 17.1,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 4
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 11
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "slife",
                "credstore"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "2 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 2,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "26 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 26
                    }
                  }
                ],
                "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": "moderate",
        "name": "Engineering Quality",
        "value": 66,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "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": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 30,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 30,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 15,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 3,
              "scorecard_aggregate": 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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "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 dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "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.5,
                "status": "met",
                "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": "no SAST tool detected",
                "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": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "1 existing vulnerabilities detected",
                "points": 6.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "at_risk",
        "name": "AI Readiness",
        "value": 40,
        "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.99,
              "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": "99 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 99,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 42,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "uv.lock"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.93,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "93 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 93,
                      "sampled": 100
                    }
                  }
                ],
                "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": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 52062,
              "source_files_sampled": 144,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/144 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 144,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "critical",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "example_dirs": [],
              "has_mcp_signal": true,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              }
            ]
          }
        ],
        "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": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index pypi:slife@0.3.20; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-29T02:40:42.682091Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/j/juzcn/slife.svg",
  "full_name": "juzcn/slife",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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 agregadasPyPI.