Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-27 16:10 UTC

JarvusInnovations / gws-axi

Google Workspace CLI for agents — designed with AXI (Agent eXperience Interface).

TypeScriptMIT★ 8 stars⑂ 1 forksince Apr 2026View on GitHub ↗

JarvusInnovations/gws-axi holds a health index of 62 out of 100, placing it in the Moderate band. It scores highest on Vitality (82/100) and lowest on Community & Adoption (37/100). It was last updated 6 days ago. A single contributor accounts for most of its recent work.

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

62
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

Jarvus InnovationsOrganization
12 followers225 public repossince Feb 2011

This repository is backed by an organization — shared, accountable stewardship that can outlive any single maintainer.

Package ecosystems

RegistryPackageVersionDownloads / moVersionsLast publishTags
npmgws-axi0.17.02,188286 days agogooglegoogle-workspacegmailcalendardocsdriveslidescliagentaxitoon

Metrics by category

Vitality

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

82Good · 22% of overall
How it's scored
36/36Push recency — last push 6 days ago
6.2/36Commit cadence — 9/52 weeks with commits
18/18Commit volume — 181 commits in the last year
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year181
human_commit_share1
days_since_last_push6
active_weeks_last_year9

Release discipline

100Excellent
How it's scored
27/27Ships releases — 28 releases published
36/36Release recency — latest release 6 days ago
27/27Release cadence — a release every ~3 days
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count28
latest_release_tagv0.17.0
releases_from_tagsno
days_since_latest_release6
mean_days_between_releases3
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?

37At risk · 18% of overall
How it's scored
13.7/60Stars — 8 stars
0/25Forks — 1 forks
0/15Watchers — 0 watchers
Inputs used
forks1
stars8
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)
0/18CONTRIBUTING guide
0/13.5Code of conduct
0/7.2Issue template
0/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
How it's scored
44.5/80Monthly downloads — 2,188 downloads/month across npm
0/20Registry dependents — not reported by this ecosystem
Inputs used
packagesgws-axi
dependents
ecosystemsnpm
total_downloads
monthly_downloads2,188
Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.

Sustainability & Governance

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

63Moderate · 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
10/10OpenSSF Scorecard: Contributors — project has 5 contributing companies or organizations
Inputs used
bus_factor1
contributors_sampled1
top_contributor_share1
How it's scored
46.8/46.8Issue resolution — 100% of issues closed
38.2/38.3PR acceptance — 42/42 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 0/8 approved changesets -- score normalized to 0
Inputs used
merged_prs42
open_issues0
closed_issues3
issue_closed_ratio1
closed_unmerged_prs0
How it's scored
30/30Ownership backing — organization-owned
0/20Verified domain
8/25Owner reach — 12 followers of JarvusInnovations
25/25Track record — 225 public repos, account ~15 yr old
Inputs used
followers12
owner_typeOrganization
is_verified
owner_loginJarvusInnovations
public_repos225
account_age_days5,646
How it's scored
25/25Published & resolvable — 1 package(s) on npm
35/35Publish recency — latest publish 6 days ago
20/20Version history — 28 published versions
20/20Not deprecated — active, not deprecated or yanked
Inputs used
packagesgws-axi
ecosystemsnpm
any_deprecatedno
min_days_since_publish6

Engineering Quality

Are baseline engineering and documentation practices in place?

67Moderate · 20% of overall
How it's scored
24/24CI workflows — 5 workflow(s)
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 8 out of 8 merged PRs checked by a CI test -- score normalized to 10
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno

Documentation

65Moderate
How it's scored
30/30README
25/25Documentation directory
0/15Documentation / homepage site
10/10Repository description
0/10Topics
0/10Wiki
Inputs used
topics
has_wikino
homepage
has_readmeyes
has_docs_diryes
has_descriptionyes

Security

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

54Moderate · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
2.2/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 8 out of 8 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/8 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 5 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
7.5/7.5Maintained — 30 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
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 — detected GitHub workflow tokens with excessive permissions
5.2/7.5Vulnerabilities — 3 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate4.6
Excluded from scoring (no data or not applicable): signed_releases. Remaining weights renormalized.
How it's scored
35/35Direct dependencies free of known advisories — no direct dependency carries a known advisory
10/25Indirect dependencies free of known advisories — 1 affected: brace-expansion 2.1.2 (high 7.5)
40/40No advisories left outstanding — no advisory has been public longer than 90 days
Inputs used
sourceosv
advisories1
affected_packages1
assessed_packages93
unassessed_packages0
affected_by_severityhigh 1
direct_affected_packages0
Matched the npm:gws-axi@0.17.0 runtime dependency closure — what installing the published package pulls in — 93 packages. Reachability is not analyzed.

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.

68Moderate · 0% of overall
How it's scored
45/45Agent instructions — .claude/CLAUDE.md
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 100 of 100 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share1
agent_instruction_files.claude/CLAUDE.md
agent_instruction_max_bytes13,597
How it's scored
0/18One-command bootstrap
22/22Automated tests
0/11Lint / format config
11/11Static type checking — tsconfig.json
0/10Reproducible environment
10/10Demonstrated agent practice — 82 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
lockfiles
has_dockerfileno
typed_languageyes
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configstsconfig.json
agent_commit_share0.82
toolchain_manifests
dependency_bot_commit_share0
How it's scored
45/45Type-checkable code — TypeScript (statically typed)
55/55Manageable file sizes — 0/97 source files over 60KB
Inputs used
primary_languageTypeScript
largest_source_bytes53,959
source_files_sampled97
oversized_source_files0

Key facts

8GitHub stars
1contributors
181commits, last 12 months
6days since last push
28releases
1bus factor
0open issues
npmpackage ecosystems

Data collection warnings

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

More detail

OpenSSF Scorecard 4.6 / 10
4.6aggregate

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-27 16:10 UTC

10Binary-Artifactsno binaries found in the repo
3Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests8 out of 8 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/8 approved changesets -- score normalized to 0
10Contributorsproject has 5 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow 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
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
7Vulnerabilities3 existing vulnerabilities detected
Direct dependencies 7
RegistryPackageVersion constraintManifest
npm@toon-format/toon^2.1.0package.json
npmaddressparser^1.0.1package.json
npmaxi-sdk-js^0.1.4package.json
npmdiff^9.0.0package.json
npmgoogle-auth-library^10.7.0package.json
npmgoogleapis^173.0.0package.json
npmturndown^7.2.4package.json
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

Dependency advisories 1

Installing npm:gws-axi@0.17.0 pulls in 93 packages, direct and transitive: 1 carry known advisories, of which 0 are direct dependencies.

PackageVersionRelationSeverityAdvisoriesFixed in
brace-expansion2.1.2indirecthigh15.0.8

An advisory means the version recorded in the dependency graph falls inside an advisory’s affected range. Reachability is not analysed, and the graph includes development and test pins — a finding may concern tooling rather than shipped software.

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 637,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "Shell": 138,
        "JavaScript": 54026,
        "TypeScript": 628563
      },
      "pushed_at": "2026-07-20T22:08:31Z",
      "created_at": "2026-04-19T15:46:25Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-20T22:07:09Z",
      "description": "Google Workspace CLI for agents — designed with AXI (Agent eXperience Interface).",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "develop",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": "http://jarv.us",
      "name": "Jarvus Innovations",
      "type": "Organization",
      "login": "JarvusInnovations",
      "company": null,
      "location": "Philadelphia, PA",
      "followers": 12,
      "avatar_url": "https://avatars.githubusercontent.com/u/609450?v=4",
      "created_at": "2011-02-09T19:43:15Z",
      "is_verified": null,
      "public_repos": 225,
      "account_age_days": 5646
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.17.0",
          "kind": "minor",
          "published_at": "2026-07-20T22:08:31Z"
        },
        {
          "tag": "v0.16.2",
          "kind": "patch",
          "published_at": "2026-07-02T18:40:08Z"
        },
        {
          "tag": "v0.16.1",
          "kind": "patch",
          "published_at": "2026-07-02T12:52:34Z"
        },
        {
          "tag": "v0.16.0",
          "kind": "minor",
          "published_at": "2026-07-02T04:56:26Z"
        },
        {
          "tag": "v0.15.0",
          "kind": "minor",
          "published_at": "2026-07-02T00:36:23Z"
        },
        {
          "tag": "v0.14.1",
          "kind": "patch",
          "published_at": "2026-06-24T17:30:36Z"
        },
        {
          "tag": "v0.14.0",
          "kind": "minor",
          "published_at": "2026-06-24T16:09:03Z"
        },
        {
          "tag": "v0.13.0",
          "kind": "minor",
          "published_at": "2026-06-23T19:38:13Z"
        },
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2026-06-23T13:35:11Z"
        },
        {
          "tag": "v0.11.0",
          "kind": "minor",
          "published_at": "2026-06-23T13:07:02Z"
        },
        {
          "tag": "v0.10.2",
          "kind": "patch",
          "published_at": "2026-06-11T17:34:50Z"
        },
        {
          "tag": "v0.10.1",
          "kind": "patch",
          "published_at": "2026-06-11T16:37:42Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2026-06-11T15:57:14Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2026-06-10T23:43:27Z"
        },
        {
          "tag": "v0.8.4",
          "kind": "patch",
          "published_at": "2026-06-09T02:29:41Z"
        },
        {
          "tag": "v0.8.3",
          "kind": "patch",
          "published_at": "2026-06-08T13:17:32Z"
        },
        {
          "tag": "v0.8.2",
          "kind": "patch",
          "published_at": "2026-05-22T16:30:29Z"
        },
        {
          "tag": "v0.8.1",
          "kind": "patch",
          "published_at": "2026-05-22T16:25:19Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-05-13T17:50:38Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-05-13T17:08:09Z"
        },
        {
          "tag": "v0.6.2",
          "kind": "patch",
          "published_at": "2026-05-13T15:33:29Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2026-05-01T22:30:05Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-04-28T14:31:10Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-04-24T22:38:22Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-04-22T02:38:39Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-04-20T00:36:33Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-04-19T20:07:44Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-04-19T19:28:20Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "8e0b492538df01efd83ce02d8336ebd4f6030e2c",
          "body": "…e-data\n\nfeat(calendar): provider-uniform join URLs (conferenceData + scrape fallback)",
          "is_bot": false,
          "headline": "Merge pull request #44 from JarvusInnovations/feat/calendar-conferenc…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-20T22:06:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ac3caf39ae50115892a9fa5c9a96885b553ba303",
          "body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01X1L36Gc8WZ93aCfUHtrWbW",
          "is_bot": false,
          "headline": "chore(plans): mark calendar-conferencing done (PR #44)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-20T21:46:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e203b9c4a29b5e6e659b478edcfc62259bdcd7f4",
          "body": "README calendar-reads example + implementation-status entry in the\nproject CLAUDE.md.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01X1L36Gc8WZ93aCfUHtrWbW",
          "is_bot": false,
          "headline": "docs(calendar): note conferencing join-URL surface (#43)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-20T21:44:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "cafdae37b9849d63cb5acf8740a050ff014c41aa",
          "body": "Surface a single tappable join link for any meeting, not just Google\nMeet. New shared resolver src/commands/calendar/conference.ts walks a\npriority chain: structured conferenceData video entryPoint -> hangoutLink\n-> provider-anchored URL scraped from description, then location.\n\nThe scrape is the on\n[…]\nAuth scope. 16 unit tests over real-shape Meet + Teams-synced fixtures.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01X1L36Gc8WZ93aCfUHtrWbW",
          "is_bot": false,
          "headline": "feat(calendar): resolve provider-uniform join URLs (#43)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-20T21:44:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "57be38d23401fe359d199b83f692bf9f78aae719",
          "body": "Spec the cross-command join-URL surface for `calendar events`/`get`:\na provider-uniform resolution chain (structured conferenceData video\nentryPoint -> hangoutLink -> provider-anchored description/location\nscrape) with source disclosure per surface-completeness-limits.\n\nMotivated by issue #43: a rea\n[…]\nhe\ndescription, so conferenceData alone leaves exactly that case blank.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01X1L36Gc8WZ93aCfUHtrWbW",
          "is_bot": false,
          "headline": "docs(specs): add calendar conferencing spec + plan (#43)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-20T21:44:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fa2e25879f69190f308a863b1e20172ba8150c2d",
          "body": "fix(auth): never send joined teammates to the Cloud Console",
          "is_bot": false,
          "headline": "Merge pull request #41 from JarvusInnovations/fix/join-no-console",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T18:38:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eeb617b4d3fb876deeda28d2b991623327f2896d",
          "body": "A teammate who adopts a shared client via `auth join` has no IAM on the\nshared GCP project, but setup.html rendered the full per-step Cloud\nConsole deep-links (their setup is 6/7, not \"complete\", so links weren't\ncollapsed). Following one — e.g. \"Audience → Test users\" — dropped them on\na Console \"Y\n[…]\nvs\n  Internal consent-screen config, user cap, teammate steps).\n- Spec + status index updated; unit tests for the guidance helper.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(auth): never send joined teammates to the Cloud Console",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T17:07:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2d511e7a9e99aef9bc2bd87abbb4e769c025ac71",
          "body": "…hint\n\nfix(auth): name the target account on auth login (setup page + login_hint)",
          "is_bot": false,
          "headline": "Merge pull request #39 from JarvusInnovations/fix/auth-login-account-…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T12:51:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "37a22a20aaf3d4ce24bde7d718bb4f4f196fe10b",
          "body": "…n_hint)\n\nBare `auth login` (no --account) prepared an OAuth flow with no expected\naccount, so the setup.html panel showed a generic \"Waiting for\nauthentication\" and the Google URL carried no `login_hint` — the user\ncouldn't tell which account they were about to authenticate, or which\nbrowser profil\n[…]\nunt), so\nthis closes the gap without further UI changes. Documented in\narchitecture.md; unit-tested via the extracted pure helper.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(auth): name the target account on `auth login` (setup page + logi…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T05:39:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4419444086b218fcb28a5087b6d7f556b39c106f",
          "body": "feat(slides): inline-markdown links + comments",
          "is_bot": false,
          "headline": "Merge pull request #38 from JarvusInnovations/feat/slides-links-comments",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T04:54:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5da3a185951f2c87af082723cf3ea9aed7652356",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(plans): close out slides-links-comments done (PR #38)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T04:40:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e99b9b68af7390a00e532ad02f106ec2d98668fa",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: document slides links + comments in README and status index",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T04:39:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a0379723a18a88d3ffc6b8711a4078c8cb2a8eda",
          "body": "Slides text extraction dropped hyperlinks (read textRun.content, ignored\ntextRun.style.link). Now:\n- linkHref() maps external url → the url, internal pageObjectId →\n  slide:<id>; nav-only links (relativeLink/slideIndex) stay plain text.\n- runsToMarkdown() joins runs, wrapping linked spans as [text](\n[…]\nnts, no new scope. Unit tests cover linkHref, runsToMarkdown\n(coalescing, whitespace, distinct links, empty core), and extraction.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(slides): resolve embedded links inline as markdown + add comments",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T04:39:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4b85b1d50f07bdc77e42ddcf9c22f9f35edd247e",
          "body": "Backfill the previously-unspecced Slides read surface with a\ncontent-extraction contract (title/body/tables/notes, image counts,\ninline-markdown link resolution) and document the slides comments alias.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(specs): add slides read spec + links/comments plan",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T04:39:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2edf1a4b1bd3543095ae6b192f59ef916c4299f7",
          "body": "feat(sheets): add Sheets service — read (rich grid) + comments",
          "is_bot": false,
          "headline": "Merge pull request #36 from JarvusInnovations/feat/sheets-read",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T04:30:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6e7fc8fea1a3a192e5652e73991e5af8ee5f9a50",
          "body": "CI format:check (oxfmt) flagged the three new/edited files. Also add the\nSheets service to the README status table, intro, agent-instruction\nsnippet, usage examples, and roadmap.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "style(sheets): apply oxfmt formatting + document Sheets in README",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T03:47:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0066d8b109df52d7337bb1ea84f768dcde8f481c",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(plans): close out sheets-read done (PR #36)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T03:33:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5f93ab06461c75d860746334a794652ae85ca60c",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: record sheets service in project status index",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T03:31:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8968c7678a51152783d7733c5a2cb5dadadb46ab",
          "body": "New `sheets` service (BYO `spreadsheets` scope + sheets.googleapis.com;\nsheetsClient factory; doctor probe; cli registration).\n\n`sheets read <id>`:\n- Tab model like `docs read`: always lists sheets[N]{gid,title,index,rows,\n  cols}; single-tab auto-renders, multi-tab without --tab disambiguates.\n- Gr\n[…]\nts cover the pure helpers (column letters, A1 range origin,\ngrid build + header promotion, link/markdown extraction, header-mode).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sheets): add sheets service — read (rich grid) + comments",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T03:31:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "41355d0a2e7d99a52db37db5437ff4081d64aa9a",
          "body": "Spec-first scaffold for a new Sheets service. `sheets read` mirrors the\n`docs read` tab model (a spreadsheet's sheets are its tabs), renders the\ngrid with A1-addressable column letters or auto/explicit header promotion,\nresolves embedded links inline as markdown, and surfaces cell notes. Also\nregisters sheets in architecture.md (commands, client factories, scopes).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(specs): add sheets read spec + plan",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T03:30:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c100ef8e5fd469a4ee3698d1afccb8a591d70bcf",
          "body": "feat(auth): add `auth join` for shared-client onboarding",
          "is_bot": false,
          "headline": "Merge pull request #35 from JarvusInnovations/feat/auth-join",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T00:34:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "caf80ec059f80704511ce20c36b5de17d1a9cb79",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(plan): close out auth-join (pr #35)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T00:27:54Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "72b6b3307ee00f9ff64564b251004b5eb7db5b70",
          "body": "Adds `gws-axi auth join <path> [--published]`: reads a shared Desktop\nOAuth client credentials.json from any path (e.g. ~/Downloads), copies\nit into the config dir, and marks setup steps 1-6 done (via: team-join),\nleaving step 7 (the teammate's own login) untouched. Lets a team reuse\none OAuth clien\n[…]\nJSON, shared by auth join, the\ncredentials_saved step, and the oauth_client auto-confirm.\n\nImplements specs/commands/auth-join.md.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): add `auth join` for shared-client onboarding",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T00:26:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "00971768f0c507a5d26ecade6fc8cc50d416f2c6",
          "body": "Spec for a one-shot onboarding command onto an already-provisioned\n(shared) OAuth client: validate a Desktop credentials.json, install it,\nand mark setup steps 1-6 satisfied-by-the-shared-client so the from-\nscratch wizard doesn't misfire. Includes the local principle that\npublish status is asserted (--published), never inferred from the file.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(specs): add auth join spec + plan",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-07-02T00:26:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "28130d1b6b03c3b0aa52bed84b0dd4ab5215ad51",
          "body": "ci: add pre-merge lint/format/type-check gates",
          "is_bot": false,
          "headline": "Merge pull request #33 from JarvusInnovations/chore/ci-quality-gates",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-27T02:33:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6ec0a20e16e89c13a242855ded9b6951fb5eb415",
          "body": "Extend the existing build-and-test job with the standard pre-merge quality\ngates (oxlint, oxfmt --check, tsc --noEmit) ahead of build and test. Keeps\nthe repo's existing setup-node + setup-bun provisioning as-is; the gates are\ncredential-free and run on every push/PR to main and develop.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QHVPQXzEiaPAupLgDa7D5n",
          "is_bot": false,
          "headline": "ci: add lint, format-check, and type-check gates to CI",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-27T02:17:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "028be6931887c3d45d4e8253d6e184f5f35c118f",
          "body": "One-time mechanical reformat of the TypeScript source tree with oxfmt\n(the new house formatter) so the format:check gate passes on its first\nCI run. No behavioral changes — formatting only.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QHVPQXzEiaPAupLgDa7D5n",
          "is_bot": false,
          "headline": "style: apply oxfmt formatting across src",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-27T02:16:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2e8c974649ca2581e8114af65aeeeec0a63ef3bf",
          "body": "Clear the errors the new lint gate surfaces, all minimal:\n\n- Remove six unused imports/bindings (no-unused-vars): readPendingAuth\n  (auth.ts), readSetupState (steps.ts), getDefaultAccount (loopback.ts),\n  accountHeaderFields (service-stub.ts), gmail_v1 type (modify.ts), and the\n  dead runtimeFailing\n[…]\nintAt scan; same behavior, no control chars\n  in a RegExp.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QHVPQXzEiaPAupLgDa7D5n",
          "is_bot": false,
          "headline": "fix: resolve oxlint correctness findings in existing code",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-27T02:15:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e5957e3aa88a113e853953b8bce2939a88623307",
          "body": "Add the Jarvus house TypeScript linter/formatter (oxlint + oxfmt) as dev\ndependencies and wire the standard four-script contract into package.json:\nlint / format / format:check / typecheck (scoped to src bin). Add the base\noxlint config (correctness-as-error) and recommend the oxc VS Code extension\nso local editing matches CI.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QHVPQXzEiaPAupLgDa7D5n",
          "is_bot": false,
          "headline": "chore(ci): add oxlint + oxfmt tooling and quality-gate scripts",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-27T02:15:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5d6324ece893e4c8e595850992092882ebc7ba4e",
          "body": "…sync\n\ndocs(readme): sync command surface + status table",
          "is_bot": false,
          "headline": "Merge pull request #31 from JarvusInnovations/docs/readme-drive-docs-…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T16:35:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d66a96886cf6adbf42b61872d3972298c0dbe23d",
          "body": "… table\n\n- Status: replace the dense blockquote with a per-service Reads/Writes table\n  (✅ shipped / 🟡 partial / 🚧 planned / ✋ out of scope).\n- Docs: add `revisions` and `diff`; document `docs read`'s inline revisions;\n  fix the export flag (`--format` → `--as`) and add `--revision`.\n- Drive: split \n[…]\nin/--content, --convert, --convert+--update) + `mkdir`\n  writes.\n- Roadmap: correct the stale \"Drive writes not implemented\" line.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(readme): sync command surface + replace status blockquote with a…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T16:34:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a0222a3add56d799a34dd1d4c1f3fbc78c43323e",
          "body": "…nt-sources\n\nfeat(drive): upload content sources (stdin/--content) + convert-on-update",
          "is_bot": false,
          "headline": "Merge pull request #30 from JarvusInnovations/feat/drive-upload-conte…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T16:07:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "32c87e4b34447f7bbabdd7123d2e836921b26bcc",
          "body": "…convert done (PR #30)\n\nCloseout for both upload follow-ups (shipped together in PR #30): status done,\nvalidation checked, Notes + Follow-ups populated. Updates CLAUDE.md status.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(plans): mark drive-upload-inline-content + drive-upload-update-…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T16:06:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6aae31f848bcb967ee1f1964c28b6816047db314",
          "body": "Lifts the blanket --convert + --update rejection. When the target file is\nalready the native type the source converts to (e.g. markdown -> existing\nDoc), the converted media is re-imported as a NEW revision — the write side\nof the read->edit->write-back loop with docs read/diff/revisions.\n\nA files.g\n[…]\n live: markdown convert+update bumped a Doc 1->2 revisions with\nreplaced content; csv-onto-Doc mismatch rejected. 131 tests green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(drive): allow --convert with --update for matching native targets",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T16:04:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d18d455fbd41ced39dc82303ae6a7792d5f93b76",
          "body": "drive upload now accepts content from three mutually-exclusive sources: a\nlocal file path (default), `-` for stdin, or --content <string>. For stdin\nand --content there's no filename to infer, so --name is required and the\ndefault --mime derives from the --name extension (reusing detectMimeType).\n\nL\n[…]\ne notes.md --convert`.\n\nVerified live: stdin and --content each create a native Doc via Google's\nconversion. 131 tests green (+5).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(drive): upload from stdin or --content (no temp file)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T16:01:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a2e7537fc8c8448ffde77f39392ad9fee0aeacbb",
          "body": "…date\n\nSpec-first groundwork for the two upload follow-ups:\n\n- Content sources: local path (default), stdin (`-`), or `--content <string>`;\n  exactly one required. --name required (and --mime derived from it) when\n  there's no filename to infer.\n- `--convert` + `--update`: lifted the blanket rejecti\n[…]\nvision (the write side of read->edit->write-back).\n\nMarks drive-upload-inline-content and drive-upload-update-convert in-progress.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(specs): extend drive upload with content sources + convert-on-up…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:58:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dcd3b766e1db5a47ef50bf64bd41df4700b9a19b",
          "body": "…overability\n\nfeat(docs): revision discoverability + diff command",
          "is_bot": false,
          "headline": "Merge pull request #28 from JarvusInnovations/feat/docs-revision-disc…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:34:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "74445418fbcf0798d2bb08a20870c1ec40e2ee1b",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(plans): mark docs-revision-discoverability done (PR #28)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:32:58Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "db5f4c1919239733c8e541db4e6d6fb03a6d114a",
          "body": "…lity\n\nCheck verified criteria and capture the work-in-progress record. Status\nstays in-progress; formal closeout (status done + pr) happens at merge.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(plans): record validation + notes for docs-revision-discoverabi…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:27:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5a39c623025bf713c0e9d0ca515123422d57740a",
          "body": "Resolve spec-drift audit findings (all spec-wording clarifications; no code\nchange — the implementation was correct and more specific than the prose):\n\n- docs-read: failure case emits a `revisions: history unavailable` scalar;\n  the unconditional version-history help entry covers the redirect.\n- doc\n[…]\n the fidelity caveat\n  lives in help[].\n- drive-revisions: REVISION_CONTENT_UNAVAILABLE also covers native export\n  HTTP failures.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(specs): tighten docs read/diff specs to match shipped behavior",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:26:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "14e9be58d1fe55bdde070f99fdba478d5c7cff98",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: update implementation status for docs read revisions + docs diff",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:22:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "99fc82e6b83c8366e35f9fe3c98b8cc35e7dd515",
          "body": "`docs diff <fileId> <revA> [revB]` exports both revisions to markdown\nserver-side and computes a unified diff locally (Google has no diff API),\nso agents don't download both sides and diff themselves. revB defaults to\nthe head revision.\n\nOutput: document/from/to provenance + summary{lines_added,line\n[…]\ntical revisions,\nREVISION_NOT_FOUND, VALIDATION_ERROR, and --help routing. computeDiff +\nparseFlags unit-tested (126 tests green).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(docs): add diff command for comparing two revisions",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:22:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6cb942dc64beaa99c80f513ec830bdfe43b2d527",
          "body": "docs read now shows a `revisions[5]{id,modified,author}` block on every read\n(provenance-by-default) and funnels help to `docs revisions`,\n`docs download --revision`, and `docs diff` with real revision ids.\n\nThe revisions fetch is best-effort: a failed secondary Drive call degrades to\na `revisions: history unavailable` note rather than failing the content read.\nVerified live against a real multi-tab Doc.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(docs): inline recent revisions in docs read",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:18:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d4acb86fd563895f985d5a9710ecf9e4230b18ea",
          "body": "Factor the revision-export logic out of `docs download --revision` into\nsrc/commands/docs/revision-content.ts:\n\n- fetchNativeRevisionExport — exportLinks fetch + markdown-default fallback,\n  returning bytes + provenance. Reused by the upcoming `docs diff`.\n- listRecentRevisions — minimal newest-firs\n[…]\nevision branch now calls the\nhelper; the binary branch keeps its own metadata + alt=media fetch. Build\nclean, all 116 tests green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(docs): extract shared revision helpers",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:15:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fbfeff11a1094a78a1a999c8dae4c0c9d16b708c",
          "body": "Commands:\n  bun add diff\n  bun add -d @types/diff\n\nUsed by the upcoming `docs diff` to compute unified diffs of two\nrevisions' markdown exports locally (Google exposes no diff API).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(deps): add diff for docs diff command",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:11:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d897294ba9e4f2e780090c46ce3f2cdb50eac9e2",
          "body": "…e-convert\n\nTwo planned upload-side capabilities surfaced while specing the\nread->edit->write-back round trip:\n\n- drive-upload-inline-content: upload from stdin/--content (no temp file).\n- drive-upload-update-convert: allow --convert + --update so an existing\n  native Doc's content can be replaced from markdown as a new revision.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(plans): note follow-up plans for upload inline-content and updat…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:11:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5543aed6761f86c9a235a2a85c4b8104ec77c236",
          "body": "Spec groundwork for making Google Doc version history discoverable and\ndiffable, before implementation:\n\n- principles.md: new `provenance-by-default` — content reads carry their\n  source revision by default (deliberately overrides minimal-default-schemas);\n  justified by porting content between syst\n[…]\nmd: diff out-of-scope line now points at docs diff.\n- plans/docs-revision-discoverability.md: the implementing plan (in-progress).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(specs): add provenance-by-default, docs read revisions, docs diff",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-24T15:11:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "527c52beeb19bb5d32be5f777ea3c1ddfbfff03a",
          "body": "…hooks\n\nfeat(setup): add `setup hooks` command for session-hook install",
          "is_bot": false,
          "headline": "Merge pull request #26 from JarvusInnovations/feat/standardize-setup-…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-23T19:35:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b202e6acd7923e5b442d64d847993d11e211660",
          "body": "Add an explicit `setup hooks` command that installs/repairs the agent\nSessionStart hook via installSessionStartHooks() (Claude Code, Codex,\nOpenCode), matching the AXI standard (principle 7) and the first-party\nreference tools (gh-axi, chrome-devtools-axi).\n\n- remove the stale auto-install path (the\n[…]\nle-skill as the two ambient-\n  context paths\n- update specs (architecture.md, new commands/setup.md), docs/design.md,\n  and README\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(setup): add `setup hooks` command for session-hook install",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-23T19:05:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9787f8797d30b7b4ce94ea2a8c4e78399b065983",
          "body": "feat(drive): add mkdir command (create folders)",
          "is_bot": false,
          "headline": "Merge pull request #24 from JarvusInnovations/feat/drive-mkdir",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-23T13:33:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ad912f8256840f3048fadaf3a11e336ea99ed7d5",
          "body": "Add `gws-axi drive mkdir <name>` — create a Drive folder via files.create\nwith mimeType application/vnd.google-apps.folder (no media); --parent nests\nit under an existing folder. Returns action: created + folder{id,name,\nparents,web_view_link} and leads help[] with `drive upload --parent <id>`.\n\nRep\n[…]\nd-to-end: folder -> nested folder -> upload into it -> ls.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DsJVnPZmZWd4KdLHJYXCPQ",
          "is_bot": false,
          "headline": "feat(drive): implement mkdir command (create folders)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-23T13:32:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9bc90c233704d1df34c17a1f5846bd263f569138",
          "body": "Second Drive write: `gws-axi drive mkdir <name>` creates a folder\n(files.create with the folder MIME, no media), with optional --parent.\nProduces the folder ID that `drive upload --parent` consumes. Rides the\nexisting full `drive` scope — no new scope. Spec is source of truth.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DsJVnPZmZWd4KdLHJYXCPQ",
          "is_bot": false,
          "headline": "docs(specs): add drive mkdir command spec",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-23T13:32:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "85eb7a653d81d60920ffdcf20d0927a7c8911b07",
          "body": "feat(drive): add upload command (create / convert / update)",
          "is_bot": false,
          "headline": "Merge pull request #22 from JarvusInnovations/feat/drive-upload",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-23T13:03:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c39cdebb6cf22a0a31870c9006e9f178f1400437",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DsJVnPZmZWd4KdLHJYXCPQ",
          "is_bot": false,
          "headline": "chore(plans): mark drive-upload done (PR #22)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-23T12:55:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d535510ffa93836bc3712d0c029ba14f7085c78b",
          "body": "Add `gws-axi drive upload <local-path>` — the first Drive write:\n\n- create-new (default): stream a local file to files.create\n- --convert: server-side conversion to native Doc/Sheet/Slides\n- --update <fileId>: replace an existing file's content (new revision) + rename\n- --parent/--name/--mime, with \n[…]\nped via docs download), and the unsupported-convert guard.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DsJVnPZmZWd4KdLHJYXCPQ",
          "is_bot": false,
          "headline": "feat(drive): implement upload command (create/convert/update)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-23T12:54:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "df89aa30cf9a718d458f180c4892156d903bd083",
          "body": "First Drive write: `gws-axi drive upload <local-path>` to push local file\nbytes into Drive, with --parent/--name/--mime, --convert (native Google\nformat), and --update <fileId> (replace content). Rides the existing full\n`drive` scope — no new scope. Spec is source of truth; implementation follows.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DsJVnPZmZWd4KdLHJYXCPQ",
          "is_bot": false,
          "headline": "docs(specs): add drive upload command spec",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-23T12:54:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "013a0b5fa9a8e5cc9a972b35675ceed03f804198",
          "body": "…reauth-hints\n\nfix(doctor): emit per-account re-auth commands for scope/token gaps",
          "is_bot": false,
          "headline": "Merge pull request #20 from JarvusInnovations/fix/doctor-per-account-…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T17:33:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "13544140429b0d16eb439f5d63de3a32e64949b1",
          "body": "The scope-gap and token-failure hints named the affected accounts but\ngave only a generic `auth login --account <email>` template — leaving an\nagent to construct the command per account. Per AXI contextual-help-\nsuggestions, emit one concrete runnable line per affected account:\n\n  gws-axi auth login\n[…]\n-wait\n\nwith the agent prepare/relay/`--wait` flow spelled out, so an agent can\nrun them directly without filling in a placeholder.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(doctor): emit per-account re-auth commands for scope/token gaps",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T17:32:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dd623218639fc8ff8df9aaf074c8e2a99d0bd693",
          "body": "…cope-checks\n\nfix(doctor): check ADDITIONAL_SCOPES presence per account",
          "is_bot": false,
          "headline": "Merge pull request #18 from JarvusInnovations/fix/doctor-additional-s…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T16:06:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25e4459d2dfda800c6ac807c5a93ed34c9e74ea8",
          "body": "doctor's runtime tier only probed the five representative SERVICE_SCOPES,\nso a granted-but-missing additional scope (drive.activity.readonly,\ngmail.settings.basic) was invisible — surfacing only when the dependent\ncommand was finally run and failed. For scopes that require a one-time\nre-auth that's \n[…]\nautomatically.\n\nUpdates specs/commands/drive-activity.md (the doctor behavior it\npreviously disclaimed) and adds probe unit tests.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(doctor): check ADDITIONAL_SCOPES presence per account",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T16:05:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "060275e34c97ebcdb08c27345d25eda1846e0ebc",
          "body": "…exploration\n\nfeat: workspace history & exploration reads (gmail headers/raw, drive revisions, drive activity)",
          "is_bot": false,
          "headline": "Merge pull request #17 from JarvusInnovations/feat/workspace-history-…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:53:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6733c9a6ab098194076deac05ea66823a6df5240",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(plans): record PR #17 on workspace-history-exploration",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:50:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a43031b285008a76dcb4df622c86684b7c242543",
          "body": "Flip status to done, check verified validation criteria, record Notes\n(live-verification scope, the audit pass) and Follow-ups (People API\nactor resolution, --full activity, revision --diff — all deferred).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(plans): close out workspace-history-exploration",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:48:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1c7423abf360f7539926ee468939b09551c1e058",
          "body": "Update CLAUDE.md \"Current implementation status\": gmail read\n--headers/--raw, drive/docs revisions + download --revision, drive\nactivity (with the drive.activity.readonly re-auth note), and the\nexpanded Vitest coverage.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(status): record workspace history & exploration reads",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:46:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "cc64a8ef021d02b8eb88f559e787b1509468f718",
          "body": "Spec-drift audit of the three new features surfaced one bug and several\ngaps; bring code and specs back into conformance:\n\n- gmail read --raw --out: emit the same message{id,thread_id,internal_date,\n  bytes} shape as the inline path (was missing internal_date and nested\n  bytes at the wrong level).\n\n[…]\nhe additional\n  action labels + actor types; clarify the API-enablement vs runtime-probe\n  split for driveactivity.googleapis.com.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(workspace-history): resolve spec-drift audit findings",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:46:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4febee2fd5369ed64abb5bc04adc33dd31fd177b",
          "body": "Implements specs/commands/drive-activity.md.\n\n`drive activity <itemId>` reports an attributed, timestamped action\ntimeline — create/edit/move/rename/delete/restore, permission changes,\nand comments — as activities[N]{time,action,actor,target}, newest first.\nRicher than `drive revisions` (content ver\n[…]\nplied by auth/drive, so pre-existing accounts must re-auth\nonce — surfaced via an INSUFFICIENT_SCOPE error pointing at auth login.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(drive): add activity timeline via Drive Activity API v2",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:40:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "25bd94144b4256d659083d432a8e112d2622474d",
          "body": "Implements specs/commands/drive-revisions.md.\n\n`drive revisions <fileId>` (and `docs revisions` alias) lists a file's\nrevision history newest-first as revisions[N]{id,modified,author}, with\na document{} header (type native|binary, revision_count, head_revision),\n--full for size/mime/kept/published, \n[…]\nON_NOT_FOUND, EXPORT_FORMAT_REQUIRED, REVISION_CONTENT_UNAVAILABLE\n(purged binary revisions). No new scope — auth/drive covers it.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(drive): add revisions list + revision content download",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:37:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5243da41d7c12a407a2e307fa40a08e47b51c2bb",
          "body": "Implements specs/commands/gmail-read.md.\n\n--headers renders the full RFC 2822 header set (every Received hop,\nMessage-ID, In-Reply-To, References, DKIM/ARC auth results) as a\nheaders[N]{name,value} list plus internal_date, alongside the parsed\nbody so an agent gets provenance and readable content in\n[…]\nessage (noted in help[]). No new scope — gmail.modify already covers\nformat=raw and full payload headers. Reading stays read-only.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(gmail): add read --headers and --raw modes",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:32:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1e47b153730b0e544475e9fcb2b85aeb3591ef46",
          "body": "Spec-first for three additive read-only capabilities:\n- specs/commands/gmail-read.md — --raw (format=raw) + --headers (full\n  RFC 2822 header set + internalDate) modes; no new scope\n- specs/commands/drive-revisions.md — drive revisions list (+ docs\n  revisions alias) and docs download --revision; ma\n[…]\n tracking the build (three\ncommits, validation criteria) and IDs-first-class + completeness-limit\ndisclosure baked into each spec.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(specs): spec workspace history & exploration reads",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:29:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "854dda111e76fd228bc19e68978a5b4f7b123546",
          "body": "Reverse-engineer the existing codebase into specs/ as the source of truth:\n- specs/principles.md — decisive cross-cutting principles (agent-first\n  output, minimal default schemas, ids-are-first-class,\n  surface-completeness-limits, write-protection, read-only-stays-read-only,\n  byo-oauth, single-so\n[…]\nlans\ndashboard SessionStart hook (repo-relative path so it's portable across\ncontributors). Document the methodology in CLAUDE.md.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(specops): scaffold spec-driven development",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:23:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7600b67cf585897ad95a708a12ead4a66a91ec3e",
          "body": "Ran: npx skills add JarvusInnovations/specops\n\nVendors the skill subtree under .agents/skills/specops (universal +\nClaude Code symlink at .claude/skills/specops) and records skills-lock.json.\nInstalled per-project and committed so the spec-and-plan methodology\ntravels with the repo for every contributor and agent.\n\nProject scaffolding (specs/, plans/, session hook) follows separately.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(skills): install specops spec-driven-development skill",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:15:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7d7b31d1b3123aee4a6cd708aca0c5f591502f4b",
          "body": "Ran: bun add googleapis@latest google-auth-library@latest\n\nPin google-auth-library via `overrides` so the top-level copy and the one\nnested under googleapis-common resolve to a single instance. Without the\npin, googleapis-common pulls its own 10.5.x, producing two\nstructurally-distinct OAuth2Client \n[…]\ny range — npm rejects a literal version that differs from\nthe direct-dep spec (EOVERRIDE), which would break npm/npx in this repo.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(deps): bump googleapis 173.0.0 + google-auth-library 10.7.0",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-11T15:14:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "85d5714231831d5227eca91f0bd8071150a35c89",
          "body": null,
          "is_bot": false,
          "headline": "chore(asdf): bump nodejs to 22.22.3",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-10T22:13:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da748289de8e19f03c20a2387f33c73660923d41",
          "body": "feat(gmail): implement write surface (decline send by design)",
          "is_bot": false,
          "headline": "Merge pull request #14 from JarvusInnovations/feat/gmail-writes",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-10T22:11:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5ae1473962d1b32e12b3051fd9503bd6c84f53d0",
          "body": "Refresh README status blurb, add a full Gmail writes section (triage,\ndrafting, label CRUD, filters) with the send rationale and the\ngmail.settings.basic re-auth note, and update the roadmap. Correct the\nstale CLAUDE.md implementation-status block (Gmail writes done; Drive/Slides\nreads done; send deliberately omitted).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: document Gmail write surface and send-is-out-of-scope",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-10T22:09:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0e48a54fc28a8a4223e9f7b5b020cd6c65dd23b8",
          "body": "Wire up the Gmail mutation commands behind the existing gmail.modify scope\n(plus gmail.settings.basic for filters):\n\n- draft        — compose a reviewable draft (text/plain, base64url MIME via\n                 compose.ts); --to/--cc/--bcc/--subject/--body|--body-file/--thread\n- modify       — add/re\n[…]\nhis is a\ncode/product boundary (guardrail against accidental sends), not a hard\nsecurity control — the token remains send-capable.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(gmail): implement write surface; decline send by design",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-10T22:09:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "52ff3c5854acdaa97526ef3f473359a0c8ae172a",
          "body": "Gmail filter management (users.settings.filters.*) requires\ngmail.settings.basic, which gmail.modify does not include. Add it as\nADDITIONAL_SCOPES — kept separate from the per-service representative\nscope so probe/health checks still key off a single scope each.\n\nAccounts authenticated before this change must re-run `auth login` once\nto pick up the new scope; filter commands surface SCOPE_MISSING until then.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): request gmail.settings.basic scope for filter management",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-10T22:08:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1c80abfcce74ecaa3dbd767d1624ac089399883c",
          "body": "Pull label name↔id resolution (resolveLabelId, resolveLabelIds,\nlabelNamesFor, isSystemLabel, fetchLabels) out of search.ts into a shared\nlabels-shared.ts so the incoming write commands resolve labels identically.\nsearch.ts now imports the shared resolver; behavior is unchanged.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor(gmail): extract shared label resolver",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-10T22:08:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d8b7302fac059798b6eee37c9ac3356b01f45fa4",
          "body": "Matches the first-party chrome-devtools-axi + slack-axi, which hand-render help\nas a multi-line `help[N]:` block rather than letting encode() inline it:\n- renderHelp now formats the block manually (all renderListResponse commands).\n- home returns a composed string (was an object the SDK inlined) so its help\n  is multi-line too; account/setup fields unchanged.\n\n37 tests passing.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(output): render help as multi-line block (canonical AXI form)",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-09T02:12:18Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "83bbc13eff023659bd88952c93c5fddc84392c66",
          "body": "Match the AXI home-screen convention: the final help line now reads\n\"Run `gws-axi --help` to see the full command list, or\n`gws-axi <command> --help` for usage on any command\".\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(home): expand command-list hint to point at per-command --help",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-06-08T13:15:58Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5c13336a85135ff3c52e266b05f27cfd490421cf",
          "body": "…rrent gaps\n\nThe README still described the v0.3 state (Calendar-only, Gmail/Docs/Drive/\nSlides as NOT_IMPLEMENTED stubs, 7-day token expiry as an open issue).\nRewrites the status banner, adds usage sections for the four newly-shipped\nservices, fixes the auth-login example to reflect the blocking-by\n[…]\n\nbehavior, and updates Known issues to the actual remaining gaps (Gmail\nwrites, Docs writes) plus the `auth publish` escape hatch.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(readme): refresh for v0.8 — full read coverage, auth publish, cu…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-22T16:29:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4ab1a7601885376c1767080bc947470715739a8c",
          "body": "Gmail's composer stamps a Content-ID on every user-attached file\nalongside Content-Disposition: attachment. The previous heuristic\ntreated any Content-ID as inline, demoting real attachments to\n\"inline image\" and hiding them from `gmail read` output. Let the\nexplicit disposition win; fall back to the cid-heuristic only when\nno disposition was declared.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(gmail): surface attachments that also carry Content-ID",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-22T04:36:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ad86362a6435b90955e38843ec353dffdde21e56",
          "body": "Replaces buildServiceStub with a real dispatcher mirroring docs.ts /\ngmail.ts / drive.ts. Registers the three read handlers (get, page,\nsummarize); the two write subcommands (create, update) stay as\nplanned stubs with their own --help text.\n\nRemoves slides from cli.ts COMMAND_HELP so `slides <sub> -\n[…]\n(per the routing rule in CLAUDE.md) —\nwhich also means COMMAND_HELP is now empty of services: every\nservice has a real dispatcher.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(slides): wire up real dispatcher, drop stub",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-13T17:30:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "be79fe1f05f6d8c82d3ac768a791cf49dd8ce9ec",
          "body": "Read-only v1 slice for the slides service. Three handlers plus a\nshared text-extraction helper:\n\n- `slides/text.ts` — extractSlideContent walks a Page's pageElements,\n  pulling a best-effort title (from TITLE / CENTERED_TITLE\n  placeholders), body text from every other shape and table in\n  document \n[…]\nitalic line\n  noting images / tables / video. Same truncation + --out escape\n  hatches as `docs read` (default 8000 chars inline).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(slides): add get, page, summarize handlers",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-13T17:30:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6ef814b484756daa6b81e554a7d3e4a01d9daa78",
          "body": "…bound\n\nThe arbitrary depth=10 default could cut off deeply-nested trees\nunexpectedly. The --limit (total file count, default 500, max 5000)\nis the real safety bound that prevents runaway walks. Default to\nNumber.POSITIVE_INFINITY for depth so the practical limit is just\ntotal file count; callers who want a \"shallow overview\" still pass\n--depth explicitly (e.g., --depth 2 for \"top two levels only\").\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(drive): default --depth to unlimited; --limit is the real safety …",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-13T17:05:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "844371c4e64123a4753aa22f2b494b91a88afae8",
          "body": "Replace buildServiceStub with a real dispatcher mirroring docs.ts and\ngmail.ts. Registers the four read handlers (ls, get, search,\npermissions) plus a `download` subcommand that delegates to\ndocs/download.ts — same implementation handles native Google file\nexport and uploaded-file media fetch regard\n[…]\n\nRemoves drive from cli.ts COMMAND_HELP so `drive <sub> --help` routes\nthrough the dispatcher (per the routing rule in CLAUDE.md).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(drive): wire up real dispatcher, drop stub",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-13T16:33:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "02d9cf21439da29003e8b0b50e558c33c38678c9",
          "body": "…lers\n\nRead-only v1 slice for the drive service. Four handlers:\n\n- `drive ls [<folder-id>] [--recursive] [--depth <n>] [--limit <n>]\n  [--page <token>] [--include-trashed]` — folder listing. Default is\n  shallow (one level); --recursive walks the tree and emits a flat\n  list with relative paths. Rec\n[…]\ns table (role, type,\n  email_or_domain). Flags \"anyone with link\" sharing and counts\n  external (off-domain) users in suggestions.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(drive): add ls (with --recursive), get, search, permissions hand…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-13T16:33:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8ded157ebb7f1379ac924471b69c504342daa16e",
          "body": "Closes #5.\n\nA \"what's on my calendar this week\" query against a busy schedule hits\n25 fast — AXI principle 2 (\"default limits high enough to cover common\ncases in one call\") prefers a default that doesn't force agents to\nre-run with --limit. 100 covers a full week of dense scheduling\ncomfortably; th\n[…]\nsearch at 25, docs find/\ncomments at 50) in this change — those have different volume\ncharacteristics and warrant separate review.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(calendar): bump events --limit default from 25 to 100",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-13T15:32:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f18af7db335494b618e68031086972549be99e8a",
          "body": "Closes #6.\n\nPreviously emitted `<name>[0]:` plus a separate `message:` sibling\n(parser-stability defense). The AXI convention is a single scalar\nfield — `<name>: <human-readable reason>` — which trades type\npolymorphism (array vs string) for one less field for agents to read.\nExternal review pointed\n[…]\nents that\nmirrored the old pattern. Populated lists are unchanged.\n\nUpdated the test guidance in CLAUDE.md to match the new shape.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(output): collapse empty lists to AXI canonical scalar form",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-13T15:32:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "28515af761c44acf48aa766e1e8ffad0f9aa07ca",
          "body": "Calendar events can carry Drive attachments — typically meeting notes\n(Gemini Notes / Notes by Gemini), agendas, slide decks. The Calendar\nAPI returns these on the event resource as attachments[], but neither\ncalendar events nor calendar get exposed them, so an agent looking up\n\"my meeting earlier t\n[…]\n at\n    least one is a Google Doc). Agents scanning events see \"this one\n    has notes\" at-a-glance without knowing to ask for it.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(calendar): surface event attachments to enable handoff to docs read",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-05-01T22:28:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d650e48170674b59ea0c4830511ba4d276cd065d",
          "body": "When --account doesn't match any existing authenticated account but is\nwithin edit distance ≤2 of one, abort BEFORE preparing the OAuth flow\n(LIKELY_TYPO error) with a \"did you mean\" pointing at the corrected\ncommand. The post-OAuth account-mismatch check still exists as a\nbackstop, but most typos n\n[…]\nunt ... double-check spelling\n\nAlso dedupes the inline editDistance helper out of loopback.ts in favor\nof the shared util/typo.ts.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): pre-flight typo check on `auth login --account`",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T14:26:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9d0d5cddaa0248ffba057c868b4e51522d2a85ee",
          "body": "Pulled out of loopback.ts so other commands can also flag close-match\ntypos before doing expensive work. Two exports:\n\n  - editDistance(a, b): Levenshtein distance, iterative DP.\n  - findLikelyTypo(value, candidates, maxDistance=2): returns the closest\n    candidate within the threshold, or undefine\n[…]\n/ substitutions, the \"themightychris@gmai.com\" → \"gmail.com\"\ncase that triggered this, threshold respect, and best-of-N selection.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(util): add reusable typo / edit-distance helper with tests",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T14:26:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "89cc33ab3163c2a5d1b0e4c8dd2174bf932ea24a",
          "body": "When the authenticated email differs from --account by ≤2 characters\n(and length differs by ≤2), the error now says \"Likely typo in\n--account\" with the corrected command pre-filled, instead of just\nshowing the two strings side-by-side. Two long emails differing by one\ncharacter were nearly impossibl\n[…]\ngws-axi auth login --account themightychris@gmail.com`...\n\nInlines a small Levenshtein helper rather than pulling in a dependency.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(auth): explicitly flag likely typos in account-mismatch errors",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T14:21:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c2a5d58d47c985fe6f08ffce90bcf21c5cd6580a",
          "body": "prepareLogin's instructions array now adds a bullet calling out the\n\"Google hasn't verified this app\" warning and the \"Advanced → Go to\n<app> (unsafe)\" path. Phrased emphatically when predictUnverifiedApp\nWarning returns \"always\" (personal Gmail / Testing-state app — the\nwarning will appear), softer\n[…]\n auth command file so future\nflows (e.g., agents that re-issue prepare without a new login) inherit\nthe same conditional language.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): include Advanced-link instruction in agent-flow login output",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T14:14:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "753912ec9f193231f09de4b8b2b17be406e1e064",
          "body": "waitForCallback was sending the \"Authenticated\" page to the browser\nimmediately on receiving the OAuth code, BEFORE token exchange and\nwriteAccountFiles ran. If exchange failed or the authenticated email\ndidn't match what we asked for (account-mismatch), the browser still\nshowed success while the CL\n[…]\nnverifiedAppWarning into the\nloopback's writeSetupHtml call so the html panel gets the right\nwarning level for the target account.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(auth): defer success page until token write actually succeeds",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T14:13:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ec56a53fa26de899de1b8074f1e83c7e0a3c2d56",
          "body": "Add predictUnverifiedAppWarning(email, published) classifying when the\n\"Google hasn't verified this app\" intermediate screen will appear:\n\n  - \"always\": personal Gmail (@gmail.com / @googlemail.com), OR app\n    still in Testing state. Render a strong yellow banner instructing\n    the user to click \"\n[…]\n see the\nguidance right next to the \"Authenticate with Google\" button rather\nthan discovering the small Advanced link by accident.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): predict + display unverified-app warning on setup.html",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T14:13:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ad9fe55016fb37963ed5170a8f0ba4b33eac45e7",
          "body": "doctor now exposes an `auth_health:` section between accounts and\nruntime that summarizes:\n  - whether the consent screen is published (the 7-day vs permanent\n    distinction)\n  - per-account token permanence rolled into the failing/warning tally,\n    so a pre-publish account warns even when API pro\n[…]\nt\n\"restricted scope (gmail.modify) ✓\" (separately committed) so the\nrestricted-scope dimension is also visible in the same output.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(doctor): report token permanence per account in auth_health block",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T14:00:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2a3b99099bc56144a24675ad3f29e8baf96bc7db",
          "body": "…n success\n\nAfter a successful OAuth callback, the response now carries:\n  - token_permanence: e.g. \"permanent — issued 0s after publish\" or\n    \"7-day clock — consent screen still in Testing...\"\n  - restricted_scope: live API probe of gmail.modify via\n    gmail.users.getProfile, reporting \"gmail.mo\n[…]\ny expiration —\nrunning auth login now tells you whether the new token is permanent\nwithout having to remember to run doctor after.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): report token permanence + restricted-scope status on logi…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T14:00:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "53bddaf43cb22a308ad13e560c16f5da5b215057",
          "body": "… probe\n\nTwo reusable checks both `auth login` and `doctor` should report:\n\n1. summarizeAccountHealth(email): compares the account's stored\n   obtained_at against state.published.confirmed_at and classifies\n   permanence as 'permanent', 'pre-publish-7-day' (published but token\n   pre-dates publish),\n[…]\nscope verification explicitly (\"restricted scope\n(gmail.modify) ✓\") rather than burying that signal under an opaque\nmessage count.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): add health helper for token permanence + restricted-scope…",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T14:00:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d613eab02cfc5d0f0f45630a64cc7c865aaf6113",
          "body": "…timestamp\n\n`auth publish` (no flag) now reads each account's obtained_at and\ncompares it against state.published.confirmed_at to flag which tokens\nwere issued under the 7-day Testing-state policy vs which were issued\npost-publish. Pre-publish accounts get a per-account re-auth checklist;\nall-post-p\n[…]\nuires verification\" banner is about consent-screen warnings, NOT\nabout token longevity (the 7-day expiry is purely Testing-state).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(auth): publish reports per-account token status against publish …",
          "author_name": "Chris Alfano",
          "author_login": "themightychris",
          "committed_at": "2026-04-28T13:52:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 28,
      "commits_last_year": 181,
      "latest_release_at": "2026-07-20T22:08:31Z",
      "latest_release_tag": "v0.17.0",
      "releases_from_tags": false,
      "days_since_last_push": 6,
      "active_weeks_last_year": 9,
      "days_since_latest_release": 6,
      "mean_days_between_releases": 3
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 50,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "gws-axi",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "google",
            "google-workspace",
            "gmail",
            "calendar",
            "docs",
            "drive",
            "slides",
            "cli",
            "agent",
            "axi",
            "toon"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/gws-axi",
          "is_deprecated": false,
          "latest_version": "0.17.0",
          "repository_url": "https://github.com/JarvusInnovations/gws-axi",
          "versions_count": 28,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 2188,
          "first_published_at": "2026-04-19T19:26:14.414000Z",
          "latest_published_at": "2026-07-20T22:09:02.105000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 6
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 8,
      "watchers": 0,
      "fork_history": {
        "days": [
          {
            "date": "2026-07-25",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": null,
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 53959,
      "source_files_sampled": 97,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        ".claude/CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 13597
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [
          {
            "name": "brace-expansion",
            "direct": false,
            "version": "2.1.2",
            "severity": "high",
            "ecosystem": "npm",
            "cvss_score": 7.5,
            "advisory_ids": [
              "GHSA-mh99-v99m-4gvg"
            ],
            "fixed_version": "5.0.8",
            "advisory_count": 1,
            "oldest_advisory_days": 2
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "high": 1
        },
        "advisory_count": 1,
        "affected_count": 1,
        "assessed_count": 93,
        "malicious_count": 0,
        "assessed_package": "npm:gws-axi@0.17.0",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@toon-format/toon",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.1.0"
        },
        {
          "name": "addressparser",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.0.1"
        },
        {
          "name": "axi-sdk-js",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.1.4"
        },
        {
          "name": "diff",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^9.0.0"
        },
        {
          "name": "google-auth-library",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^10.7.0"
        },
        {
          "name": "googleapis",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^173.0.0"
        },
        {
          "name": "turndown",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^7.2.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": 42,
        "open_issues": 0,
        "closed_ratio": 1,
        "closed_issues": 3,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "themightychris",
          "commits": 181,
          "avatar_url": "https://avatars.githubusercontent.com/u/458494?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "publish-npm.yml",
        "release-prepare.yml",
        "release-publish.yml",
        "release-validate.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "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": 3,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/8 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 5 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 3 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": 10,
            "reason": "packaging workflow 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": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 7,
            "reason": "3 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "8e0b492538df01efd83ce02d8336ebd4f6030e2c",
        "ran_at": "2026-07-27T16:10:39Z",
        "aggregate_score": 4.6,
        "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-20T22:08:34Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-20T22:08:20Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/JarvusInnovations/gws-axi",
    "host": "github.com",
    "name": "gws-axi",
    "owner": "JarvusInnovations"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 62,
      "inputs": {
        "security": 54,
        "vitality": 82,
        "community": 37,
        "governance": 63,
        "engineering": 67
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 82,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "commits_last_year": 181,
              "human_commit_share": 1,
              "days_since_last_push": 6,
              "active_weeks_last_year": 9
            },
            "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": "9/52 weeks with commits",
                "points": 6.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 9
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "181 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 181
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 3 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": 28,
              "latest_release_tag": "v0.17.0",
              "releases_from_tags": false,
              "days_since_latest_release": 6,
              "mean_days_between_releases": 3
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "28 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 28
                    }
                  }
                ],
                "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 ~3 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 3
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 37,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 14,
            "inputs": {
              "forks": 1,
              "stars": 8,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "8 stars",
                "points": 13.7,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 8
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "1 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 56,
            "inputs": {
              "packages": [
                "gws-axi"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 2188
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,188 downloads/month across npm",
                "points": 44.5,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2188,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 63,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 20,
            "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 5 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "excellent",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "merged_prs": 42,
              "open_issues": 0,
              "closed_issues": 3,
              "issue_closed_ratio": 1,
              "closed_unmerged_prs": 0
            },
            "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": "42/42 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 42,
                      "decided": 42
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/8 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 63,
            "inputs": {
              "followers": 12,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "JarvusInnovations",
              "public_repos": 225,
              "account_age_days": 5646
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "12 followers of JarvusInnovations",
                "points": 8,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 12,
                      "login": "JarvusInnovations"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "225 public repos, account ~15 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 225
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 15
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "gws-axi"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 6
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 6 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "28 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 28
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 67,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "5 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "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": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 54,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 46,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 4.6
            },
            "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 is not maximal on development and all release branches",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "8 out of 8 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/8 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 5 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 3 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 detected",
                "points": 5,
                "status": "met",
                "details": [],
                "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": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "3 existing vulnerabilities detected",
                "points": 5.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Matched the npm:gws-axi@0.17.0 runtime dependency closure — what installing the published package pulls in — 93 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:gws-axi@0.17.0",
                  "assessed": 93
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 85,
            "inputs": {
              "source": "osv",
              "advisories": 1,
              "affected_packages": 1,
              "assessed_packages": 93,
              "unassessed_packages": 0,
              "affected_by_severity": "high 1",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "1 affected: brace-expansion 2.1.2 (high 7.5)",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_affected",
                    "params": {
                      "count": 1,
                      "packages": "brace-expansion 2.1.2 (high 7.5)"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory has been public longer than 90 days",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "advisories_none_stale",
                    "params": {
                      "days": 90
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 93,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 5
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 68,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                ".claude/CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 13597
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": ".claude/CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".claude/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": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 43,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "tsconfig.json"
              ],
              "agent_commit_share": 0.82,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "82 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 82,
                      "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": "TypeScript",
              "largest_source_bytes": 53959,
              "source_files_sampled": 97,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/97 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 97,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T16:10:57.302980Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/j/JarvusInnovations/gws-axi.svg",
  "full_name": "JarvusInnovations/gws-axi",
  "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 statisticsnpm.