Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-24 03:02 UTC

gavraz / recon

tmux-native dashboard for managing Claude Code agents

Rust · ShellMIT★ 260 stars⑂ 35 forkssince Mar 2026View on GitHub ↗

gavraz/recon holds a health index of 52 out of 100, placing it in the Moderate band. It scores highest on Vitality (81/100) and lowest on Security (32/100). It was last updated 6 days ago. A single contributor accounts for most of its recent work.

52
overall / 100
Moderate

Software health index

Metrics are grouped into weighted categories on one standardized 1–100 scale. Overall starts as their weighted mean; when public evidence triggers the High-Risk Jurisdiction Policy, the rating is adjusted and receives an At risk ceiling of 49. AI Readiness sits outside the overall score.

52
Excellent85-100Exemplary; meets essentially all checked criteria
Good70-84Healthy; minor gaps
Moderate50-69Acceptable with notable gaps; review recommended
At risk30-49Significant weaknesses; adoption warrants caution
Critical1-29Severe problems (abandoned, single-maintainer, no hygiene)
VitalityCommunity &AdoptionSustainability &GovernanceEngineeringQualitySecurityAI Readiness

Score profile

Each axis is a category. The shape matters more than the average — a healthy subject fills the whole shape, while a spike-and-crater profile means strength in one dimension is masking risk in another.

Ownership

gavrazPersonal account
9 followers10 public repossince Aug 2014

This repository is owned by a personal account. A single-owner project carries more continuity risk than an organization-backed one.

Package ecosystems

RegistryPackageVersionDownloads / moVersionsLast publish
crates.ioreconpoints to another repo — not scored0.0.110127 days ago

Metrics by category

Vitality

Is the project alive — is code being written and are releases shipping?

81Good · 22% of overall
How it's scored
36/36Push recency — last push 6 days ago
4.2/36Commit cadence — 6/52 weeks with commits
18/18Commit volume — 119 commits in the last year
10/10OpenSSF Scorecard: Maintained — 8 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year119
human_commit_share1
days_since_last_push6
active_weeks_last_year6

Release discipline

100Excellent
How it's scored
27/27Ships releases — 16 releases published
36/36Release recency — latest release 6 days ago
27/27Release cadence — a release every ~13.4 days
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count16
latest_release_tagv0.7.0
releases_from_tagsno
days_since_latest_release6
mean_days_between_releases13.4
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.

Community & Adoption

Does the project have users, downloads, attention, and a welcoming setup for contributors?

60Moderate · 18% of overall
How it's scored
39.1/60Stars — 260 stars
12.8/25Forks — 35 forks
0/15Watchers — 0 watchers
Inputs used
forks35
stars260
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
How it's scored
22.5/22.5README
22.5/22.5License — recognized license (MIT)
18/18CONTRIBUTING guide
0/13.5Code of conduct
0/7.2Issue template
0/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingyes
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno

Sustainability & Governance

Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?

38At risk · 24% of overall
How it's scored
9/54Bus factor — 1 contributor(s) cover half of all commits
0/22.5Commit distribution — top contributor authored 100% of commits
1.4/13.5Contributor breadth — 1 contributors
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Inputs used
bus_factor1
contributors_sampled1
top_contributor_share1
How it's scored
46.8/46.8Issue resolution — 100% of issues closed
17.9/38.3PR acceptance — 7/15 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 1/30 approved changesets -- score normalized to 0
Inputs used
merged_prs7
open_issues0
closed_issues12
issue_closed_ratio1
closed_unmerged_prs8
How it's scored
10/30Ownership backing — personal (user) account
0/20Verified domain — not applicable to user accounts
7.2/25Owner reach — 9 followers of gavraz
19.6/25Track record — 10 public repos, account ~11 yr old
Inputs used
followers9
owner_typeUser
is_verified
owner_logingavraz
public_repos10
account_age_days4,374
Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.

Engineering Quality

Are baseline engineering and documentation practices in place?

46At risk · 20% of overall
How it's scored
0/24CI workflows
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
0/6.4.editorconfig
2/20OpenSSF Scorecard: CI-Tests — 1 out of 7 merged PRs checked by a CI test -- score normalized to 1
Inputs used
has_cino
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno
How it's scored
30/30README
25/25Documentation directory
0/15Documentation / homepage site
10/10Repository description
0/10Topics
10/10Wiki
Inputs used
topics
has_wikiyes
homepage
has_readmeyes
has_docs_diryes
has_descriptionyes

Security

Are visible security and supply-chain practices strong, without unresolved high-risk jurisdiction exposure?

32At risk · 16% of overall
How it's scored
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/2.5CI-Tests — 1 out of 7 merged PRs checked by a CI test -- score normalized to 1
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 1/30 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
0/10Dangerous-Workflow — no data
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
7.5/7.5Maintained — 8 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — no data
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — no data
0/7.5Token-Permissions — no data
6/7.5Vulnerabilities — 2 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated14
scorecard_versionv5.5.0
checks_inconclusive4
scorecard_aggregate3.2
Excluded from scoring (no data or not applicable): dangerous_workflow, packaging, signed_releases, token_permissions. Remaining weights renormalized.

AI Readiness

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.

74Good · 0% of overall
How it's scored
45/45Agent instructions — CLAUDE.md
0/15Machine-readable docs (llms.txt)
27.2/40Legible commit history — 51 of 100 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.51
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes3,167
How it's scored
12.6/18One-command bootstrap — Cargo.toml (toolchain convention, no task runner)
22/22Automated tests
0/11Lint / format config
11/11Static type checking — Rust (statically typed)
10/10Reproducible environment — Dockerfile, lockfile
10/10Demonstrated agent practice — 5 of the last 100 commits agent-authored or agent-credited
0/8Automated maintenance — no automated dependency updates observed
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Inputs used
has_nixno
has_testsyes
lockfilesCargo.lock
has_dockerfileyes
typed_languageyes
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0.05
toolchain_manifestsCargo.toml
dependency_bot_commit_share0
How it's scored
45/45Type-checkable code — Rust (statically typed)
55/55Manageable file sizes — 0/13 source files over 60KB
Inputs used
primary_languageRust
largest_source_bytes50,022
source_files_sampled13
oversized_source_files0

Key facts

260GitHub stars
1contributors
119commits, last 12 months
6days since last push
16releases
1bus factor
0open issues
crates.iopackage ecosystems

Data collection warnings

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • crates package 'recon' points at a different repository (https://codeberg.org/sumitpsm/recon); excluded from ecosystem scoring
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

More detail

Star and fork history 0 ★ / 35 ⇿
0Stars
35Forks
15Releases

When each star and fork was added, collected from GitHub and bucketed by day. Cumulative growth sits directly above the daily additions it is made of, so the two read against each other: steady organic accretion looks nothing like an abrupt, short-lived burst. Where that difference is measurable, it is reported as growth authenticity.

01325383342026-032026-052026-06
Major 0Minor 6Patch 9
OpenSSF Scorecard 3.2 / 10
3.2aggregate

Independent, tool-agnostic security assessment from the open-source OpenSSF Scorecard. Each check rewards a security practice, not a specific vendor's tool. Checks Scorecard could not determine are marked n/a and excluded from the security score (never counted as zero).Scorecard v5.5.0 · 2026-07-24 03:02 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
1CI-Tests1 out of 7 merged PRs checked by a CI test -- score normalized to 1
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 1/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
n/aDangerous-Workflowno workflows found
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained8 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10
n/aPackagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
n/aSigned-Releasesno releases found
n/aToken-PermissionsNo tokens found
8Vulnerabilities2 existing vulnerabilities detected
Direct dependencies 9
RegistryPackageVersion constraintManifest
crates.ioratatui0.29Cargo.toml
crates.iocrossterm0.28Cargo.toml
crates.iotokio1Cargo.toml
crates.ioserde1Cargo.toml
crates.ioserde_json1Cargo.toml
crates.iotoml0.8Cargo.toml
crates.iodirs6Cargo.toml
crates.ioclap4Cargo.toml
crates.iochrono0.4Cargo.toml
All dependencies not collected

The resolved dependency set could not be collected for this report: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 1994,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Rust": 163149,
        "Shell": 29799,
        "Python": 6886
      },
      "pushed_at": "2026-07-17T19:10:27Z",
      "created_at": "2026-03-14T12:39:15Z",
      "owner_type": "User",
      "updated_at": "2026-07-22T04:40:30Z",
      "description": "tmux-native dashboard for managing Claude Code agents",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Rust",
      "significant_languages": [
        "Rust",
        "Shell"
      ]
    },
    "owner": {
      "blog": null,
      "name": "gavraz",
      "type": "User",
      "login": "gavraz",
      "company": null,
      "location": null,
      "followers": 9,
      "avatar_url": "https://avatars.githubusercontent.com/u/8331212?v=4",
      "created_at": "2014-08-01T15:13:35Z",
      "is_verified": null,
      "public_repos": 10,
      "account_age_days": 4374
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-07-17T19:10:34Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2026-04-29T19:08:02Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-04-04T08:32:17Z"
        },
        {
          "tag": "v0.5.1",
          "kind": "patch",
          "published_at": "2026-04-01T10:09:57Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-03-31T12:19:12Z"
        },
        {
          "tag": "v0.4.3",
          "kind": "patch",
          "published_at": "2026-03-25T08:13:32Z"
        },
        {
          "tag": "v0.4.2",
          "kind": "patch",
          "published_at": "2026-03-22T10:32:01Z"
        },
        {
          "tag": "v0.4.1",
          "kind": "patch",
          "published_at": "2026-03-20T12:35:34Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-03-19T21:43:31Z"
        },
        {
          "tag": "v0.3.3",
          "kind": "patch",
          "published_at": "2026-03-19T14:18:01Z"
        },
        {
          "tag": "v0.3.2",
          "kind": "patch",
          "published_at": "2026-03-19T13:08:30Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2026-03-19T08:42:21Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-03-17T23:29:45Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-03-16T23:00:58Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-03-16T17:45:27Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-03-16T15:47:58Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "707418b642bc62491c16e10930c666a8b1921b06",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.7.0",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-07-17T19:10:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d953e8af674e8a788532ae2bdd2e24b6df402b8a",
          "body": "* Submit e2e prompts in two steps (text, then Enter) so newer Claude TUIs do not swallow the Enter as part of a bracketed paste\n* Give working_state a deterministic sleep-based Working window, pre-authorizing only sleep via --allowedTools so other permission prompts are unchanged\n* Reformat codebase with cargo fmt (no behavioral change)",
          "is_bot": false,
          "headline": "Reformat codebase and stabilize e2e tests (#27)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-07-17T19:06:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d1b8740ad894643c4a6226db7506f814874a094",
          "body": "* Add find_jsonl_by_open_fd() lsof fallback to relink resumed sessions to their JSONL, fixing `new` status misattribution and flicker (#22)\n* Add tests/e2e_discovery.sh — deterministic, claude-free discovery tests using a node-backed stub pane and scratch $HOME",
          "is_bot": false,
          "headline": "Fix `new` status misattribution for resumed sessions (#22) (#26)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-07-17T18:33:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "65245ea0be1a4a681eb8977a6b0c6af081b03b3c",
          "body": "* Add optional config.toml (XDG config dir) to select and order the session table columns\n* Add per-column width overrides via [table.widths]\n* Fail fast on launch for malformed configs or unknown column names; missing file uses defaults\n* Add `recon config --available-columns` to list columns and print an example stanza\n* Drive table rendering from the configured column list instead of a hardcoded set\n* Fix invisible Directory text and Project separators on the selected row (contrast)",
          "is_bot": false,
          "headline": "Add configurable table columns via config.toml (#25)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-07-17T13:55:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3f22a3ac44a35d6600ea8d8681546936fd03c252",
          "body": "* Correct claude-sonnet-4-6 context window to 1M and add missing current models (Fable 5, Sonnet 5, Opus 4.8, Opus 4.5)\n* Keep prefix fallback so future dated Opus 4.6+ variants default to 1M\n* Document Anthropic models-overview source in model.rs and CLAUDE.md for mechanical refresh",
          "is_bot": false,
          "headline": "Fix context-window sizes for 1M-context models (#21) (#24)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-07-17T11:25:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "34e4349d7a5f80ac32a25689ae6019af171dfbdc",
          "body": "* Capture #{window_name} from tmux list-panes and surface it as a new Window column\n* Thread tmux_window through LiveSessionInfo and all session-construction paths\n* Include window name in JSON output and the `/` search filter",
          "is_bot": false,
          "headline": "Add tmux window name column to session table (#23)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-07-17T11:18:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca5a0e789ab841d3d192e1ef45cd94a997ebee86",
          "body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: bump version to 0.6.1",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-04-29T19:06:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b3ca16b6824a798601724e5aecbfea2b7e7ebaf7",
          "body": "The npm-distributed Claude CLI on macOS reports \"claude.exe\" as its\nprocess name, causing discover_claude_tmux_panes() to filter out all\nClaude panes and show an empty session table.\n\nFixes #16\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: detect claude.exe pane command on macOS",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-04-29T18:57:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "823e79d85f4612f10f7120c7de21766f94856f02",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.6.0",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-04-04T08:31:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0ebe8e332c762ebbc0843273542a7781ed5e8856",
          "body": "* --tag key:value on recon launch stores tags in tmux session environment\n* --tag key:value on recon json filters sessions (AND logic, must match all)\n* Tags included in JSON output as a key-value object\n* Add 3 e2e tests for tag launch, filter, and multi-filter",
          "is_bot": false,
          "headline": "Add session tagging for programmatic use",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-04-04T08:24:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "acc9cf62bc10405c112dd35032601daa74020533",
          "body": null,
          "is_bot": false,
          "headline": "Add search keybinding to README, fix stale footer hint",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-04-03T20:33:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fecbf85ad965eaac609205d73ca0613b6eb37d72",
          "body": "* Add --name and --cwd flags to launch (previously used current dir only)\n* Add --command flag to run custom commands instead of claude\n* Replace --name-only with --attach (background by default)",
          "is_bot": false,
          "headline": "Improve recon launch with --name, --cwd, --command, --attach",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-04-03T20:26:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "32a6cf08660d6c1dbb74c2a279846056d125ad30",
          "body": "* Add bounded JSONL line reader using fill_buf/consume to prevent OOM from crafted files\n* Validate CWD before passing to git and tmux commands\n* Replace tmux session name denylist sanitizer with alphanumeric allowlist\n* Seek to file tail in read_jsonl_summary instead of reading entire file into memory\n* Add 15 unit tests for read_line_capped, validate_cwd, and sanitize_session_name",
          "is_bot": false,
          "headline": "Harden against malicious JSONL injection (#13)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-04-03T19:55:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bed932a19d1dcdd6674eb00a3512d0929a20fdad",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.5.1",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-04-01T10:09:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b3147fd7c1109eb98b0dc2a705a9dcb64493ab96",
          "body": "* Drop find_clear_successor, is_clear_born, encode_project_path, and post-scan fixup loop (~100 lines)\n* Document /clear as a known limitation in README\n* Simplify e2e reset test to verify session survives rather than tracking stale data",
          "is_bot": false,
          "headline": "Remove /clear successor detection (#14)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-04-01T09:55:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c701b608c8ba77e881243652121df509a4b5d9fa",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.5.0",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-31T12:18:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "615137cfb7d4728ee57d93c0dd7d5ca5fcdae222",
          "body": "* Press / to enter search mode, filters sessions in real-time by project or session name\n* Single match + Enter switches directly to that session\n* Works in both Table and View modes, filter persists across mode switches",
          "is_bot": false,
          "headline": "Add session search/filter to TUI (#15)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-31T12:03:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d676fd8b50b87456ddd1b1dbeaed309d3fe670a0",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.4.3",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-25T08:12:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c88fae64a3b6d9eb0338379109169e4494cdd2f3",
          "body": "* Store full pane target (session:window.pane) and use it for capture-pane and switch-client instead of bare session name\n* Dedup unmatched live sessions by PID instead of tmux session name to support multiple Claude panes in the same session\n* Use pane_target for placeholder keys in build_live_sess\n[…]\ntection, pane_target format, and dual-pane discovery\n\nReported-by: rickythefox <1675955+rickythefox@users.noreply.github.com>\nCo-Authored-By: rickythefox <1675955+rickythefox@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Fix status detection reading wrong pane in multi-pane sessions (#10)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-24T08:44:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d5074a57000c51ec3ee0f21d21ab1480054772f9",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.4.2",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-22T10:31:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c1aa31138a05ae1a1c03c2467c0f997aa7fdd213",
          "body": "* Sort by last_activity truncated to the minute to prevent table reordering on every poll\n* Display \"< 1m\" instead of exact seconds for recent activity",
          "is_bot": false,
          "headline": "Stabilize session ordering with minute-resolution sort",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-22T10:08:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68eb3f63234827890b0125e283e5a28b9b714cca",
          "body": "* Carry forward CWD from prev_sessions when incremental parse yields no new lines, avoiding lossy decode_project_path fallback that mangled hyphenated names (api-server → api/server)\n* Canonicalize paths in fetch_relative_dir for macOS /tmp symlink resolution\n* Restructure demo: monorepo subdirectory room (api-server › services/auth) showcasing relative_dir grouping\n* Update record.sh to produce readme.tape → assets/demo.gif",
          "is_bot": false,
          "headline": "Fix CWD corruption on incremental JSONL parse, update demo",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-22T07:59:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "168b9ca955def2ba7d9711c0a40505e7f7f0dff8",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.4.1",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-20T12:35:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "253149bbb63e084e27a8af0c2fc6049974c48c99",
          "body": "* Replace stored room_id with derived room_id() method on Session\n* Store relative_dir as raw data, compute display strings at point of use\n* Table view now shows project::relative_dir::branch (e.g. line5::tools/solo::main)",
          "is_bot": false,
          "headline": "Refactor: derive room_id from raw fields, show relative dir in table",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-20T12:32:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2d8a371314223573885bb31d0a33bcc7a5e0d938",
          "body": null,
          "is_bot": false,
          "headline": "Update README: rooms group by git repo, not working directory",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T21:52:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e72c27226a4eed30fee659855f80d53512518530",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.4.0",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T21:43:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "921bcd24d9316644652d59318b6f3a5d9a4bab48",
          "body": "* Add room_id field to Session using git rev-parse --git-common-dir for worktree-stable repo identity\n* Rooms now group by repo name + relative path (e.g. \"line5\" or \"line5 › tools/solo\")\n* Fix project_name to also use canonical repo name instead of worktree directory name",
          "is_bot": false,
          "headline": "Use git-common-dir for stable room identity across worktrees",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T21:36:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0bc8b255171530740fcba61397de496df8146fb",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.3.3",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T14:17:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a8ee23a636bc784cae1db0db2a5c123f6f162f14",
          "body": "* Scan 10 lines instead of 5 — Claude Code UI chrome (separators, prompt,\n  status bar, tips) pushes the spinner line beyond 5\n* Use Dingbats range U+2720-2767 instead of individual chars\n* Add middle dot (U+00B7) used by Claude Code for progress lines",
          "is_bot": false,
          "headline": "Fix Working detection: increase scan depth and widen spinner range",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T14:14:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4701ed46e5f3e0c2121cfa3c6a9021623d896784",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.3.2",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T13:08:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1c329c1fe9ff915e29e5288b99d3b9f8817a94d7",
          "body": "* Add started_at as tiebreaker when sessions have identical last_activity\n* Fix test to explicitly set most-recent activity instead of relying on\n  creation order, which was a race with the working_state prompt",
          "is_bot": false,
          "headline": "Fix flaky sort_order test",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T13:01:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9dc6bf1c9a0fdc30f70d35677e62b3ad5cfb9efa",
          "body": "* Detect Working by scanning last 5 lines for Unicode spinner (✽✢✳✶⏺)\n  followed by \"…\" — covers thinking, tool execution, and streaming\n* Replace fragile text-matching (\"esc to interrupt\", \"to run in background\",\n  \"thinking with\") with a single visual pattern\n* Add working_sonnet e2e test: Sonnet reads large fixture files, asserts Working\n* Add test fixture files for reliable long-running prompts",
          "is_bot": false,
          "headline": "Rewrite Working detection using spinner+ellipsis pattern",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T10:01:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "066c070736aeda1562377cd3876b1c2d8b96f844",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.3.1",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T08:41:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da0e2c38eb6740cf03d61fd249ea1db5ed0b6356",
          "body": null,
          "is_bot": false,
          "headline": "Remove manual refresh keybinding (auto-refresh every 2s)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T08:30:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25be2d5736b0744696f2087889686686adf7b5dd",
          "body": "* Skip <synthetic> model entries in JSONL parser — they have 0 tokens and\n  were overwriting real model/token data, causing sessions to show as New\n* Remove 24h JSONL mtime cutoff — redundant since live_map already filters\n  dead sessions, and the stat() call was slower than just checking the map\n* \n[…]\ncessors before unrelated sessions can steal them\n* Prefer largest JSONL when same session_id exists in multiple project dirs\n* Use /clear successor directly in resume path instead of filtering to None",
          "is_bot": false,
          "headline": "Fix session discovery: skip synthetic entries, remove stale heuristics",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T06:48:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "13ce2f3165e56fbf6e8ca53d56b6bab28c2d7421",
          "body": "* Detect tool execution as Working via \"to run in background\" pane text\n* Check pane before token count so first-prompt Working isn't masked as New\n* Deduplicate when same session_id has JONLs in multiple project dirs\n* Use \"wait 10 seconds and then run ls\" prompt in e2e to reliably catch Working",
          "is_bot": false,
          "headline": "Fix Working state detection and duplicate session from multi-dir JSONL",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-19T06:16:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "84ff4e4584fc5da85226070c1e943a425379357c",
          "body": null,
          "is_bot": false,
          "headline": "Add contribution policy",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-18T00:01:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4606f50fe11b97a7fa0d9e8f112780dccd99842",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.3.0",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-17T23:29:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "437047827240b2d9838afb1eb48ec6a027cd559b",
          "body": null,
          "is_bot": false,
          "headline": "Replace 30s mtime heuristic with /clear marker check in resume filter",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-17T23:26:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0f67704037eae37b36c9bcde9a1770e5ffb887b7",
          "body": "* Replace mtime + 10s-active heuristic with /clear marker detection\n* New JONLs created by /clear always have <command-name>/clear</command-name>\n  in their first few lines — check this instead of guessing from timestamps\n* Eliminates false positives from dead sessions' stale JONLs",
          "is_bot": false,
          "headline": "Use /clear command marker for deterministic post-clear JSONL detection",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-17T23:13:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a33c02c8ebceaa238a47cc8cd31a03cb6a7acf65",
          "body": "* Parse \"Set model to <name> with <effort> effort\" from JSONL local-command-stdout\n  entries to get per-session model ID and effort level immediately on /model change\n* Add reverse lookup from display name to model ID (model.rs)\n* Remove global effort_level from App (was read from settings.json, wrong for\n  per-session overrides)\n* Strip ANSI escape codes (both raw \\x1b and JSON-encoded \\\\u001b) from parsed output\n* Filter out tool result entries to avoid false matches on source code in JSONL",
          "is_bot": false,
          "headline": "Extract per-session model and effort from /model command output",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-17T20:49:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "44b1fed271898da694716b64ed56212c116abc73",
          "body": "* Handle /clear creating a new JSONL without updating {PID}.json: post-scan\n  fixup switches to a newer actively-written JSONL in the same project dir\n* Handle resumed sessions where --resume ps args become stale after /clear:\n  filter stale resume paths, fall back to CWD-based JSONL lookup\n* Fix en\n[…]\node),\n  fixing discovery for sessions in .claude/worktrees/ paths\n* Refactor e2e tests to support running individual tests by name\n* Add reset_activity e2e test verifying activity updates after /clear",
          "is_bot": false,
          "headline": "Fix stale JSONL after /clear and broken worktree path encoding",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-17T18:37:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "879bc0f6d48e96b64be1077c17fbe05382aa82e9",
          "body": "pane_status() only checked the last non-empty line for \"Esc to cancel\",\nmissing fetch/MCP permission prompts that use a numbered selection menu\ninstead. Now scans the last 5 lines for the \"❯ N.\" pattern (arrow +\ndigit) which is unique to the selection UI.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Detect selection-menu permission prompts as Input status",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-17T17:47:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a058ad7e9b8a5f06ea8dc2eef1c96bbdcb3c6a2e",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.2.1",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T23:00:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e8f45d9b5f8a6db4a8457b2c4d8b79ca253a7f8a",
          "body": null,
          "is_bot": false,
          "headline": "Remove redundant Features section from README",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T22:58:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b23fa78ba212ffd199d574e550ebbebb5bdf3558",
          "body": "* `recon park` serializes live sessions to ~/.local/state/recon/parked.json\n* `recon unpark` restores them via claude --resume with original tmux names\n* Park uses JSONL filename as session ID to correctly handle resumed sessions\n* Resume is idempotent — skips sessions already running in tmux\n* E2e test for resume idempotency",
          "is_bot": false,
          "headline": "Add park/unpark commands for saving and restoring sessions",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T22:55:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d9e857122f29ff577aabe4d2ff6d3df4469fee0a",
          "body": "* Replace --json with json subcommand\n* Default test model from sonnet to haiku",
          "is_bot": false,
          "headline": "Fix e2e test for clap migration and default to haiku model",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T19:54:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6e27a964b110f5c2c5b38d728b5c18b74ff8d51e",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.2.0",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T17:45:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "226390822fc05798087a0f8e8e9a119a61b88a4a",
          "body": null,
          "is_bot": false,
          "headline": "Remove static screenshot from README in favor of demo GIF",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T17:44:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "90b8c65f8ea9fcfb826417cdd16b94298e63ea7a",
          "body": "* Hero GIF showing table view, visual view, and room zoom\n* VHS tape for reproducible recording via Docker",
          "is_bot": false,
          "headline": "Add animated demo GIF to README",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T17:31:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61cee6637778d959c014edb080e75a355263a774",
          "body": null,
          "is_bot": false,
          "headline": "Remove mouse setting from tmux.conf to avoid overriding user config",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T17:23:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "94926bbf059766995148ca540d48f3cd5eecef60",
          "body": "…cores",
          "is_bot": false,
          "headline": "Fix tmux pane parsing on tmux 3.5+ which converts tab chars to unders…",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T17:23:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a980d6b14b5910bd9ce94bfbcfa2285d25d8b185",
          "body": "* Dockerfile with multi-stage build (rust + VHS + tmux + node)\n* demo.sh creates 7 fake agents across 4 rooms with all states\n* record.sh builds and records GIF inside isolated container\n* VHS tapes for table view, view mode, zoom, and full tour",
          "is_bot": false,
          "headline": "Add Docker-based demo recording infrastructure",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T17:21:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8d0937004d08e51d4fdff8fd41591b4cd36389db",
          "body": "* Table view: sort by last activity instead of creation time\n* View mode: secondary room sort by last activity instead of alphabetical\n* Rooms use max activity across all sessions; eggs (no activity) sort last",
          "is_bot": false,
          "headline": "Sort sessions and rooms by last activity",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T16:52:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "885ca083a6d4fbeaac21b5f480401a54283cdb98",
          "body": "* Fix Usage section to reflect subcommand syntax (recon json, recon resume --id)\n* Add i/Tab keybinding to Table View section\n* Add Claude Code skill to Features list",
          "is_bot": false,
          "headline": "Update README to match clap CLI and document missing features",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T16:40:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "65fa7f71469de64bfd74fdc01de43980b10ac60c",
          "body": null,
          "is_bot": false,
          "headline": "Update tmux session diagram in README.md",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T16:32:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15a6e8b5d1a7b341d991c0e38b7f9688d80e46a3",
          "body": "* When pane_current_command shows claude's version but pane_pid is the shell, fall back to child PID lookup via pgrep",
          "is_bot": false,
          "headline": "Fix PID detection when claude is launched manually in a tmux shell",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T15:46:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9ca40571afa38fbbffb9d951de4d438796039890",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Align box-drawing characters in README diagram",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T13:34:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ce114b79b7e9e605cbbe4be8b11d8504a862c1fc",
          "body": "* Replace manual arg parsing with clap — auto-generates --help from doc comments\n* Unify `resume` and `--resume <id>` into a single subcommand with optional --id flag\n* Add .claude/skills/recon/SKILL.md for Claude to discover recon capabilities\n* Add /demo to .gitignore",
          "is_bot": false,
          "headline": "Migrate to clap and add recon Claude skill",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-16T08:57:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2898a527c3fefd7a02f7efece34867c0de18fba0",
          "body": "* `recon next` headless command switches directly to the first Input session\n* `i` and `Tab` in-app shortcuts trigger the same jump\n* `prefix + i` tmux binding runs `recon next` without opening the TUI\n* Remap tmux bindings: g → dashboard, r → resume (was R)",
          "is_bot": false,
          "headline": "Add 'recon next' command and i/Tab shortcut to jump to input agent",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-15T10:58:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b0e60c580e0b06c3aa677ac8038bc54062bc2279",
          "body": null,
          "is_bot": false,
          "headline": "Rewrite README intro to highlight tmux-native workflow",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T20:38:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ae1f9317d3914a7da94369b3ace8fe24fd0890b3",
          "body": null,
          "is_bot": false,
          "headline": "Update README keybindings for view mode agent selection",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T20:32:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "64a40b4564da3cb3aed5a2d9d6bc365df335511a",
          "body": "* h/l to select agents within a zoomed room, Enter to switch, x to kill, n to create\n* Selection highlight with background color and bold cyan name\n* Swap page nav to j/k, agent nav to h/l for spatial consistency\n* Update Phase 3 design doc to reflect TUI implementation",
          "is_bot": false,
          "headline": "Add agent selection and interaction in zoomed view mode",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T20:29:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0d0e9135c58bbd390bb183050980144488c031a4",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Update view screenshot with multi-agent rooms and all states",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T20:08:21Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "64b8e23bb359c754ca30fed905176f0797701aab",
          "body": null,
          "is_bot": false,
          "headline": "Show full path with ~ as room name in view mode",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T19:46:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0ad7001d0baa703576a6d97f0f0a03deb0a7766d",
          "body": null,
          "is_bot": false,
          "headline": "Update view screenshot",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T19:33:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5d8e3c90c61d007da21d9dd5409302e028aa30f4",
          "body": "* Replace text mock with actual screenshot showing colored pixel sprites\n* Remove broken half-block character mock that misaligned on GitHub",
          "is_bot": false,
          "headline": "Add Tamagotchi view screenshot to README",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T19:28:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7ecee79e514d45cad3da5ac12931bb3a4d71412c",
          "body": "* Add MIT LICENSE file\n* Add Tamagotchi view mock and docs as primary view in README\n* Document keybindings for both table and view modes",
          "is_bot": false,
          "headline": "Add MIT license and update README with Tamagotchi view docs",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T19:22:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7bb213143469b5d34bb6c4eb147ddcefed841bec",
          "body": "* Render creatures using ▀▄ half-block characters with fg+bg RGB colors for true pixel art\n* 10x10 pixel grids per state: cream egg, green happy blob, blue-grey sleeper, orange angry face\n* Each state has its own color palette (3-8 colors per creature)\n* Add sprite_preview.py script for designing and previewing sprites in terminal",
          "is_bot": false,
          "headline": "Replace ASCII art with half-block pixel sprites",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T19:17:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f4ad7488046d8f5306b0739f115974969cc9107a",
          "body": "* Tick-based animation for Working (3 frames) and Input (3 frames); Idle and New stay static\n* Fixed 2x2 room grid with pagination (h/l) and zoom into room (1-4, Esc to back out)\n* Context usage bar per agent with three-tier coloring (green/yellow/red)\n* Pulsing yellow/white border and character col\n[…]\nd agents\n* Fatigue overlay (sweat drops) when context usage exceeds 75%\n* Per-session phase offset so characters don't animate in lockstep\n* Fix Unicode truncation panic on multi-byte block characters",
          "is_bot": false,
          "headline": "Add animations, 2x2 grid layout, and context bars to view mode",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T19:02:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "56510f0152cf069297de906cc44258411523aaa5",
          "body": "* New `recon view` subcommand and `v` key toggle between table/view modes\n* Sessions grouped into rooms by working directory basename\n* ASCII art creatures reflect agent status: egg (new), happy (working), sleeping (idle), crying (input)\n* Rooms with input-needed agents highlighted with yellow borders\n* Vertically centered grid layout that reflows with terminal width",
          "is_bot": false,
          "headline": "Add Tamagotchi-style view mode with ASCII art agent creatures",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T18:25:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9e91e2b44258d7a309c236a2cf1e015315ad496f",
          "body": "* Add --no-attach flag to recon --resume to skip tmux attach/switch\n* Use --no-attach in e2e test so it doesn't block",
          "is_bot": false,
          "headline": "Fix e2e test hanging on resume by adding --no-attach flag",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T18:11:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9bdbd855bedaa27dbb9ff5867b9c41ec873ad557",
          "body": null,
          "is_bot": false,
          "headline": "Add 'x' shortcut to kill selected tmux session",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T18:05:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8d2b37af7fd2cb836d959b930d051d1303374832",
          "body": "* Pass --model and --effort flags to all claude invocations (configurable via CLAUDE_MODEL/CLAUDE_EFFORT env vars)\n* Increase essay prompt to 500 words and idle timeout to 60s for slower model+effort combos\n* Use 'exit' command instead of Ctrl+C to reliably quit claude sessions\n* Fix pipefail crash when resume session ID grep finds no match",
          "is_bot": false,
          "headline": "Run e2e tests with Sonnet low effort by default",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T17:53:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "afc60c76cc627b8e4a9aa52138b4d5f27f3c15df",
          "body": "…hboard mock",
          "is_bot": false,
          "headline": "Update README with resume picker, Context column rename, and full das…",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T17:38:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6abcb185399b38f99109fcafd270acf5af7baa0d",
          "body": "* Remove y/resume popup from main TUI (replaced by prefix+R picker)\n* Remove clipboard helper and resume_popup state\n* Fix unused import warnings (Modifier, Read)\n* Remove unused fields from ParsedInfo and JsonlEntry structs",
          "is_bot": false,
          "headline": "Remove y keybinding and resume popup, fix all warnings",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T17:27:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "16aa2bdd1f6d2f4d5bb0ec9bbd483e789c9180c9",
          "body": null,
          "is_bot": false,
          "headline": "Rename Tokens to Context throughout UI and JSON output",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T17:18:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "75e0e284a1e2153162b25d07bfbff86293656e5a",
          "body": null,
          "is_bot": false,
          "headline": "Auto-size git column width in resume picker based on content",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T17:16:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "30bbb56c0e8c15672b9149c2f1eeaedc8cd497b2",
          "body": null,
          "is_bot": false,
          "headline": "Fix column widths in resume picker",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T17:14:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "539a9a2854d2378f0042e4453055f21bc94a2033",
          "body": null,
          "is_bot": false,
          "headline": "Display 1M instead of 1000k for context window",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T17:12:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61805599481672ca6ff6bb4f1bc7b3e7b3adc527",
          "body": null,
          "is_bot": false,
          "headline": "Show tokens as used/available in resume picker (e.g. 10k/200k)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T17:02:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cdf5c2a690f6593e7898ededd5977d073241f5ec",
          "body": null,
          "is_bot": false,
          "headline": "Fix context window: Opus 4.6 is 1M, not 200k",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T16:59:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a33dae010b2b0160080ac4fed7d348f8a2009db9",
          "body": "* Drop history file — JSONL files persist after exit, no second source needed\n* Show first 8 chars of session ID in Session ID column\n* Show Git(Project::Branch) with green branch name (same style as main TUI)\n* Read gitBranch from JSONL entries",
          "is_bot": false,
          "headline": "Simplify resume picker to JSONL-only, add session ID and git branch",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T16:55:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2ca69e4b45ae72c9996423379b843f9d698467a7",
          "body": null,
          "is_bot": false,
          "headline": "Add prefix+R keybinding for resume session picker",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T15:26:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a43273b9fe788a52fda198f4fb939a8e90754017",
          "body": null,
          "is_bot": false,
          "headline": "Show full session ID for JSONL-scanned sessions",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T15:25:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e668580f2ed537b9b968ca96e291cc7386bdeb56",
          "body": "… sessions",
          "is_bot": false,
          "headline": "Show short session ID instead of duplicate dir name for JSONL-scanned…",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T15:25:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d95b9f72bd93efe317c30e6c0150e948015f5297",
          "body": null,
          "is_bot": false,
          "headline": "Scan JSONL files for resumable sessions (they persist after exit)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T15:21:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ea1bb9654730d7bf44963883d5beee5a43b88790",
          "body": "Claude cleans up session files when processes die, so we can't scan them\nlater. Instead, recon detects disappeared sessions during its refresh\ncycle and writes them to ~/.recon/history.json. The resume picker reads\nthis file, filtering out any that are currently live again.",
          "is_bot": false,
          "headline": "Save exited sessions to history file during recon refresh",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T15:19:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb47205563826327e07b97b0d7bf462e5b46fbe5",
          "body": null,
          "is_bot": false,
          "headline": "Sort resume picker by last active (most recently closed first)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T15:11:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "37e889f12a9924da41ec23c35c3a82cd64f99cff",
          "body": "…eded\n\n* Scans ~/.claude/sessions/*.json for dead sessions, reads JSONL for\n  model/tokens — works without recon TUI having been open\n* Shows empty state in picker instead of exiting immediately\n* Exposes build_live_session_map_public() to filter out live sessions\n* Removes ResumeHistory file-based tracking from app.rs (no longer needed)",
          "is_bot": false,
          "headline": "Resume picker scans claude session files directly, no history file ne…",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T15:09:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26afccf6dd502055455e0bb69cca59513006e273",
          "body": "* When a session disappears during refresh (exited), log it to\n  ~/.recon/history.json (last 10 entries) with session_id, name, cwd, model\n* New `recon resume` subcommand: interactive TUI picker for resuming past\n  sessions — shows name, directory, model, tokens, exit time\n* tmux keybinding: prefix+R opens the resume picker as a popup\n* Removed bash wrapper from session creation (no longer needed) — claude runs\n  directly again, restoring clean PID tracking",
          "is_bot": false,
          "headline": "Add resumable sessions history and interactive picker",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T15:05:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7abb0ecbd894985ac2e0d73baa2e17988dcd4eb2",
          "body": null,
          "is_bot": false,
          "headline": "Delay display-message so it appears on the next session after exit",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T14:29:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9d70ca282b98b8c0dc43e98cc4c877c8b054b4c9",
          "body": "* Wrap claude in bash: after claude exits, the wrapper reads the session file\n  and runs tmux display-message to show the resume command in the status bar\n* Add child-PID detection: when pane_current_command is bash/sh/zsh, check\n  child processes for a claude session file (handles the wrapper case)\n* Remove the pane-exited hook approach (was unreliable)",
          "is_bot": false,
          "headline": "Use bash wrapper for session creation, detect claude child PIDs",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T14:22:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e6566cf10b27f03d88bf0dbea0fbf0ac2e04b059",
          "body": null,
          "is_bot": false,
          "headline": "Show resume command in tmux status bar when claude exits",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T14:14:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d97fdc8a6a86d5a42f6e84be5e712abe64abd012",
          "body": "* Press y on any session to show a popup with recon --resume <id> --name <name>\n  and auto-copy it to the clipboard — no need to read claude's exit message\n* Remove remain-on-exit / auto-close timer: sessions close normally on exit",
          "is_bot": false,
          "headline": "Add y keybinding to copy resume command, drop remain-on-exit",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T14:12:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e9b2ea004c9f13a52d85a1b646f74d5ce7bacfcb",
          "body": null,
          "is_bot": false,
          "headline": "Auto-close dead pane 60s after claude exits (remain-on-exit timeout)",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T14:05:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce5f988783eaccddd984624707652a4e72091b00",
          "body": null,
          "is_bot": false,
          "headline": "Keep tmux window alive after claude exits to show resume ID",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T13:55:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "df942b98d1534163fe63defd921a59c704c83f14",
          "body": "* claude --resume creates a new session-id in the session file but appends\n  to the original JSONL — the name mismatch caused recon to show a placeholder\n* For sessions started via recon --resume: store original session-id in tmux\n  session env (RECON_RESUMED_FROM) and read it back in the fallback l\n[…]\ninal session's cwd from its JSONL so the\n  tmux session starts in the right project directory\n* Add E2E test (test 7) that verifies a resumed session shows the original\n  token count rather than 0/New",
          "is_bot": false,
          "headline": "Fix resumed sessions showing as New with 0 tokens",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T13:53:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d3e9141b3db1ff33482f0f746edc044cb019df33",
          "body": null,
          "is_bot": false,
          "headline": "Update README with --resume command",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T13:29:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5ecb3d64eeb33208ba168cbfd4763ff446602dec",
          "body": "* New `recon --resume <session-id> [--name <name>]` command wraps `claude --resume` in a tmux session\n* `switch_to_session` now uses `attach-session` when outside tmux and `switch-client` when inside, so the terminal is taken over directly",
          "is_bot": false,
          "headline": "Add recon --resume command to attach to a resumed claude session",
          "author_name": "gavraz",
          "author_login": "gavraz",
          "committed_at": "2026-03-14T13:29:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 16,
      "commits_last_year": 119,
      "latest_release_at": "2026-07-17T19:10:34Z",
      "latest_release_tag": "v0.7.0",
      "releases_from_tags": false,
      "days_since_last_push": 6,
      "active_weeks_last_year": 6,
      "days_since_latest_release": 6,
      "mean_days_between_releases": 13.4
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 57,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "recon",
          "exists": true,
          "license": "GPL-3.0",
          "keywords": [],
          "ecosystem": "crates",
          "matches_repo": false,
          "registry_url": "https://crates.io/crates/recon",
          "is_deprecated": false,
          "latest_version": "0.0.1",
          "repository_url": "https://codeberg.org/sumitpsm/recon",
          "versions_count": 1,
          "total_downloads": 31,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 10,
          "first_published_at": "2026-06-26T06:56:20.283121Z",
          "latest_published_at": "2026-06-26T06:56:20.283121Z",
          "latest_version_yanked": false,
          "days_since_latest_publish": 27
        }
      ]
    },
    "popularity": {
      "forks": 35,
      "stars": 260,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-03-15",
            "count": 2
          },
          {
            "date": "2026-03-16",
            "count": 2
          },
          {
            "date": "2026-03-17",
            "count": 3
          },
          {
            "date": "2026-03-18",
            "count": 3
          },
          {
            "date": "2026-03-19",
            "count": 2
          },
          {
            "date": "2026-03-22",
            "count": 1
          },
          {
            "date": "2026-03-24",
            "count": 2
          },
          {
            "date": "2026-03-25",
            "count": 4
          },
          {
            "date": "2026-03-27",
            "count": 1
          },
          {
            "date": "2026-03-31",
            "count": 1
          },
          {
            "date": "2026-04-09",
            "count": 1
          },
          {
            "date": "2026-04-19",
            "count": 1
          },
          {
            "date": "2026-04-21",
            "count": 1
          },
          {
            "date": "2026-05-08",
            "count": 1
          },
          {
            "date": "2026-05-10",
            "count": 1
          },
          {
            "date": "2026-05-12",
            "count": 1
          },
          {
            "date": "2026-05-20",
            "count": 1
          },
          {
            "date": "2026-05-27",
            "count": 1
          },
          {
            "date": "2026-06-01",
            "count": 1
          },
          {
            "date": "2026-06-03",
            "count": 1
          },
          {
            "date": "2026-06-20",
            "count": 1
          },
          {
            "date": "2026-06-21",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 33,
        "total_forks": 35
      },
      "star_history": null,
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "Cargo.toml"
      ],
      "largest_source_bytes": 50022,
      "source_files_sampled": 13,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 3167
    },
    "dependencies": {
      "manifests": [
        "Cargo.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": [
        "crates"
      ],
      "dependencies": [
        {
          "name": "ratatui",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.29"
        },
        {
          "name": "crossterm",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.28"
        },
        {
          "name": "tokio",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "serde",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "serde_json",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "1"
        },
        {
          "name": "toml",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.8"
        },
        {
          "name": "dirs",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "6"
        },
        {
          "name": "clap",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "4"
        },
        {
          "name": "chrono",
          "manifest": "Cargo.toml",
          "ecosystem": "crates",
          "version_constraint": "0.4"
        }
      ],
      "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": 7,
        "open_issues": 0,
        "closed_ratio": 1,
        "closed_issues": 12,
        "closed_unmerged_prs": 8
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "gavraz",
          "commits": 119,
          "avatar_url": "https://avatars.githubusercontent.com/u/8331212?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": false,
      "has_tests": true,
      "ci_workflows": [],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "Cargo.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": 1,
            "reason": "1 out of 7 merged PRs checked by a CI test -- score normalized to 1",
            "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 1/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": null,
            "reason": "no workflows found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "8 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": null,
            "reason": "No tokens found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 8,
            "reason": "2 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "707418b642bc62491c16e10930c666a8b1921b06",
        "ran_at": "2026-07-24T03:02:14Z",
        "aggregate_score": 3.2,
        "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-17T19:10:26Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-17T19:06:11Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/gavraz/recon",
    "host": "github.com",
    "name": "recon",
    "owner": "gavraz"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 52,
      "inputs": {
        "security": 32,
        "vitality": 81,
        "community": 60,
        "governance": 38,
        "engineering": 46
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 81,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "commits_last_year": 119,
              "human_commit_share": 1,
              "days_since_last_push": 6,
              "active_weeks_last_year": 6
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 6 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "6/52 weeks with commits",
                "points": 4.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "119 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 119
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "8 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 16,
              "latest_release_tag": "v0.7.0",
              "releases_from_tags": false,
              "days_since_latest_release": 6,
              "mean_days_between_releases": 13.4
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "16 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 16
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 6 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~13.4 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 13.4
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "moderate",
        "name": "Community & Adoption",
        "value": 60,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "moderate",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 52,
            "inputs": {
              "forks": 35,
              "stars": 260,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "260 stars",
                "points": 39.1,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 260
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "35 forks",
                "points": 12.8,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 35
                    }
                  }
                ],
                "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": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "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": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 38,
        "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": "moderate",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "merged_prs": 7,
              "open_issues": 0,
              "closed_issues": 12,
              "issue_closed_ratio": 1,
              "closed_unmerged_prs": 8
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "100% of issues closed",
                "points": 46.8,
                "status": "met",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "7/15 decided PRs merged",
                "points": 17.9,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 7,
                      "decided": 15
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 1/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": 46,
            "inputs": {
              "followers": 9,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "gavraz",
              "public_repos": 10,
              "account_age_days": 4374
            },
            "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": "9 followers of gavraz",
                "points": 7.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 9,
                      "login": "gavraz"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "10 public repos, account ~11 yr old",
                "points": 19.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 10
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 11
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "at_risk",
        "name": "Engineering Quality",
        "value": 46,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "critical",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 26,
            "inputs": {
              "has_ci": false,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "1 out of 7 merged PRs checked by a CI test -- score normalized to 1",
                "points": 2,
                "status": "partial",
                "details": [],
                "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": 32,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Dangerous-Workflow, Packaging, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "dangerous_workflow",
                    "packaging",
                    "signed_releases",
                    "token_permissions"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 32,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 14,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 4,
              "scorecard_aggregate": 3.2
            },
            "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": "1 out of 7 merged PRs checked by a CI test -- score normalized to 1",
                "points": 0.2,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 1/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no workflows found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "8 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "No tokens found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "2 existing vulnerabilities detected",
                "points": 6,
                "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": "good",
        "name": "AI Readiness",
        "value": 74,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "good",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.51,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 3167
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md"
                    }
                  }
                ],
                "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": "51 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 27.2,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 51,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 66,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "Cargo.lock"
              ],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.05,
              "toolchain_manifests": [
                "Cargo.toml"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Cargo.toml (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "Cargo.toml"
                    }
                  }
                ],
                "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": "Rust (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Rust"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "5 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 5,
                      "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": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Rust",
              "largest_source_bytes": 50022,
              "source_files_sampled": 13,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Rust (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Rust"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/13 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 13,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "crates package 'recon' points at a different repository (https://codeberg.org/sumitpsm/recon); excluded from ecosystem scoring",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-24T03:02:22.550012Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/g/gavraz/recon.svg",
  "full_name": "gavraz/recon",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Scores are signals, not warranties. They reflect publicly visible practices on GitHub — not a code audit, and not a security guarantee.

Missing data is excluded and weights renormalized, never scored as zero. Methodology is versioned and open: metrics v1.13.0, schema v0.27.0 — full methodology · metrics wiki.

How one result sits in the wider record: aggregate statisticscrates.io.